provider/aws: Elastic Beanstalk Environment update configuration template name changes (#6342)

* Updated `aws_elastic_beanstalk_environment` to update environment when the `template_name` attribute has a change. Consildated update functions to use a single update call and added state change conf to wait until environment is in a "Ready" state.

* Adding tests for `aws_elastic_beanstalk_configuration_template` use with the `aws_elastic_beanstalk_environment` resource.

* Verifies option settings from an `aws_elastic_beanstalk_configuration_template` resource are applied to the associated `aws_elastic_beanstalk_environment` resource
* Verifies updated name of an `aws_elastic_beanstalk_configuration_template` resource triggers an update for the associated `aws_elastic_beanstalk_environment` resource
* Verifies that option settings set in the `aws_elastic_beanstalk_environment` resource override settings in the `aws_elastic_beanstalk_configuration_template` resource
This commit is contained in:
David Harris 2016-04-26 04:15:46 -06:00 committed by Paul Stack
parent 47c2b8247d
commit 9ab2447b0b
2 changed files with 190 additions and 56 deletions

View File

@ -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 {

View File

@ -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"
}
}
`