github.com/bendemaree/terraform@v0.5.4-0.20150613200311-f50d97d6eee6/builtin/providers/aws/resource_aws_security_group_rule_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/aws/awserr"
    10  	"github.com/aws/aws-sdk-go/service/ec2"
    11  	"github.com/hashicorp/terraform/helper/resource"
    12  	"github.com/hashicorp/terraform/terraform"
    13  )
    14  
    15  func TestIpPermissionIDHash(t *testing.T) {
    16  	simple := &ec2.IPPermission{
    17  		IPProtocol: aws.String("tcp"),
    18  		FromPort:   aws.Long(int64(80)),
    19  		ToPort:     aws.Long(int64(8000)),
    20  		IPRanges: []*ec2.IPRange{
    21  			&ec2.IPRange{
    22  				CIDRIP: aws.String("10.0.0.0/8"),
    23  			},
    24  		},
    25  	}
    26  
    27  	egress := &ec2.IPPermission{
    28  		IPProtocol: aws.String("tcp"),
    29  		FromPort:   aws.Long(int64(80)),
    30  		ToPort:     aws.Long(int64(8000)),
    31  		IPRanges: []*ec2.IPRange{
    32  			&ec2.IPRange{
    33  				CIDRIP: aws.String("10.0.0.0/8"),
    34  			},
    35  		},
    36  	}
    37  
    38  	egress_all := &ec2.IPPermission{
    39  		IPProtocol: aws.String("-1"),
    40  		IPRanges: []*ec2.IPRange{
    41  			&ec2.IPRange{
    42  				CIDRIP: aws.String("10.0.0.0/8"),
    43  			},
    44  		},
    45  	}
    46  
    47  	// hardcoded hashes, to detect future change
    48  	cases := []struct {
    49  		Input  *ec2.IPPermission
    50  		Type   string
    51  		Output string
    52  	}{
    53  		{simple, "ingress", "sg-82613597"},
    54  		{egress, "egress", "sg-363054720"},
    55  		{egress_all, "egress", "sg-857124156"},
    56  	}
    57  
    58  	for _, tc := range cases {
    59  		actual := ipPermissionIDHash(tc.Type, tc.Input)
    60  		if actual != tc.Output {
    61  			t.Fatalf("input: %s - %#v\noutput: %s", tc.Type, tc.Input, actual)
    62  		}
    63  	}
    64  }
    65  
    66  func TestAccAWSSecurityGroupRule_Ingress(t *testing.T) {
    67  	var group ec2.SecurityGroup
    68  
    69  	testRuleCount := func(*terraform.State) error {
    70  		if len(group.IPPermissions) != 1 {
    71  			return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d",
    72  				1, len(group.IPPermissions))
    73  		}
    74  
    75  		rule := group.IPPermissions[0]
    76  		if *rule.FromPort != int64(80) {
    77  			return fmt.Errorf("Wrong Security Group port setting, expected %d, got %d",
    78  				80, int(*rule.FromPort))
    79  		}
    80  
    81  		return nil
    82  	}
    83  
    84  	resource.Test(t, resource.TestCase{
    85  		PreCheck:     func() { testAccPreCheck(t) },
    86  		Providers:    testAccProviders,
    87  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
    88  		Steps: []resource.TestStep{
    89  			resource.TestStep{
    90  				Config: testAccAWSSecurityGroupRuleIngressConfig,
    91  				Check: resource.ComposeTestCheckFunc(
    92  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
    93  					testAccCheckAWSSecurityGroupRuleAttributes(&group, "ingress"),
    94  					resource.TestCheckResourceAttr(
    95  						"aws_security_group_rule.ingress_1", "from_port", "80"),
    96  					testRuleCount,
    97  				),
    98  			},
    99  		},
   100  	})
   101  }
   102  
   103  func TestAccAWSSecurityGroupRule_IngressClassic(t *testing.T) {
   104  	var group ec2.SecurityGroup
   105  
   106  	testRuleCount := func(*terraform.State) error {
   107  		if len(group.IPPermissions) != 1 {
   108  			return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d",
   109  				1, len(group.IPPermissions))
   110  		}
   111  
   112  		rule := group.IPPermissions[0]
   113  		if *rule.FromPort != int64(80) {
   114  			return fmt.Errorf("Wrong Security Group port setting, expected %d, got %d",
   115  				80, int(*rule.FromPort))
   116  		}
   117  
   118  		return nil
   119  	}
   120  
   121  	resource.Test(t, resource.TestCase{
   122  		PreCheck:     func() { testAccPreCheck(t) },
   123  		Providers:    testAccProviders,
   124  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   125  		Steps: []resource.TestStep{
   126  			resource.TestStep{
   127  				Config: testAccAWSSecurityGroupRuleIngressClassicConfig,
   128  				Check: resource.ComposeTestCheckFunc(
   129  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   130  					testAccCheckAWSSecurityGroupRuleAttributes(&group, "ingress"),
   131  					resource.TestCheckResourceAttr(
   132  						"aws_security_group_rule.ingress_1", "from_port", "80"),
   133  					testRuleCount,
   134  				),
   135  			},
   136  		},
   137  	})
   138  }
   139  
   140  func TestAccAWSSecurityGroupRule_MultiIngress(t *testing.T) {
   141  	var group ec2.SecurityGroup
   142  
   143  	testMultiRuleCount := func(*terraform.State) error {
   144  		if len(group.IPPermissions) != 3 {
   145  			return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d",
   146  				3, len(group.IPPermissions))
   147  		}
   148  
   149  		var rule *ec2.IPPermission
   150  		for _, r := range group.IPPermissions {
   151  			if *r.FromPort == int64(80) {
   152  				rule = r
   153  			}
   154  		}
   155  
   156  		if *rule.ToPort != int64(8000) {
   157  			return fmt.Errorf("Wrong Security Group port 2 setting, expected %d, got %d",
   158  				8000, int(*rule.ToPort))
   159  		}
   160  
   161  		return nil
   162  	}
   163  
   164  	resource.Test(t, resource.TestCase{
   165  		PreCheck:     func() { testAccPreCheck(t) },
   166  		Providers:    testAccProviders,
   167  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   168  		Steps: []resource.TestStep{
   169  			resource.TestStep{
   170  				Config: testAccAWSSecurityGroupRuleConfigMultiIngress,
   171  				Check: resource.ComposeTestCheckFunc(
   172  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   173  					testMultiRuleCount,
   174  				),
   175  			},
   176  		},
   177  	})
   178  }
   179  
   180  func TestAccAWSSecurityGroupRule_Egress(t *testing.T) {
   181  	var group ec2.SecurityGroup
   182  
   183  	resource.Test(t, resource.TestCase{
   184  		PreCheck:     func() { testAccPreCheck(t) },
   185  		Providers:    testAccProviders,
   186  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   187  		Steps: []resource.TestStep{
   188  			resource.TestStep{
   189  				Config: testAccAWSSecurityGroupRuleEgressConfig,
   190  				Check: resource.ComposeTestCheckFunc(
   191  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   192  					testAccCheckAWSSecurityGroupRuleAttributes(&group, "egress"),
   193  				),
   194  			},
   195  		},
   196  	})
   197  }
   198  
   199  func TestAccAWSSecurityGroupRule_SelfReference(t *testing.T) {
   200  	var group ec2.SecurityGroup
   201  
   202  	resource.Test(t, resource.TestCase{
   203  		PreCheck:     func() { testAccPreCheck(t) },
   204  		Providers:    testAccProviders,
   205  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   206  		Steps: []resource.TestStep{
   207  			resource.TestStep{
   208  				Config: testAccAWSSecurityGroupRuleConfigSelfReference,
   209  				Check: resource.ComposeTestCheckFunc(
   210  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   211  				),
   212  			},
   213  		},
   214  	})
   215  }
   216  
   217  func testAccCheckAWSSecurityGroupRuleDestroy(s *terraform.State) error {
   218  	conn := testAccProvider.Meta().(*AWSClient).ec2conn
   219  
   220  	for _, rs := range s.RootModule().Resources {
   221  		if rs.Type != "aws_security_group" {
   222  			continue
   223  		}
   224  
   225  		// Retrieve our group
   226  		req := &ec2.DescribeSecurityGroupsInput{
   227  			GroupIDs: []*string{aws.String(rs.Primary.ID)},
   228  		}
   229  		resp, err := conn.DescribeSecurityGroups(req)
   230  		if err == nil {
   231  			if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupID == rs.Primary.ID {
   232  				return fmt.Errorf("Security Group (%s) still exists.", rs.Primary.ID)
   233  			}
   234  
   235  			return nil
   236  		}
   237  
   238  		ec2err, ok := err.(awserr.Error)
   239  		if !ok {
   240  			return err
   241  		}
   242  		// Confirm error code is what we want
   243  		if ec2err.Code() != "InvalidGroup.NotFound" {
   244  			return err
   245  		}
   246  	}
   247  
   248  	return nil
   249  }
   250  
   251  func testAccCheckAWSSecurityGroupRuleExists(n string, group *ec2.SecurityGroup) resource.TestCheckFunc {
   252  	return func(s *terraform.State) error {
   253  		rs, ok := s.RootModule().Resources[n]
   254  		if !ok {
   255  			return fmt.Errorf("Not found: %s", n)
   256  		}
   257  
   258  		if rs.Primary.ID == "" {
   259  			return fmt.Errorf("No Security Group is set")
   260  		}
   261  
   262  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   263  		req := &ec2.DescribeSecurityGroupsInput{
   264  			GroupIDs: []*string{aws.String(rs.Primary.ID)},
   265  		}
   266  		resp, err := conn.DescribeSecurityGroups(req)
   267  		if err != nil {
   268  			return err
   269  		}
   270  
   271  		if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupID == rs.Primary.ID {
   272  			*group = *resp.SecurityGroups[0]
   273  			return nil
   274  		}
   275  
   276  		return fmt.Errorf("Security Group not found")
   277  	}
   278  }
   279  
   280  func testAccCheckAWSSecurityGroupRuleAttributes(group *ec2.SecurityGroup, ruleType string) resource.TestCheckFunc {
   281  	return func(s *terraform.State) error {
   282  		p := &ec2.IPPermission{
   283  			FromPort:   aws.Long(80),
   284  			ToPort:     aws.Long(8000),
   285  			IPProtocol: aws.String("tcp"),
   286  			IPRanges:   []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("10.0.0.0/8")}},
   287  		}
   288  		var rules []*ec2.IPPermission
   289  		if ruleType == "ingress" {
   290  			rules = group.IPPermissions
   291  		} else {
   292  			rules = group.IPPermissionsEgress
   293  		}
   294  
   295  		if len(rules) == 0 {
   296  			return fmt.Errorf("No IPPerms")
   297  		}
   298  
   299  		// Compare our ingress
   300  		if !reflect.DeepEqual(rules[0], p) {
   301  			return fmt.Errorf(
   302  				"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   303  				rules[0],
   304  				p)
   305  		}
   306  
   307  		return nil
   308  	}
   309  }
   310  
   311  const testAccAWSSecurityGroupRuleIngressConfig = `
   312  resource "aws_security_group" "web" {
   313    name = "terraform_acceptance_test_example"
   314    description = "Used in the terraform acceptance tests"
   315  
   316          tags {
   317                  Name = "tf-acc-test"
   318          }
   319  }
   320  
   321  resource "aws_security_group_rule" "ingress_1" {
   322    type = "ingress"
   323    protocol = "tcp"
   324    from_port = 80
   325    to_port = 8000
   326    cidr_blocks = ["10.0.0.0/8"]
   327  
   328    security_group_id = "${aws_security_group.web.id}"
   329  }
   330  `
   331  
   332  const testAccAWSSecurityGroupRuleIngressClassicConfig = `
   333  provider "aws" {
   334          region = "us-east-1"
   335  }
   336  
   337  resource "aws_security_group" "web" {
   338    name = "terraform_acceptance_test_example"
   339    description = "Used in the terraform acceptance tests"
   340  
   341          tags {
   342                  Name = "tf-acc-test"
   343          }
   344  }
   345  
   346  resource "aws_security_group_rule" "ingress_1" {
   347    type = "ingress"
   348    protocol = "tcp"
   349    from_port = 80
   350    to_port = 8000
   351    cidr_blocks = ["10.0.0.0/8"]
   352  
   353    security_group_id = "${aws_security_group.web.id}"
   354  }
   355  `
   356  
   357  const testAccAWSSecurityGroupRuleEgressConfig = `
   358  resource "aws_security_group" "web" {
   359    name = "terraform_acceptance_test_example"
   360    description = "Used in the terraform acceptance tests"
   361  
   362          tags {
   363                  Name = "tf-acc-test"
   364          }
   365  }
   366  
   367  resource "aws_security_group_rule" "egress_1" {
   368    type = "egress"
   369    protocol = "tcp"
   370    from_port = 80
   371    to_port = 8000
   372    cidr_blocks = ["10.0.0.0/8"]
   373  
   374    security_group_id = "${aws_security_group.web.id}"
   375  }
   376  `
   377  
   378  const testAccAWSSecurityGroupRuleConfigMultiIngress = `
   379  resource "aws_security_group" "web" {
   380    name = "terraform_acceptance_test_example_2"
   381    description = "Used in the terraform acceptance tests"
   382  }
   383  
   384  resource "aws_security_group" "worker" {
   385    name = "terraform_acceptance_test_example_worker"
   386    description = "Used in the terraform acceptance tests"
   387  }
   388  
   389  
   390  resource "aws_security_group_rule" "ingress_1" {
   391    type = "ingress"
   392    protocol = "tcp"
   393    from_port = 22
   394    to_port = 22
   395    cidr_blocks = ["10.0.0.0/8"]
   396  
   397    security_group_id = "${aws_security_group.web.id}"
   398          source_security_group_id = "${aws_security_group.worker.id}"
   399  }
   400  
   401  resource "aws_security_group_rule" "ingress_2" {
   402    type = "ingress"
   403    protocol = "tcp"
   404    from_port = 80
   405    to_port = 8000
   406          self = true
   407  
   408    security_group_id = "${aws_security_group.web.id}"
   409  }
   410  `
   411  
   412  // check for GH-1985 regression
   413  const testAccAWSSecurityGroupRuleConfigSelfReference = `
   414  provider "aws" {
   415    region = "us-west-2"
   416  }
   417  
   418  resource "aws_vpc" "main" {
   419    cidr_block = "10.0.0.0/16"
   420    tags {
   421      Name = "sg-self-test"
   422    }
   423  }
   424  
   425  resource "aws_security_group" "web" {
   426    name = "main"
   427    vpc_id = "${aws_vpc.main.id}"
   428    tags {
   429      Name = "sg-self-test"
   430    }
   431  }
   432  
   433  resource "aws_security_group_rule" "self" {
   434    type = "ingress"
   435    protocol = "-1"
   436    from_port = 0
   437    to_port = 0
   438    self = true
   439    security_group_id = "${aws_security_group.web.id}"
   440  }
   441  `