github.com/grange74/terraform@v0.7.0-rc3.0.20160722171430-8c8803864753/builtin/providers/aws/resource_aws_elastic_beanstalk_environment_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "regexp" 7 "testing" 8 9 "github.com/aws/aws-sdk-go/aws" 10 "github.com/aws/aws-sdk-go/aws/awserr" 11 "github.com/aws/aws-sdk-go/service/elasticbeanstalk" 12 "github.com/hashicorp/terraform/helper/acctest" 13 "github.com/hashicorp/terraform/helper/resource" 14 "github.com/hashicorp/terraform/terraform" 15 ) 16 17 func TestAccAWSBeanstalkEnv_basic(t *testing.T) { 18 var app elasticbeanstalk.EnvironmentDescription 19 20 resource.Test(t, resource.TestCase{ 21 PreCheck: func() { testAccPreCheck(t) }, 22 Providers: testAccProviders, 23 CheckDestroy: testAccCheckBeanstalkEnvDestroy, 24 Steps: []resource.TestStep{ 25 resource.TestStep{ 26 Config: testAccBeanstalkEnvConfig, 27 Check: resource.ComposeTestCheckFunc( 28 testAccCheckBeanstalkEnvExists("aws_elastic_beanstalk_environment.tfenvtest", &app), 29 ), 30 }, 31 }, 32 }) 33 } 34 35 func TestAccAWSBeanstalkEnv_tier(t *testing.T) { 36 var app elasticbeanstalk.EnvironmentDescription 37 beanstalkQueuesNameRegexp := regexp.MustCompile("https://sqs.+?awseb[^,]+") 38 39 resource.Test(t, resource.TestCase{ 40 PreCheck: func() { testAccPreCheck(t) }, 41 Providers: testAccProviders, 42 CheckDestroy: testAccCheckBeanstalkEnvDestroy, 43 Steps: []resource.TestStep{ 44 resource.TestStep{ 45 Config: testAccBeanstalkWorkerEnvConfig, 46 Check: resource.ComposeTestCheckFunc( 47 testAccCheckBeanstalkEnvTier("aws_elastic_beanstalk_environment.tfenvtest", &app), 48 resource.TestMatchResourceAttr( 49 "aws_elastic_beanstalk_environment.tfenvtest", "queues.0", beanstalkQueuesNameRegexp), 50 ), 51 }, 52 }, 53 }) 54 } 55 56 func TestAccAWSBeanstalkEnv_outputs(t *testing.T) { 57 var app elasticbeanstalk.EnvironmentDescription 58 beanstalkAsgNameRegexp := regexp.MustCompile("awseb.+?AutoScalingGroup[^,]+") 59 beanstalkElbNameRegexp := regexp.MustCompile("awseb.+?EBLoa[^,]+") 60 beanstalkInstancesNameRegexp := regexp.MustCompile("i-([0-9a-fA-F]{8}|[0-9a-fA-F]{17})") 61 beanstalkLcNameRegexp := regexp.MustCompile("awseb.+?AutoScalingLaunch[^,]+") 62 63 resource.Test(t, resource.TestCase{ 64 PreCheck: func() { testAccPreCheck(t) }, 65 Providers: testAccProviders, 66 CheckDestroy: testAccCheckBeanstalkEnvDestroy, 67 Steps: []resource.TestStep{ 68 resource.TestStep{ 69 Config: testAccBeanstalkEnvConfig, 70 Check: resource.ComposeTestCheckFunc( 71 testAccCheckBeanstalkEnvExists("aws_elastic_beanstalk_environment.tfenvtest", &app), 72 resource.TestMatchResourceAttr( 73 "aws_elastic_beanstalk_environment.tfenvtest", "autoscaling_groups.0", beanstalkAsgNameRegexp), 74 resource.TestMatchResourceAttr( 75 "aws_elastic_beanstalk_environment.tfenvtest", "load_balancers.0", beanstalkElbNameRegexp), 76 resource.TestMatchResourceAttr( 77 "aws_elastic_beanstalk_environment.tfenvtest", "instances.0", beanstalkInstancesNameRegexp), 78 resource.TestMatchResourceAttr( 79 "aws_elastic_beanstalk_environment.tfenvtest", "launch_configurations.0", beanstalkLcNameRegexp), 80 ), 81 }, 82 }, 83 }) 84 } 85 86 func TestAccAWSBeanstalkEnv_cname_prefix(t *testing.T) { 87 var app elasticbeanstalk.EnvironmentDescription 88 cnamePrefix := acctest.RandString(8) 89 beanstalkCnameRegexp := regexp.MustCompile("^" + cnamePrefix + ".+?elasticbeanstalk.com$") 90 91 resource.Test(t, resource.TestCase{ 92 PreCheck: func() { testAccPreCheck(t) }, 93 Providers: testAccProviders, 94 CheckDestroy: testAccCheckBeanstalkEnvDestroy, 95 Steps: []resource.TestStep{ 96 resource.TestStep{ 97 Config: testAccBeanstalkEnvCnamePrefixConfig(cnamePrefix), 98 Check: resource.ComposeTestCheckFunc( 99 testAccCheckBeanstalkEnvExists("aws_elastic_beanstalk_environment.tfenvtest", &app), 100 resource.TestMatchResourceAttr( 101 "aws_elastic_beanstalk_environment.tfenvtest", "cname", beanstalkCnameRegexp), 102 ), 103 }, 104 }, 105 }) 106 } 107 108 func TestAccAWSBeanstalkEnv_config(t *testing.T) { 109 var app elasticbeanstalk.EnvironmentDescription 110 111 resource.Test(t, resource.TestCase{ 112 PreCheck: func() { testAccPreCheck(t) }, 113 Providers: testAccProviders, 114 CheckDestroy: testAccCheckBeanstalkEnvDestroy, 115 Steps: []resource.TestStep{ 116 resource.TestStep{ 117 Config: testAccBeanstalkConfigTemplate, 118 Check: resource.ComposeTestCheckFunc( 119 testAccCheckBeanstalkEnvExists("aws_elastic_beanstalk_environment.tftest", &app), 120 testAccCheckBeanstalkEnvConfigValue("aws_elastic_beanstalk_environment.tftest", "1"), 121 ), 122 }, 123 124 resource.TestStep{ 125 Config: testAccBeanstalkConfigTemplateUpdate, 126 Check: resource.ComposeTestCheckFunc( 127 testAccCheckBeanstalkEnvExists("aws_elastic_beanstalk_environment.tftest", &app), 128 testAccCheckBeanstalkEnvConfigValue("aws_elastic_beanstalk_environment.tftest", "2"), 129 ), 130 }, 131 132 resource.TestStep{ 133 Config: testAccBeanstalkConfigTemplateUpdate, 134 Check: resource.ComposeTestCheckFunc( 135 testAccCheckBeanstalkEnvExists("aws_elastic_beanstalk_environment.tftest", &app), 136 testAccCheckBeanstalkEnvConfigValue("aws_elastic_beanstalk_environment.tftest", "3"), 137 ), 138 }, 139 }, 140 }) 141 } 142 143 func TestAccAWSBeanstalkEnv_resource(t *testing.T) { 144 var app elasticbeanstalk.EnvironmentDescription 145 146 resource.Test(t, resource.TestCase{ 147 PreCheck: func() { testAccPreCheck(t) }, 148 Providers: testAccProviders, 149 CheckDestroy: testAccCheckBeanstalkEnvDestroy, 150 Steps: []resource.TestStep{ 151 resource.TestStep{ 152 Config: testAccBeanstalkResourceOptionSetting, 153 Check: resource.ComposeTestCheckFunc( 154 testAccCheckBeanstalkEnvExists("aws_elastic_beanstalk_environment.tfenvtest", &app), 155 ), 156 }, 157 }, 158 }) 159 } 160 161 func TestAccAWSBeanstalkEnv_vpc(t *testing.T) { 162 var app elasticbeanstalk.EnvironmentDescription 163 164 resource.Test(t, resource.TestCase{ 165 PreCheck: func() { 166 testAccPreCheck(t) 167 }, 168 Providers: testAccProviders, 169 CheckDestroy: testAccCheckBeanstalkEnvDestroy, 170 Steps: []resource.TestStep{ 171 resource.TestStep{ 172 Config: testAccBeanstalkEnv_VPC(acctest.RandString(5)), 173 Check: resource.ComposeTestCheckFunc( 174 testAccCheckBeanstalkEnvExists("aws_elastic_beanstalk_environment.default", &app), 175 ), 176 }, 177 }, 178 }) 179 } 180 181 func testAccCheckBeanstalkEnvDestroy(s *terraform.State) error { 182 conn := testAccProvider.Meta().(*AWSClient).elasticbeanstalkconn 183 184 for _, rs := range s.RootModule().Resources { 185 if rs.Type != "aws_elastic_beanstalk_environment" { 186 continue 187 } 188 189 // Try to find the environment 190 describeBeanstalkEnvOpts := &elasticbeanstalk.DescribeEnvironmentsInput{ 191 EnvironmentIds: []*string{aws.String(rs.Primary.ID)}, 192 } 193 resp, err := conn.DescribeEnvironments(describeBeanstalkEnvOpts) 194 if err == nil { 195 switch { 196 case len(resp.Environments) > 1: 197 return fmt.Errorf("Error %d environments match, expected 1", len(resp.Environments)) 198 case len(resp.Environments) == 1: 199 if *resp.Environments[0].Status == "Terminated" { 200 return nil 201 } 202 return fmt.Errorf("Elastic Beanstalk ENV still exists.") 203 default: 204 return nil 205 } 206 } 207 208 // Verify the error is what we want 209 ec2err, ok := err.(awserr.Error) 210 if !ok { 211 return err 212 } 213 if ec2err.Code() != "InvalidBeanstalkEnvID.NotFound" { 214 return err 215 } 216 } 217 218 return nil 219 } 220 221 func testAccCheckBeanstalkEnvExists(n string, app *elasticbeanstalk.EnvironmentDescription) resource.TestCheckFunc { 222 return func(s *terraform.State) error { 223 rs, ok := s.RootModule().Resources[n] 224 if !ok { 225 return fmt.Errorf("Not found: %s", n) 226 } 227 228 if rs.Primary.ID == "" { 229 return fmt.Errorf("Elastic Beanstalk ENV is not set") 230 } 231 232 env, err := describeBeanstalkEnv(testAccProvider.Meta().(*AWSClient).elasticbeanstalkconn, aws.String(rs.Primary.ID)) 233 if err != nil { 234 return err 235 } 236 237 *app = *env 238 239 return nil 240 } 241 } 242 243 func testAccCheckBeanstalkEnvTier(n string, app *elasticbeanstalk.EnvironmentDescription) resource.TestCheckFunc { 244 return func(s *terraform.State) error { 245 rs, ok := s.RootModule().Resources[n] 246 if !ok { 247 return fmt.Errorf("Not found: %s", n) 248 } 249 250 if rs.Primary.ID == "" { 251 return fmt.Errorf("Elastic Beanstalk ENV is not set") 252 } 253 254 env, err := describeBeanstalkEnv(testAccProvider.Meta().(*AWSClient).elasticbeanstalkconn, aws.String(rs.Primary.ID)) 255 if err != nil { 256 return err 257 } 258 if *env.Tier.Name != "Worker" { 259 return fmt.Errorf("Beanstalk Environment tier is %s, expected Worker", *env.Tier.Name) 260 } 261 262 *app = *env 263 264 return nil 265 } 266 } 267 268 func testAccCheckBeanstalkEnvConfigValue(n string, expectedValue string) resource.TestCheckFunc { 269 return func(s *terraform.State) error { 270 conn := testAccProvider.Meta().(*AWSClient).elasticbeanstalkconn 271 272 rs, ok := s.RootModule().Resources[n] 273 if !ok { 274 return fmt.Errorf("Not found: %s", n) 275 } 276 277 if rs.Primary.ID == "" { 278 return fmt.Errorf("Elastic Beanstalk ENV is not set") 279 } 280 281 resp, err := conn.DescribeConfigurationOptions(&elasticbeanstalk.DescribeConfigurationOptionsInput{ 282 ApplicationName: aws.String(rs.Primary.Attributes["application"]), 283 EnvironmentName: aws.String(rs.Primary.Attributes["name"]), 284 Options: []*elasticbeanstalk.OptionSpecification{ 285 { 286 Namespace: aws.String("aws:elasticbeanstalk:application:environment"), 287 OptionName: aws.String("TEMPLATE"), 288 }, 289 }, 290 }) 291 if err != nil { 292 return err 293 } 294 295 if len(resp.Options) != 1 { 296 return fmt.Errorf("Found %d options, expected 1.", len(resp.Options)) 297 } 298 299 log.Printf("[DEBUG] %d Elastic Beanstalk Option values returned.", len(resp.Options[0].ValueOptions)) 300 301 for _, value := range resp.Options[0].ValueOptions { 302 if *value != expectedValue { 303 return fmt.Errorf("Option setting value: %s. Expected %s", *value, expectedValue) 304 } 305 } 306 307 return nil 308 } 309 } 310 311 func describeBeanstalkEnv(conn *elasticbeanstalk.ElasticBeanstalk, 312 envID *string) (*elasticbeanstalk.EnvironmentDescription, error) { 313 describeBeanstalkEnvOpts := &elasticbeanstalk.DescribeEnvironmentsInput{ 314 EnvironmentIds: []*string{envID}, 315 } 316 317 log.Printf("[DEBUG] Elastic Beanstalk Environment TEST describe opts: %s", describeBeanstalkEnvOpts) 318 319 resp, err := conn.DescribeEnvironments(describeBeanstalkEnvOpts) 320 if err != nil { 321 return &elasticbeanstalk.EnvironmentDescription{}, err 322 } 323 if len(resp.Environments) == 0 { 324 return &elasticbeanstalk.EnvironmentDescription{}, fmt.Errorf("Elastic Beanstalk ENV not found.") 325 } 326 if len(resp.Environments) > 1 { 327 return &elasticbeanstalk.EnvironmentDescription{}, fmt.Errorf("Found %d environments, expected 1.", len(resp.Environments)) 328 } 329 return resp.Environments[0], nil 330 } 331 332 const testAccBeanstalkEnvConfig = ` 333 resource "aws_elastic_beanstalk_application" "tftest" { 334 name = "tf-test-name" 335 description = "tf-test-desc" 336 } 337 338 resource "aws_elastic_beanstalk_environment" "tfenvtest" { 339 name = "tf-test-name" 340 application = "${aws_elastic_beanstalk_application.tftest.name}" 341 solution_stack_name = "64bit Amazon Linux running Python" 342 } 343 ` 344 345 const testAccBeanstalkWorkerEnvConfig = ` 346 resource "aws_iam_instance_profile" "tftest" { 347 name = "tftest_profile" 348 roles = ["${aws_iam_role.tftest.name}"] 349 } 350 351 resource "aws_iam_role" "tftest" { 352 name = "tftest_role" 353 path = "/" 354 assume_role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"ec2.amazonaws.com\"},\"Effect\":\"Allow\",\"Sid\":\"\"}]}" 355 } 356 357 resource "aws_iam_role_policy" "tftest" { 358 name = "tftest_policy" 359 role = "${aws_iam_role.tftest.id}" 360 policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"QueueAccess\",\"Action\":[\"sqs:ChangeMessageVisibility\",\"sqs:DeleteMessage\",\"sqs:ReceiveMessage\"],\"Effect\":\"Allow\",\"Resource\":\"*\"}]}" 361 } 362 363 resource "aws_elastic_beanstalk_application" "tftest" { 364 name = "tf-test-name" 365 description = "tf-test-desc" 366 } 367 368 resource "aws_elastic_beanstalk_environment" "tfenvtest" { 369 name = "tf-test-name" 370 application = "${aws_elastic_beanstalk_application.tftest.name}" 371 tier = "Worker" 372 solution_stack_name = "64bit Amazon Linux running Python" 373 374 setting { 375 namespace = "aws:autoscaling:launchconfiguration" 376 name = "IamInstanceProfile" 377 value = "${aws_iam_instance_profile.tftest.name}" 378 } 379 } 380 ` 381 382 func testAccBeanstalkEnvCnamePrefixConfig(randString string) string { 383 return fmt.Sprintf(` 384 resource "aws_elastic_beanstalk_application" "tftest" { 385 name = "tf-test-name" 386 description = "tf-test-desc" 387 } 388 389 resource "aws_elastic_beanstalk_environment" "tfenvtest" { 390 name = "tf-test-name" 391 application = "${aws_elastic_beanstalk_application.tftest.name}" 392 cname_prefix = "%s" 393 solution_stack_name = "64bit Amazon Linux running Python" 394 } 395 `, randString) 396 } 397 398 const testAccBeanstalkConfigTemplate = ` 399 resource "aws_elastic_beanstalk_application" "tftest" { 400 name = "tf-test-name" 401 description = "tf-test-desc" 402 } 403 404 resource "aws_elastic_beanstalk_environment" "tftest" { 405 name = "tf-test-name" 406 application = "${aws_elastic_beanstalk_application.tftest.name}" 407 template_name = "${aws_elastic_beanstalk_configuration_template.tftest.name}" 408 } 409 410 resource "aws_elastic_beanstalk_configuration_template" "tftest" { 411 name = "tf-test-original" 412 application = "${aws_elastic_beanstalk_application.tftest.name}" 413 solution_stack_name = "64bit Amazon Linux running Python" 414 415 setting { 416 namespace = "aws:elasticbeanstalk:application:environment" 417 name = "TEMPLATE" 418 value = "1" 419 } 420 } 421 ` 422 423 const testAccBeanstalkConfigTemplateUpdate = ` 424 resource "aws_elastic_beanstalk_application" "tftest" { 425 name = "tf-test-name" 426 description = "tf-test-desc" 427 } 428 429 resource "aws_elastic_beanstalk_environment" "tftest" { 430 name = "tf-test-name" 431 application = "${aws_elastic_beanstalk_application.tftest.name}" 432 template_name = "${aws_elastic_beanstalk_configuration_template.tftest.name}" 433 } 434 435 resource "aws_elastic_beanstalk_configuration_template" "tftest" { 436 name = "tf-test-updated" 437 application = "${aws_elastic_beanstalk_application.tftest.name}" 438 solution_stack_name = "64bit Amazon Linux running Python" 439 440 setting { 441 namespace = "aws:elasticbeanstalk:application:environment" 442 name = "TEMPLATE" 443 value = "2" 444 } 445 } 446 ` 447 448 const testAccBeanstalkConfigTemplateOverride = ` 449 resource "aws_elastic_beanstalk_application" "tftest" { 450 name = "tf-test-name" 451 description = "tf-test-desc" 452 } 453 454 resource "aws_elastic_beanstalk_environment" "tftest" { 455 name = "tf-test-name" 456 application = "${aws_elastic_beanstalk_application.tftest.name}" 457 template_name = "${aws_elastic_beanstalk_configuration_template.tftest.name}" 458 459 setting { 460 namespace = "aws:elasticbeanstalk:application:environment" 461 name = "TEMPLATE" 462 value = "3" 463 } 464 } 465 466 resource "aws_elastic_beanstalk_configuration_template" "tftest" { 467 name = "tf-test-updated" 468 application = "${aws_elastic_beanstalk_application.tftest.name}" 469 solution_stack_name = "64bit Amazon Linux running Python" 470 471 setting { 472 namespace = "aws:elasticbeanstalk:application:environment" 473 name = "TEMPLATE" 474 value = "2" 475 } 476 } 477 ` 478 const testAccBeanstalkResourceOptionSetting = ` 479 resource "aws_elastic_beanstalk_application" "tftest" { 480 name = "tf-test-name" 481 description = "tf-test-desc" 482 } 483 484 resource "aws_elastic_beanstalk_environment" "tfenvtest" { 485 name = "tf-test-name" 486 application = "${aws_elastic_beanstalk_application.tftest.name}" 487 solution_stack_name = "64bit Amazon Linux running Python" 488 489 setting { 490 namespace = "aws:autoscaling:scheduledaction" 491 resource = "ScheduledAction01" 492 name = "MinSize" 493 value = "2" 494 } 495 496 setting { 497 namespace = "aws:autoscaling:scheduledaction" 498 resource = "ScheduledAction01" 499 name = "MaxSize" 500 value = "6" 501 } 502 503 setting { 504 namespace = "aws:autoscaling:scheduledaction" 505 resource = "ScheduledAction01" 506 name = "Recurrence" 507 value = "0 8 * * *" 508 } 509 } 510 ` 511 512 func testAccBeanstalkEnv_VPC(name string) string { 513 return fmt.Sprintf(` 514 resource "aws_vpc" "tf_b_test" { 515 cidr_block = "10.0.0.0/16" 516 } 517 518 resource "aws_internet_gateway" "tf_b_test" { 519 vpc_id = "${aws_vpc.tf_b_test.id}" 520 } 521 522 resource "aws_route" "r" { 523 route_table_id = "${aws_vpc.tf_b_test.main_route_table_id}" 524 destination_cidr_block = "0.0.0.0/0" 525 gateway_id = "${aws_internet_gateway.tf_b_test.id}" 526 } 527 528 resource "aws_subnet" "main" { 529 vpc_id = "${aws_vpc.tf_b_test.id}" 530 cidr_block = "10.0.0.0/24" 531 } 532 533 resource "aws_security_group" "default" { 534 name = "tf-b-test-%s" 535 vpc_id = "${aws_vpc.tf_b_test.id}" 536 } 537 538 resource "aws_elastic_beanstalk_application" "default" { 539 name = "tf-test-name" 540 description = "tf-test-desc" 541 } 542 543 resource "aws_elastic_beanstalk_environment" "default" { 544 name = "tf-test-name" 545 application = "${aws_elastic_beanstalk_application.default.name}" 546 solution_stack_name = "64bit Amazon Linux running Python" 547 548 setting { 549 namespace = "aws:ec2:vpc" 550 name = "VPCId" 551 value = "${aws_vpc.tf_b_test.id}" 552 } 553 554 setting { 555 namespace = "aws:ec2:vpc" 556 name = "Subnets" 557 value = "${aws_subnet.main.id}" 558 } 559 560 setting { 561 namespace = "aws:ec2:vpc" 562 name = "AssociatePublicIpAddress" 563 value = "true" 564 } 565 566 setting { 567 namespace = "aws:autoscaling:launchconfiguration" 568 name = "SecurityGroups" 569 value = "${aws_security_group.default.id}" 570 } 571 } 572 `, name) 573 }