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 `