diff --git a/builtin/providers/aws/resource_aws_elastic_beanstalk_environment.go b/builtin/providers/aws/resource_aws_elastic_beanstalk_environment.go index 4dbb5a375..b0acdd034 100644 --- a/builtin/providers/aws/resource_aws_elastic_beanstalk_environment.go +++ b/builtin/providers/aws/resource_aws_elastic_beanstalk_environment.go @@ -256,50 +256,18 @@ func resourceAwsElasticBeanstalkEnvironmentCreate(d *schema.ResourceData, meta i func resourceAwsElasticBeanstalkEnvironmentUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).elasticbeanstalkconn + envId := d.Id() + + updateOpts := elasticbeanstalk.UpdateEnvironmentInput{ + EnvironmentId: aws.String(envId), + } + if d.HasChange("description") { - if err := resourceAwsElasticBeanstalkEnvironmentDescriptionUpdate(conn, d); err != nil { - return err - } + updateOpts.Description = aws.String(d.Get("description").(string)) } if d.HasChange("solution_stack_name") { - if err := resourceAwsElasticBeanstalkEnvironmentSolutionStackUpdate(conn, d); err != nil { - return err - } - } - - if d.HasChange("setting") { - if err := resourceAwsElasticBeanstalkEnvironmentOptionSettingsUpdate(conn, d); err != nil { - return err - } - } - - return resourceAwsElasticBeanstalkEnvironmentRead(d, meta) -} - -func resourceAwsElasticBeanstalkEnvironmentDescriptionUpdate(conn *elasticbeanstalk.ElasticBeanstalk, d *schema.ResourceData) error { - name := d.Get("name").(string) - desc := d.Get("description").(string) - envId := d.Id() - - log.Printf("[DEBUG] Elastic Beanstalk application: %s, update description: %s", name, desc) - - _, err := conn.UpdateEnvironment(&elasticbeanstalk.UpdateEnvironmentInput{ - EnvironmentId: aws.String(envId), - Description: aws.String(desc), - }) - - return err -} - -func resourceAwsElasticBeanstalkEnvironmentOptionSettingsUpdate(conn *elasticbeanstalk.ElasticBeanstalk, d *schema.ResourceData) error { - name := d.Get("name").(string) - envId := d.Id() - - log.Printf("[DEBUG] Elastic Beanstalk application: %s, update options", name) - - req := &elasticbeanstalk.UpdateEnvironmentInput{ - EnvironmentId: aws.String(envId), + updateOpts.SolutionStackName = aws.String(d.Get("solution_stack_name").(string)) } if d.HasChange("setting") { @@ -314,29 +282,36 @@ func resourceAwsElasticBeanstalkEnvironmentOptionSettingsUpdate(conn *elasticbea os := o.(*schema.Set) ns := n.(*schema.Set) - req.OptionSettings = extractOptionSettings(ns.Difference(os)) + updateOpts.OptionSettings = extractOptionSettings(ns.Difference(os)) } - if _, err := conn.UpdateEnvironment(req); err != nil { + if d.HasChange("template_name") { + updateOpts.TemplateName = aws.String(d.Get("template_name").(string)) + } + + log.Printf("[DEBUG] Elastic Beanstalk Environment update opts: %s", updateOpts) + _, err := conn.UpdateEnvironment(&updateOpts) + if err != nil { return err } - return nil -} + stateConf := &resource.StateChangeConf{ + Pending: []string{"Launching", "Updating"}, + Target: []string{"Ready"}, + Refresh: environmentStateRefreshFunc(conn, d.Id()), + Timeout: 10 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } -func resourceAwsElasticBeanstalkEnvironmentSolutionStackUpdate(conn *elasticbeanstalk.ElasticBeanstalk, d *schema.ResourceData) error { - name := d.Get("name").(string) - solutionStack := d.Get("solution_stack_name").(string) - envId := d.Id() + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf( + "Error waiting for Elastic Beanstalk Environment (%s) to become ready: %s", + d.Id(), err) + } - log.Printf("[DEBUG] Elastic Beanstalk application: %s, update solution_stack_name: %s", name, solutionStack) - - _, err := conn.UpdateEnvironment(&elasticbeanstalk.UpdateEnvironmentInput{ - EnvironmentId: aws.String(envId), - SolutionStackName: aws.String(solutionStack), - }) - - return err + return resourceAwsElasticBeanstalkEnvironmentRead(d, meta) } func resourceAwsElasticBeanstalkEnvironmentRead(d *schema.ResourceData, meta interface{}) error { diff --git a/builtin/providers/aws/resource_aws_elastic_beanstalk_environment_test.go b/builtin/providers/aws/resource_aws_elastic_beanstalk_environment_test.go index 5a9d14379..9d4b9eafa 100644 --- a/builtin/providers/aws/resource_aws_elastic_beanstalk_environment_test.go +++ b/builtin/providers/aws/resource_aws_elastic_beanstalk_environment_test.go @@ -105,6 +105,41 @@ func TestAccAWSBeanstalkEnv_cname_prefix(t *testing.T) { }) } +func TestAccAWSBeanstalkEnv_config(t *testing.T) { + var app elasticbeanstalk.EnvironmentDescription + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckBeanstalkEnvDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccBeanstalkConfigTemplate, + Check: resource.ComposeTestCheckFunc( + testAccCheckBeanstalkEnvExists("aws_elastic_beanstalk_environment.tftest", &app), + testAccCheckBeanstalkEnvConfigValue("aws_elastic_beanstalk_environment.tftest", "1"), + ), + }, + + resource.TestStep{ + Config: testAccBeanstalkConfigTemplateUpdate, + Check: resource.ComposeTestCheckFunc( + testAccCheckBeanstalkEnvExists("aws_elastic_beanstalk_environment.tftest", &app), + testAccCheckBeanstalkEnvConfigValue("aws_elastic_beanstalk_environment.tftest", "2"), + ), + }, + + resource.TestStep{ + Config: testAccBeanstalkConfigTemplateUpdate, + Check: resource.ComposeTestCheckFunc( + testAccCheckBeanstalkEnvExists("aws_elastic_beanstalk_environment.tftest", &app), + testAccCheckBeanstalkEnvConfigValue("aws_elastic_beanstalk_environment.tftest", "3"), + ), + }, + }, + }) +} + func testAccCheckBeanstalkEnvDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).elasticbeanstalkconn @@ -192,6 +227,49 @@ func testAccCheckBeanstalkEnvTier(n string, app *elasticbeanstalk.EnvironmentDes } } +func testAccCheckBeanstalkEnvConfigValue(n string, expectedValue string) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).elasticbeanstalkconn + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("Elastic Beanstalk ENV is not set") + } + + resp, err := conn.DescribeConfigurationOptions(&elasticbeanstalk.DescribeConfigurationOptionsInput{ + ApplicationName: aws.String(rs.Primary.Attributes["application"]), + EnvironmentName: aws.String(rs.Primary.Attributes["name"]), + Options: []*elasticbeanstalk.OptionSpecification{ + { + Namespace: aws.String("aws:elasticbeanstalk:application:environment"), + OptionName: aws.String("TEMPLATE"), + }, + }, + }) + if err != nil { + return err + } + + if len(resp.Options) != 1 { + return fmt.Errorf("Found %d options, expected 1.", len(resp.Options)) + } + + log.Printf("[DEBUG] %d Elastic Beanstalk Option values returned.", len(resp.Options[0].ValueOptions)) + + for _, value := range resp.Options[0].ValueOptions { + if *value != expectedValue { + return fmt.Errorf("Option setting value: %s. Expected %s", value, expectedValue) + } + } + + return nil + } +} + func describeBeanstalkEnv(conn *elasticbeanstalk.ElasticBeanstalk, envID *string) (*elasticbeanstalk.EnvironmentDescription, error) { describeBeanstalkEnvOpts := &elasticbeanstalk.DescribeEnvironmentsInput{ @@ -255,3 +333,84 @@ solution_stack_name = "64bit Amazon Linux running Python" } `, randString) } + +const testAccBeanstalkConfigTemplate = ` +resource "aws_elastic_beanstalk_application" "tftest" { + name = "tf-test-name" + description = "tf-test-desc" +} + +resource "aws_elastic_beanstalk_environment" "tftest" { + name = "tf-test-name" + application = "${aws_elastic_beanstalk_application.tftest.name}" + template_name = "${aws_elastic_beanstalk_configuration_template.tftest.name}" +} + +resource "aws_elastic_beanstalk_configuration_template" "tftest" { + name = "tf-test-original" + application = "${aws_elastic_beanstalk_application.tftest.name}" + solution_stack_name = "64bit Amazon Linux running Python" + + setting { + namespace = "aws:elasticbeanstalk:application:environment" + name = "TEMPLATE" + value = "1" + } +} +` + +const testAccBeanstalkConfigTemplateUpdate = ` +resource "aws_elastic_beanstalk_application" "tftest" { + name = "tf-test-name" + description = "tf-test-desc" +} + +resource "aws_elastic_beanstalk_environment" "tftest" { + name = "tf-test-name" + application = "${aws_elastic_beanstalk_application.tftest.name}" + template_name = "${aws_elastic_beanstalk_configuration_template.tftest.name}" +} + +resource "aws_elastic_beanstalk_configuration_template" "tftest" { + name = "tf-test-updated" + application = "${aws_elastic_beanstalk_application.tftest.name}" + solution_stack_name = "64bit Amazon Linux running Python" + + setting { + namespace = "aws:elasticbeanstalk:application:environment" + name = "TEMPLATE" + value = "2" + } +} +` + +const testAccBeanstalkConfigTemplateOverride = ` +resource "aws_elastic_beanstalk_application" "tftest" { + name = "tf-test-name" + description = "tf-test-desc" +} + +resource "aws_elastic_beanstalk_environment" "tftest" { + name = "tf-test-name" + application = "${aws_elastic_beanstalk_application.tftest.name}" + template_name = "${aws_elastic_beanstalk_configuration_template.tftest.name}" + + setting { + namespace = "aws:elasticbeanstalk:application:environment" + name = "TEMPLATE" + value = "3" + } +} + +resource "aws_elastic_beanstalk_configuration_template" "tftest" { + name = "tf-test-updated" + application = "${aws_elastic_beanstalk_application.tftest.name}" + solution_stack_name = "64bit Amazon Linux running Python" + + setting { + namespace = "aws:elasticbeanstalk:application:environment" + name = "TEMPLATE" + value = "2" + } +} +`