github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_opsworks_stack_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/hashicorp/terraform/helper/acctest" 8 "github.com/hashicorp/terraform/helper/resource" 9 "github.com/hashicorp/terraform/terraform" 10 11 "github.com/aws/aws-sdk-go/aws" 12 "github.com/aws/aws-sdk-go/aws/awserr" 13 "github.com/aws/aws-sdk-go/service/opsworks" 14 ) 15 16 /////////////////////////////// 17 //// Tests for the No-VPC case 18 /////////////////////////////// 19 20 func TestAccAWSOpsworksStackNoVpc(t *testing.T) { 21 stackName := fmt.Sprintf("tf-opsworks-acc-%d", acctest.RandInt()) 22 var opsstack opsworks.Stack 23 resource.Test(t, resource.TestCase{ 24 PreCheck: func() { testAccPreCheck(t) }, 25 Providers: testAccProviders, 26 CheckDestroy: testAccCheckAwsOpsworksStackDestroy, 27 Steps: []resource.TestStep{ 28 resource.TestStep{ 29 Config: testAccAwsOpsworksStackConfigNoVpcCreate(stackName), 30 Check: resource.ComposeTestCheckFunc( 31 testAccCheckAWSOpsworksStackExists( 32 "aws_opsworks_stack.tf-acc", false, &opsstack), 33 testAccCheckAWSOpsworksCreateStackAttributes( 34 &opsstack, "us-east-1a", stackName), 35 testAccAwsOpsworksStackCheckResourceAttrsCreate( 36 "us-east-1a", stackName), 37 ), 38 }, 39 // resource.TestStep{ 40 // Config: testAccAWSOpsworksStackConfigNoVpcUpdate(stackName), 41 // Check: testAccAwsOpsworksStackCheckResourceAttrsUpdate("us-east-1c", stackName), 42 // }, 43 }, 44 }) 45 } 46 47 func TestAccAWSOpsworksStackVpc(t *testing.T) { 48 stackName := fmt.Sprintf("tf-opsworks-acc-%d", acctest.RandInt()) 49 var opsstack opsworks.Stack 50 resource.Test(t, resource.TestCase{ 51 PreCheck: func() { testAccPreCheck(t) }, 52 Providers: testAccProviders, 53 CheckDestroy: testAccCheckAwsOpsworksStackDestroy, 54 Steps: []resource.TestStep{ 55 resource.TestStep{ 56 Config: testAccAwsOpsworksStackConfigVpcCreate(stackName), 57 Check: resource.ComposeTestCheckFunc( 58 testAccCheckAWSOpsworksStackExists( 59 "aws_opsworks_stack.tf-acc", true, &opsstack), 60 testAccCheckAWSOpsworksCreateStackAttributes( 61 &opsstack, "us-west-2a", stackName), 62 testAccAwsOpsworksStackCheckResourceAttrsCreate( 63 "us-west-2a", stackName), 64 ), 65 }, 66 resource.TestStep{ 67 Config: testAccAWSOpsworksStackConfigVpcUpdate(stackName), 68 Check: resource.ComposeTestCheckFunc( 69 testAccCheckAWSOpsworksStackExists( 70 "aws_opsworks_stack.tf-acc", true, &opsstack), 71 testAccCheckAWSOpsworksUpdateStackAttributes( 72 &opsstack, "us-west-2a", stackName), 73 testAccAwsOpsworksStackCheckResourceAttrsUpdate( 74 "us-west-2a", stackName), 75 ), 76 }, 77 }, 78 }) 79 } 80 81 //////////////////////////// 82 //// Checkers and Utilities 83 //////////////////////////// 84 85 func testAccAwsOpsworksStackCheckResourceAttrsCreate(zone, stackName string) resource.TestCheckFunc { 86 return resource.ComposeTestCheckFunc( 87 resource.TestCheckResourceAttr( 88 "aws_opsworks_stack.tf-acc", 89 "name", 90 stackName, 91 ), 92 resource.TestCheckResourceAttr( 93 "aws_opsworks_stack.tf-acc", 94 "default_availability_zone", 95 zone, 96 ), 97 resource.TestCheckResourceAttr( 98 "aws_opsworks_stack.tf-acc", 99 "default_os", 100 "Amazon Linux 2014.09", 101 ), 102 resource.TestCheckResourceAttr( 103 "aws_opsworks_stack.tf-acc", 104 "default_root_device_type", 105 "ebs", 106 ), 107 resource.TestCheckResourceAttr( 108 "aws_opsworks_stack.tf-acc", 109 "custom_json", 110 `{"key": "value"}`, 111 ), 112 resource.TestCheckResourceAttr( 113 "aws_opsworks_stack.tf-acc", 114 "configuration_manager_version", 115 "11.10", 116 ), 117 resource.TestCheckResourceAttr( 118 "aws_opsworks_stack.tf-acc", 119 "use_opsworks_security_groups", 120 "false", 121 ), 122 ) 123 } 124 125 func testAccAwsOpsworksStackCheckResourceAttrsUpdate(zone, stackName string) resource.TestCheckFunc { 126 return resource.ComposeTestCheckFunc( 127 resource.TestCheckResourceAttr( 128 "aws_opsworks_stack.tf-acc", 129 "name", 130 stackName, 131 ), 132 resource.TestCheckResourceAttr( 133 "aws_opsworks_stack.tf-acc", 134 "default_availability_zone", 135 zone, 136 ), 137 resource.TestCheckResourceAttr( 138 "aws_opsworks_stack.tf-acc", 139 "default_os", 140 "Amazon Linux 2014.09", 141 ), 142 resource.TestCheckResourceAttr( 143 "aws_opsworks_stack.tf-acc", 144 "default_root_device_type", 145 "ebs", 146 ), 147 resource.TestCheckResourceAttr( 148 "aws_opsworks_stack.tf-acc", 149 "custom_json", 150 `{"key": "value"}`, 151 ), 152 resource.TestCheckResourceAttr( 153 "aws_opsworks_stack.tf-acc", 154 "configuration_manager_version", 155 "11.10", 156 ), 157 resource.TestCheckResourceAttr( 158 "aws_opsworks_stack.tf-acc", 159 "use_opsworks_security_groups", 160 "false", 161 ), 162 resource.TestCheckResourceAttr( 163 "aws_opsworks_stack.tf-acc", 164 "use_custom_cookbooks", 165 "true", 166 ), 167 resource.TestCheckResourceAttr( 168 "aws_opsworks_stack.tf-acc", 169 "manage_berkshelf", 170 "true", 171 ), 172 resource.TestCheckResourceAttr( 173 "aws_opsworks_stack.tf-acc", 174 "custom_cookbooks_source.0.type", 175 "git", 176 ), 177 resource.TestCheckResourceAttr( 178 "aws_opsworks_stack.tf-acc", 179 "custom_cookbooks_source.0.revision", 180 "master", 181 ), 182 resource.TestCheckResourceAttr( 183 "aws_opsworks_stack.tf-acc", 184 "custom_cookbooks_source.0.url", 185 "https://github.com/aws/opsworks-example-cookbooks.git", 186 ), 187 ) 188 } 189 190 func testAccCheckAWSOpsworksStackExists( 191 n string, vpc bool, opsstack *opsworks.Stack) resource.TestCheckFunc { 192 return func(s *terraform.State) error { 193 rs, ok := s.RootModule().Resources[n] 194 if !ok { 195 return fmt.Errorf("Not found: %s", n) 196 } 197 198 if rs.Primary.ID == "" { 199 return fmt.Errorf("No ID is set") 200 } 201 202 conn := testAccProvider.Meta().(*AWSClient).opsworksconn 203 204 params := &opsworks.DescribeStacksInput{ 205 StackIds: []*string{aws.String(rs.Primary.ID)}, 206 } 207 resp, err := conn.DescribeStacks(params) 208 209 if err != nil { 210 return err 211 } 212 213 if v := len(resp.Stacks); v != 1 { 214 return fmt.Errorf("Expected 1 response returned, got %d", v) 215 } 216 217 *opsstack = *resp.Stacks[0] 218 219 if vpc { 220 if rs.Primary.Attributes["vpc_id"] != *opsstack.VpcId { 221 return fmt.Errorf("VPCID Got %s, expected %s", *opsstack.VpcId, rs.Primary.Attributes["vpc_id"]) 222 } 223 if rs.Primary.Attributes["default_subnet_id"] != *opsstack.DefaultSubnetId { 224 return fmt.Errorf("Default subnet Id Got %s, expected %s", *opsstack.DefaultSubnetId, rs.Primary.Attributes["default_subnet_id"]) 225 } 226 } 227 228 return nil 229 } 230 } 231 232 func testAccCheckAWSOpsworksCreateStackAttributes( 233 opsstack *opsworks.Stack, zone, stackName string) resource.TestCheckFunc { 234 return func(s *terraform.State) error { 235 if *opsstack.Name != stackName { 236 return fmt.Errorf("Unnexpected stackName: %s", *opsstack.Name) 237 } 238 239 if *opsstack.DefaultAvailabilityZone != zone { 240 return fmt.Errorf("Unnexpected DefaultAvailabilityZone: %s", *opsstack.DefaultAvailabilityZone) 241 } 242 243 if *opsstack.DefaultOs != "Amazon Linux 2014.09" { 244 return fmt.Errorf("Unnexpected stackName: %s", *opsstack.DefaultOs) 245 } 246 247 if *opsstack.DefaultRootDeviceType != "ebs" { 248 return fmt.Errorf("Unnexpected DefaultRootDeviceType: %s", *opsstack.DefaultRootDeviceType) 249 } 250 251 if *opsstack.CustomJson != `{"key": "value"}` { 252 return fmt.Errorf("Unnexpected CustomJson: %s", *opsstack.CustomJson) 253 } 254 255 if *opsstack.ConfigurationManager.Version != "11.10" { 256 return fmt.Errorf("Unnexpected Version: %s", *opsstack.ConfigurationManager.Version) 257 } 258 259 if *opsstack.UseOpsworksSecurityGroups { 260 return fmt.Errorf("Unnexpected UseOpsworksSecurityGroups: %t", *opsstack.UseOpsworksSecurityGroups) 261 } 262 263 return nil 264 } 265 } 266 267 func testAccCheckAWSOpsworksUpdateStackAttributes( 268 opsstack *opsworks.Stack, zone, stackName string) resource.TestCheckFunc { 269 return func(s *terraform.State) error { 270 if *opsstack.Name != stackName { 271 return fmt.Errorf("Unnexpected stackName: %s", *opsstack.Name) 272 } 273 274 if *opsstack.DefaultAvailabilityZone != zone { 275 return fmt.Errorf("Unnexpected DefaultAvailabilityZone: %s", *opsstack.DefaultAvailabilityZone) 276 } 277 278 if *opsstack.DefaultOs != "Amazon Linux 2014.09" { 279 return fmt.Errorf("Unnexpected stackName: %s", *opsstack.DefaultOs) 280 } 281 282 if *opsstack.DefaultRootDeviceType != "ebs" { 283 return fmt.Errorf("Unnexpected DefaultRootDeviceType: %s", *opsstack.DefaultRootDeviceType) 284 } 285 286 if *opsstack.CustomJson != `{"key": "value"}` { 287 return fmt.Errorf("Unnexpected CustomJson: %s", *opsstack.CustomJson) 288 } 289 290 if *opsstack.ConfigurationManager.Version != "11.10" { 291 return fmt.Errorf("Unnexpected Version: %s", *opsstack.ConfigurationManager.Version) 292 } 293 294 if !*opsstack.UseCustomCookbooks { 295 return fmt.Errorf("Unnexpected UseCustomCookbooks: %t", *opsstack.UseCustomCookbooks) 296 } 297 298 if !*opsstack.ChefConfiguration.ManageBerkshelf { 299 return fmt.Errorf("Unnexpected ManageBerkshelf: %t", *opsstack.ChefConfiguration.ManageBerkshelf) 300 } 301 302 if *opsstack.CustomCookbooksSource.Type != "git" { 303 return fmt.Errorf("Unnexpected *opsstack.CustomCookbooksSource.Type: %s", *opsstack.CustomCookbooksSource.Type) 304 } 305 306 if *opsstack.CustomCookbooksSource.Revision != "master" { 307 return fmt.Errorf("Unnexpected *opsstack.CustomCookbooksSource.Type: %s", *opsstack.CustomCookbooksSource.Revision) 308 } 309 310 if *opsstack.CustomCookbooksSource.Url != "https://github.com/aws/opsworks-example-cookbooks.git" { 311 return fmt.Errorf("Unnexpected *opsstack.CustomCookbooksSource.Type: %s", *opsstack.CustomCookbooksSource.Url) 312 } 313 314 return nil 315 } 316 } 317 318 func testAccCheckAwsOpsworksStackDestroy(s *terraform.State) error { 319 opsworksconn := testAccProvider.Meta().(*AWSClient).opsworksconn 320 for _, rs := range s.RootModule().Resources { 321 if rs.Type != "aws_opsworks_stack" { 322 continue 323 } 324 325 req := &opsworks.DescribeStacksInput{ 326 StackIds: []*string{ 327 aws.String(rs.Primary.ID), 328 }, 329 } 330 331 _, err := opsworksconn.DescribeStacks(req) 332 if err != nil { 333 if awserr, ok := err.(awserr.Error); ok { 334 if awserr.Code() == "ResourceNotFoundException" { 335 // not found, all good 336 return nil 337 } 338 } 339 return err 340 } 341 } 342 return fmt.Errorf("Fall through error for OpsWorks stack test") 343 } 344 345 ////////////////////////////////////////////////// 346 //// Helper configs for the necessary IAM objects 347 ////////////////////////////////////////////////// 348 349 func testAccAwsOpsworksStackConfigNoVpcCreate(name string) string { 350 return fmt.Sprintf(` 351 resource "aws_opsworks_stack" "tf-acc" { 352 name = "%s" 353 region = "us-east-1" 354 service_role_arn = "${aws_iam_role.opsworks_service.arn}" 355 default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}" 356 default_availability_zone = "us-east-1a" 357 default_os = "Amazon Linux 2014.09" 358 default_root_device_type = "ebs" 359 custom_json = "{\"key\": \"value\"}" 360 configuration_manager_version = "11.10" 361 use_opsworks_security_groups = false 362 } 363 364 resource "aws_iam_role" "opsworks_service" { 365 name = "%s_opsworks_service" 366 assume_role_policy = <<EOT 367 { 368 "Version": "2008-10-17", 369 "Statement": [ 370 { 371 "Sid": "", 372 "Effect": "Allow", 373 "Principal": { 374 "Service": "opsworks.amazonaws.com" 375 }, 376 "Action": "sts:AssumeRole" 377 } 378 ] 379 } 380 EOT 381 } 382 383 resource "aws_iam_role_policy" "opsworks_service" { 384 name = "%s_opsworks_service" 385 role = "${aws_iam_role.opsworks_service.id}" 386 policy = <<EOT 387 { 388 "Statement": [ 389 { 390 "Action": [ 391 "ec2:*", 392 "iam:PassRole", 393 "cloudwatch:GetMetricStatistics", 394 "elasticloadbalancing:*", 395 "rds:*" 396 ], 397 "Effect": "Allow", 398 "Resource": ["*"] 399 } 400 ] 401 } 402 EOT 403 } 404 405 resource "aws_iam_role" "opsworks_instance" { 406 name = "%s_opsworks_instance" 407 assume_role_policy = <<EOT 408 { 409 "Version": "2008-10-17", 410 "Statement": [ 411 { 412 "Sid": "", 413 "Effect": "Allow", 414 "Principal": { 415 "Service": "ec2.amazonaws.com" 416 }, 417 "Action": "sts:AssumeRole" 418 } 419 ] 420 } 421 EOT 422 } 423 424 resource "aws_iam_instance_profile" "opsworks_instance" { 425 name = "%s_opsworks_instance" 426 roles = ["${aws_iam_role.opsworks_instance.name}"] 427 }`, name, name, name, name, name) 428 } 429 430 func testAccAWSOpsworksStackConfigNoVpcUpdate(name string) string { 431 return fmt.Sprintf(` 432 resource "aws_opsworks_stack" "tf-acc" { 433 name = "%s" 434 region = "us-east-1" 435 service_role_arn = "${aws_iam_role.opsworks_service.arn}" 436 default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}" 437 default_availability_zone = "us-east-1a" 438 default_os = "Amazon Linux 2014.09" 439 default_root_device_type = "ebs" 440 custom_json = "{\"key\": \"value\"}" 441 configuration_manager_version = "11.10" 442 use_opsworks_security_groups = false 443 use_custom_cookbooks = true 444 manage_berkshelf = true 445 custom_cookbooks_source { 446 type = "git" 447 revision = "master" 448 url = "https://github.com/aws/opsworks-example-cookbooks.git" 449 username = "example" 450 password = "example" 451 } 452 resource "aws_iam_role" "opsworks_service" { 453 name = "%s_opsworks_service" 454 assume_role_policy = <<EOT 455 { 456 "Version": "2008-10-17", 457 "Statement": [ 458 { 459 "Sid": "", 460 "Effect": "Allow", 461 "Principal": { 462 "Service": "opsworks.amazonaws.com" 463 }, 464 "Action": "sts:AssumeRole" 465 } 466 ] 467 } 468 EOT 469 } 470 471 resource "aws_iam_role_policy" "opsworks_service" { 472 name = "%s_opsworks_service" 473 role = "${aws_iam_role.opsworks_service.id}" 474 policy = <<EOT 475 { 476 "Statement": [ 477 { 478 "Action": [ 479 "ec2:*", 480 "iam:PassRole", 481 "cloudwatch:GetMetricStatistics", 482 "elasticloadbalancing:*", 483 "rds:*" 484 ], 485 "Effect": "Allow", 486 "Resource": ["*"] 487 } 488 ] 489 } 490 EOT 491 } 492 493 resource "aws_iam_role" "opsworks_instance" { 494 name = "%s_opsworks_instance" 495 assume_role_policy = <<EOT 496 { 497 "Version": "2008-10-17", 498 "Statement": [ 499 { 500 "Sid": "", 501 "Effect": "Allow", 502 "Principal": { 503 "Service": "ec2.amazonaws.com" 504 }, 505 "Action": "sts:AssumeRole" 506 } 507 ] 508 } 509 EOT 510 } 511 512 resource "aws_iam_instance_profile" "opsworks_instance" { 513 name = "%s_opsworks_instance" 514 roles = ["${aws_iam_role.opsworks_instance.name}"] 515 } 516 `, name, name, name, name, name) 517 } 518 519 //////////////////////////// 520 //// Tests for the VPC case 521 //////////////////////////// 522 523 func testAccAwsOpsworksStackConfigVpcCreate(name string) string { 524 return fmt.Sprintf(` 525 resource "aws_vpc" "tf-acc" { 526 cidr_block = "10.3.5.0/24" 527 } 528 resource "aws_subnet" "tf-acc" { 529 vpc_id = "${aws_vpc.tf-acc.id}" 530 cidr_block = "${aws_vpc.tf-acc.cidr_block}" 531 availability_zone = "us-west-2a" 532 } 533 resource "aws_opsworks_stack" "tf-acc" { 534 name = "%s" 535 region = "us-west-2" 536 vpc_id = "${aws_vpc.tf-acc.id}" 537 default_subnet_id = "${aws_subnet.tf-acc.id}" 538 service_role_arn = "${aws_iam_role.opsworks_service.arn}" 539 default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}" 540 default_os = "Amazon Linux 2014.09" 541 default_root_device_type = "ebs" 542 custom_json = "{\"key\": \"value\"}" 543 configuration_manager_version = "11.10" 544 use_opsworks_security_groups = false 545 } 546 547 resource "aws_iam_role" "opsworks_service" { 548 name = "%s_opsworks_service" 549 assume_role_policy = <<EOT 550 { 551 "Version": "2008-10-17", 552 "Statement": [ 553 { 554 "Sid": "", 555 "Effect": "Allow", 556 "Principal": { 557 "Service": "opsworks.amazonaws.com" 558 }, 559 "Action": "sts:AssumeRole" 560 } 561 ] 562 } 563 EOT 564 } 565 566 resource "aws_iam_role_policy" "opsworks_service" { 567 name = "%s_opsworks_service" 568 role = "${aws_iam_role.opsworks_service.id}" 569 policy = <<EOT 570 { 571 "Statement": [ 572 { 573 "Action": [ 574 "ec2:*", 575 "iam:PassRole", 576 "cloudwatch:GetMetricStatistics", 577 "elasticloadbalancing:*", 578 "rds:*" 579 ], 580 "Effect": "Allow", 581 "Resource": ["*"] 582 } 583 ] 584 } 585 EOT 586 } 587 588 resource "aws_iam_role" "opsworks_instance" { 589 name = "%s_opsworks_instance" 590 assume_role_policy = <<EOT 591 { 592 "Version": "2008-10-17", 593 "Statement": [ 594 { 595 "Sid": "", 596 "Effect": "Allow", 597 "Principal": { 598 "Service": "ec2.amazonaws.com" 599 }, 600 "Action": "sts:AssumeRole" 601 } 602 ] 603 } 604 EOT 605 } 606 607 resource "aws_iam_instance_profile" "opsworks_instance" { 608 name = "%s_opsworks_instance" 609 roles = ["${aws_iam_role.opsworks_instance.name}"] 610 } 611 `, name, name, name, name, name) 612 } 613 614 func testAccAWSOpsworksStackConfigVpcUpdate(name string) string { 615 return fmt.Sprintf(` 616 resource "aws_vpc" "tf-acc" { 617 cidr_block = "10.3.5.0/24" 618 } 619 resource "aws_subnet" "tf-acc" { 620 vpc_id = "${aws_vpc.tf-acc.id}" 621 cidr_block = "${aws_vpc.tf-acc.cidr_block}" 622 availability_zone = "us-west-2a" 623 } 624 resource "aws_opsworks_stack" "tf-acc" { 625 name = "%s" 626 region = "us-west-2" 627 vpc_id = "${aws_vpc.tf-acc.id}" 628 default_subnet_id = "${aws_subnet.tf-acc.id}" 629 service_role_arn = "${aws_iam_role.opsworks_service.arn}" 630 default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}" 631 default_os = "Amazon Linux 2014.09" 632 default_root_device_type = "ebs" 633 custom_json = "{\"key\": \"value\"}" 634 configuration_manager_version = "11.10" 635 use_opsworks_security_groups = false 636 use_custom_cookbooks = true 637 manage_berkshelf = true 638 custom_cookbooks_source { 639 type = "git" 640 revision = "master" 641 url = "https://github.com/aws/opsworks-example-cookbooks.git" 642 } 643 } 644 645 resource "aws_iam_role" "opsworks_service" { 646 name = "%s_opsworks_service" 647 assume_role_policy = <<EOT 648 { 649 "Version": "2008-10-17", 650 "Statement": [ 651 { 652 "Sid": "", 653 "Effect": "Allow", 654 "Principal": { 655 "Service": "opsworks.amazonaws.com" 656 }, 657 "Action": "sts:AssumeRole" 658 } 659 ] 660 } 661 EOT 662 } 663 664 resource "aws_iam_role_policy" "opsworks_service" { 665 name = "%s_opsworks_service" 666 role = "${aws_iam_role.opsworks_service.id}" 667 policy = <<EOT 668 { 669 "Statement": [ 670 { 671 "Action": [ 672 "ec2:*", 673 "iam:PassRole", 674 "cloudwatch:GetMetricStatistics", 675 "elasticloadbalancing:*", 676 "rds:*" 677 ], 678 "Effect": "Allow", 679 "Resource": ["*"] 680 } 681 ] 682 } 683 EOT 684 } 685 686 resource "aws_iam_role" "opsworks_instance" { 687 name = "%s_opsworks_instance" 688 assume_role_policy = <<EOT 689 { 690 "Version": "2008-10-17", 691 "Statement": [ 692 { 693 "Sid": "", 694 "Effect": "Allow", 695 "Principal": { 696 "Service": "ec2.amazonaws.com" 697 }, 698 "Action": "sts:AssumeRole" 699 } 700 ] 701 } 702 EOT 703 } 704 705 resource "aws_iam_instance_profile" "opsworks_instance" { 706 name = "%s_opsworks_instance" 707 roles = ["${aws_iam_role.opsworks_instance.name}"] 708 } 709 710 `, name, name, name, name, name) 711 }