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