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