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 `