diff --git a/aws/resource_aws_codedeploy_app.go b/aws/resource_aws_codedeploy_app.go index 6c539c382bb..afe29c81928 100644 --- a/aws/resource_aws_codedeploy_app.go +++ b/aws/resource_aws_codedeploy_app.go @@ -19,6 +19,38 @@ func resourceAwsCodeDeployApp() *schema.Resource { Read: resourceAwsCodeDeployAppRead, Update: resourceAwsCodeDeployUpdate, Delete: resourceAwsCodeDeployAppDelete, + Importer: &schema.ResourceImporter{ + State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + idParts := strings.Split(d.Id(), ":") + + if len(idParts) == 2 { + return []*schema.ResourceData{d}, nil + } + + applicationName := d.Id() + conn := meta.(*AWSClient).codedeployconn + + input := &codedeploy.GetApplicationInput{ + ApplicationName: aws.String(applicationName), + } + + log.Printf("[DEBUG] Reading CodeDeploy Application: %s", input) + output, err := conn.GetApplication(input) + + if err != nil { + return []*schema.ResourceData{}, err + } + + if output == nil || output.Application == nil { + return []*schema.ResourceData{}, fmt.Errorf("error reading CodeDeploy Application (%s): empty response", applicationName) + } + + d.SetId(fmt.Sprintf("%s:%s", aws.StringValue(output.Application.ApplicationId), applicationName)) + d.Set("name", applicationName) + + return []*schema.ResourceData{d}, nil + }, + }, Schema: map[string]*schema.Schema{ "name": { diff --git a/aws/resource_aws_codedeploy_app_test.go b/aws/resource_aws_codedeploy_app_test.go index 04bc7565808..357a341c05f 100644 --- a/aws/resource_aws_codedeploy_app_test.go +++ b/aws/resource_aws_codedeploy_app_test.go @@ -1,11 +1,11 @@ package aws import ( + "errors" "fmt" "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/codedeploy" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" @@ -13,52 +13,105 @@ import ( ) func TestAccAWSCodeDeployApp_basic(t *testing.T) { + var application1 codedeploy.ApplicationInfo + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_codedeploy_app.test" + resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSCodeDeployAppDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCodeDeployApp, + Config: testAccAWSCodeDeployAppConfigName(rName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("aws_codedeploy_app.foo", "compute_platform", "Server"), - testAccCheckAWSCodeDeployAppExists("aws_codedeploy_app.foo"), + testAccCheckAWSCodeDeployAppExists(resourceName, &application1), + resource.TestCheckResourceAttr(resourceName, "compute_platform", "Server"), + resource.TestCheckResourceAttr(resourceName, "name", rName), ), }, + // Import by ID { - Config: testAccAWSCodeDeployAppModified, - Check: resource.ComposeTestCheckFunc( - testAccCheckAWSCodeDeployAppExists("aws_codedeploy_app.foo"), - ), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + // Import by name + { + ResourceName: resourceName, + ImportState: true, + ImportStateId: rName, + ImportStateVerify: true, }, }, }) } func TestAccAWSCodeDeployApp_computePlatform(t *testing.T) { - rName := acctest.RandString(5) + var application1, application2 codedeploy.ApplicationInfo + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_codedeploy_app.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSCodeDeployAppDestroy, Steps: []resource.TestStep{ + { + Config: testAccAWSCodeDeployAppConfigComputePlatform(rName, "Lambda"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeDeployAppExists(resourceName, &application1), + resource.TestCheckResourceAttr(resourceName, "compute_platform", "Lambda"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, { Config: testAccAWSCodeDeployAppConfigComputePlatform(rName, "Server"), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSCodeDeployAppExists("aws_codedeploy_app.foo"), - resource.TestCheckResourceAttr( - "aws_codedeploy_app.foo", "compute_platform", "Server"), + testAccCheckAWSCodeDeployAppExists(resourceName, &application2), + testAccCheckAWSCodeDeployAppRecreated(&application1, &application2), + resource.TestCheckResourceAttr(resourceName, "compute_platform", "Server"), + ), + }, + }, + }) +} + +func TestAccAWSCodeDeployApp_name(t *testing.T) { + var application1, application2 codedeploy.ApplicationInfo + rName1 := acctest.RandomWithPrefix("tf-acc-test") + rName2 := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_codedeploy_app.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCodeDeployAppDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCodeDeployAppConfigName(rName1), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeDeployAppExists(resourceName, &application1), + resource.TestCheckResourceAttr(resourceName, "name", rName1), ), }, { - Config: testAccAWSCodeDeployAppConfigComputePlatform(rName, "Lambda"), + Config: testAccAWSCodeDeployAppConfigName(rName2), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSCodeDeployAppExists("aws_codedeploy_app.foo"), - resource.TestCheckResourceAttr( - "aws_codedeploy_app.foo", "compute_platform", "Lambda"), + testAccCheckAWSCodeDeployAppExists(resourceName, &application2), + testAccCheckAWSCodeDeployAppRecreated(&application1, &application2), + resource.TestCheckResourceAttr(resourceName, "name", rName2), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -75,11 +128,11 @@ func testAccCheckAWSCodeDeployAppDestroy(s *terraform.State) error { ApplicationName: aws.String(rs.Primary.Attributes["name"]), }) + if isAWSErr(err, codedeploy.ErrCodeApplicationDoesNotExistException, "") { + continue + } + if err != nil { - // Verify the error is what we want - if ae, ok := err.(awserr.Error); ok && ae.Code() == "ApplicationDoesNotExistException" { - continue - } return err } @@ -89,31 +142,58 @@ func testAccCheckAWSCodeDeployAppDestroy(s *terraform.State) error { return nil } -func testAccCheckAWSCodeDeployAppExists(name string) resource.TestCheckFunc { +func testAccCheckAWSCodeDeployAppExists(name string, application *codedeploy.ApplicationInfo) resource.TestCheckFunc { return func(s *terraform.State) error { - _, ok := s.RootModule().Resources[name] + rs, ok := s.RootModule().Resources[name] if !ok { return fmt.Errorf("Not found: %s", name) } + conn := testAccProvider.Meta().(*AWSClient).codedeployconn + + input := &codedeploy.GetApplicationInput{ + ApplicationName: aws.String(rs.Primary.Attributes["name"]), + } + + output, err := conn.GetApplication(input) + + if err != nil { + return err + } + + if output == nil || output.Application == nil { + return fmt.Errorf("error reading CodeDeploy Application (%s): empty response", rs.Primary.ID) + } + + *application = *output.Application + return nil } } -func testAccAWSCodeDeployAppConfigComputePlatform(rName string, value string) string { - return fmt.Sprintf(` -resource "aws_codedeploy_app" "foo" { - name = "test-codedeploy-app-%s" - compute_platform = "%s" -}`, rName, value) +func testAccCheckAWSCodeDeployAppRecreated(i, j *codedeploy.ApplicationInfo) resource.TestCheckFunc { + return func(s *terraform.State) error { + if aws.TimeValue(i.CreateTime) == aws.TimeValue(j.CreateTime) { + return errors.New("CodeDeploy Application was not recreated") + } + + return nil + } } -var testAccAWSCodeDeployApp = ` -resource "aws_codedeploy_app" "foo" { - name = "foo" -}` +func testAccAWSCodeDeployAppConfigComputePlatform(rName string, computePlatform string) string { + return fmt.Sprintf(` +resource "aws_codedeploy_app" "test" { + compute_platform = %q + name = %q +} +`, computePlatform, rName) +} -var testAccAWSCodeDeployAppModified = ` -resource "aws_codedeploy_app" "foo" { - name = "bar" -}` +func testAccAWSCodeDeployAppConfigName(rName string) string { + return fmt.Sprintf(` +resource "aws_codedeploy_app" "test" { + name = %q +} +`, rName) +} diff --git a/aws/resource_aws_codedeploy_deployment_config.go b/aws/resource_aws_codedeploy_deployment_config.go index 8be6b93337e..e88bef02062 100644 --- a/aws/resource_aws_codedeploy_deployment_config.go +++ b/aws/resource_aws_codedeploy_deployment_config.go @@ -16,6 +16,9 @@ func resourceAwsCodeDeployDeploymentConfig() *schema.Resource { Create: resourceAwsCodeDeployDeploymentConfigCreate, Read: resourceAwsCodeDeployDeploymentConfigRead, Delete: resourceAwsCodeDeployDeploymentConfigDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, Schema: map[string]*schema.Schema{ "deployment_config_name": { diff --git a/aws/resource_aws_codedeploy_deployment_config_test.go b/aws/resource_aws_codedeploy_deployment_config_test.go index 11a40e98af0..37428ae30e9 100644 --- a/aws/resource_aws_codedeploy_deployment_config_test.go +++ b/aws/resource_aws_codedeploy_deployment_config_test.go @@ -6,17 +6,42 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/codedeploy" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" ) +func TestAccAWSCodeDeployDeploymentConfig_basic(t *testing.T) { + var config1 codedeploy.DeploymentConfigInfo + resourceName := "aws_codedeploy_deployment_config.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCodeDeployDeploymentConfigDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCodeDeployDeploymentConfigFleet(rName, 75), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeDeployDeploymentConfigExists(resourceName, &config1), + resource.TestCheckResourceAttr(resourceName, "deployment_config_name", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAWSCodeDeployDeploymentConfig_fleetPercent(t *testing.T) { var config1, config2 codedeploy.DeploymentConfigInfo - - rName := acctest.RandString(5) + resourceName := "aws_codedeploy_deployment_config.test" + rName := acctest.RandomWithPrefix("tf-acc-test") resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -26,32 +51,35 @@ func TestAccAWSCodeDeployDeploymentConfig_fleetPercent(t *testing.T) { { Config: testAccAWSCodeDeployDeploymentConfigFleet(rName, 75), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSCodeDeployDeploymentConfigExists("aws_codedeploy_deployment_config.foo", &config1), - resource.TestCheckResourceAttr( - "aws_codedeploy_deployment_config.foo", "minimum_healthy_hosts.0.type", "FLEET_PERCENT"), - resource.TestCheckResourceAttr( - "aws_codedeploy_deployment_config.foo", "minimum_healthy_hosts.0.value", "75"), + testAccCheckAWSCodeDeployDeploymentConfigExists(resourceName, &config1), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.#", "1"), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.0.type", "FLEET_PERCENT"), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.0.value", "75"), ), }, { Config: testAccAWSCodeDeployDeploymentConfigFleet(rName, 50), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSCodeDeployDeploymentConfigExists("aws_codedeploy_deployment_config.foo", &config2), + testAccCheckAWSCodeDeployDeploymentConfigExists(resourceName, &config2), testAccCheckAWSCodeDeployDeploymentConfigRecreated(&config1, &config2), - resource.TestCheckResourceAttr( - "aws_codedeploy_deployment_config.foo", "minimum_healthy_hosts.0.type", "FLEET_PERCENT"), - resource.TestCheckResourceAttr( - "aws_codedeploy_deployment_config.foo", "minimum_healthy_hosts.0.value", "50"), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.#", "1"), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.0.type", "FLEET_PERCENT"), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.0.value", "50"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } func TestAccAWSCodeDeployDeploymentConfig_hostCount(t *testing.T) { var config1, config2 codedeploy.DeploymentConfigInfo - - rName := acctest.RandString(5) + resourceName := "aws_codedeploy_deployment_config.test" + rName := acctest.RandomWithPrefix("tf-acc-test") resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -61,24 +89,27 @@ func TestAccAWSCodeDeployDeploymentConfig_hostCount(t *testing.T) { { Config: testAccAWSCodeDeployDeploymentConfigHostCount(rName, 1), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSCodeDeployDeploymentConfigExists("aws_codedeploy_deployment_config.foo", &config1), - resource.TestCheckResourceAttr( - "aws_codedeploy_deployment_config.foo", "minimum_healthy_hosts.0.type", "HOST_COUNT"), - resource.TestCheckResourceAttr( - "aws_codedeploy_deployment_config.foo", "minimum_healthy_hosts.0.value", "1"), + testAccCheckAWSCodeDeployDeploymentConfigExists(resourceName, &config1), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.#", "1"), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.0.type", "HOST_COUNT"), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.0.value", "1"), ), }, { Config: testAccAWSCodeDeployDeploymentConfigHostCount(rName, 2), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSCodeDeployDeploymentConfigExists("aws_codedeploy_deployment_config.foo", &config2), + testAccCheckAWSCodeDeployDeploymentConfigExists(resourceName, &config2), testAccCheckAWSCodeDeployDeploymentConfigRecreated(&config1, &config2), - resource.TestCheckResourceAttr( - "aws_codedeploy_deployment_config.foo", "minimum_healthy_hosts.0.type", "HOST_COUNT"), - resource.TestCheckResourceAttr( - "aws_codedeploy_deployment_config.foo", "minimum_healthy_hosts.0.value", "2"), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.#", "1"), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.0.type", "HOST_COUNT"), + resource.TestCheckResourceAttr(resourceName, "minimum_healthy_hosts.0.value", "2"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -95,7 +126,7 @@ func testAccCheckAWSCodeDeployDeploymentConfigDestroy(s *terraform.State) error DeploymentConfigName: aws.String(rs.Primary.ID), }) - if ae, ok := err.(awserr.Error); ok && ae.Code() == "DeploymentConfigDoesNotExistException" { + if isAWSErr(err, codedeploy.ErrCodeDeploymentConfigDoesNotExistException, "") { continue } @@ -146,22 +177,26 @@ func testAccCheckAWSCodeDeployDeploymentConfigRecreated(i, j *codedeploy.Deploym func testAccAWSCodeDeployDeploymentConfigFleet(rName string, value int) string { return fmt.Sprintf(` -resource "aws_codedeploy_deployment_config" "foo" { - deployment_config_name = "test-deployment-config-%s" - minimum_healthy_hosts { - type = "FLEET_PERCENT" - value = %d - } -}`, rName, value) +resource "aws_codedeploy_deployment_config" "test" { + deployment_config_name = %q + + minimum_healthy_hosts { + type = "FLEET_PERCENT" + value = %d + } +} +`, rName, value) } func testAccAWSCodeDeployDeploymentConfigHostCount(rName string, value int) string { return fmt.Sprintf(` -resource "aws_codedeploy_deployment_config" "foo" { - deployment_config_name = "test-deployment-config-%s" - minimum_healthy_hosts { - type = "HOST_COUNT" - value = %d - } -}`, rName, value) +resource "aws_codedeploy_deployment_config" "test" { + deployment_config_name = %q + + minimum_healthy_hosts { + type = "HOST_COUNT" + value = %d + } +} +`, rName, value) } diff --git a/aws/resource_aws_codedeploy_deployment_group.go b/aws/resource_aws_codedeploy_deployment_group.go index 178273b9b9f..5e034d34065 100644 --- a/aws/resource_aws_codedeploy_deployment_group.go +++ b/aws/resource_aws_codedeploy_deployment_group.go @@ -6,6 +6,7 @@ import ( "log" "regexp" "sort" + "strings" "time" "github.com/hashicorp/terraform/helper/hashcode" @@ -24,6 +25,41 @@ func resourceAwsCodeDeployDeploymentGroup() *schema.Resource { Read: resourceAwsCodeDeployDeploymentGroupRead, Update: resourceAwsCodeDeployDeploymentGroupUpdate, Delete: resourceAwsCodeDeployDeploymentGroupDelete, + Importer: &schema.ResourceImporter{ + State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + idParts := strings.Split(d.Id(), ":") + + if len(idParts) != 2 { + return []*schema.ResourceData{}, fmt.Errorf("expected ID in format ApplicationName:DeploymentGroupName, received: %s", d.Id()) + } + + applicationName := idParts[0] + deploymentGroupName := idParts[1] + conn := meta.(*AWSClient).codedeployconn + + input := &codedeploy.GetDeploymentGroupInput{ + ApplicationName: aws.String(applicationName), + DeploymentGroupName: aws.String(deploymentGroupName), + } + + log.Printf("[DEBUG] Reading CodeDeploy Application: %s", input) + output, err := conn.GetDeploymentGroup(input) + + if err != nil { + return []*schema.ResourceData{}, err + } + + if output == nil || output.DeploymentGroupInfo == nil { + return []*schema.ResourceData{}, fmt.Errorf("error reading CodeDeploy Application (%s): empty response", d.Id()) + } + + d.SetId(aws.StringValue(output.DeploymentGroupInfo.DeploymentGroupId)) + d.Set("app_name", applicationName) + d.Set("deployment_group_name", deploymentGroupName) + + return []*schema.ResourceData{d}, nil + }, + }, Schema: map[string]*schema.Schema{ "app_name": { @@ -471,11 +507,18 @@ func resourceAwsCodeDeployDeploymentGroupRead(d *schema.ResourceData, meta inter } d.Set("app_name", resp.DeploymentGroupInfo.ApplicationName) - d.Set("autoscaling_groups", resp.DeploymentGroupInfo.AutoScalingGroups) d.Set("deployment_config_name", resp.DeploymentGroupInfo.DeploymentConfigName) d.Set("deployment_group_name", resp.DeploymentGroupInfo.DeploymentGroupName) d.Set("service_role_arn", resp.DeploymentGroupInfo.ServiceRoleArn) + autoScalingGroups := make([]string, len(resp.DeploymentGroupInfo.AutoScalingGroups)) + for i, autoScalingGroup := range resp.DeploymentGroupInfo.AutoScalingGroups { + autoScalingGroups[i] = aws.StringValue(autoScalingGroup.Name) + } + if err := d.Set("autoscaling_groups", autoScalingGroups); err != nil { + return fmt.Errorf("error setting autoscaling_groups: %s", err) + } + if err := d.Set("deployment_style", flattenDeploymentStyle(resp.DeploymentGroupInfo.DeploymentStyle)); err != nil { return err } diff --git a/aws/resource_aws_codedeploy_deployment_group_test.go b/aws/resource_aws_codedeploy_deployment_group_test.go index 4c3dad7ddcb..2ecc64b052f 100644 --- a/aws/resource_aws_codedeploy_deployment_group_test.go +++ b/aws/resource_aws_codedeploy_deployment_group_test.go @@ -94,6 +94,12 @@ func TestAccAWSCodeDeployDeploymentGroup_basic(t *testing.T) { "aws_codedeploy_deployment_group.foo", "trigger_configuration.#", "0"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo"), + ImportStateVerify: true, + }, }, }) } @@ -178,6 +184,12 @@ func TestAccAWSCodeDeployDeploymentGroup_basic_tagSet(t *testing.T) { "aws_codedeploy_deployment_group.foo", "trigger_configuration.#", "0"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo"), + ImportStateVerify: true, + }, }, }) } @@ -213,6 +225,12 @@ func TestAccAWSCodeDeployDeploymentGroup_onPremiseTag(t *testing.T) { "aws_codedeploy_deployment_group.foo", "on_premises_instance_tag_filter.2916377465.value", "filtervalue"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo"), + ImportStateVerify: true, + }, }, }) } @@ -275,6 +293,12 @@ func TestAccAWSCodeDeployDeploymentGroup_triggerConfiguration_basic(t *testing.T }), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -328,6 +352,12 @@ func TestAccAWSCodeDeployDeploymentGroup_triggerConfiguration_multiple(t *testin regexp.MustCompile("^arn:aws:sns:[^:]+:[0-9]{12}:baz-topic-"+rName+"$")), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -364,6 +394,12 @@ func TestAccAWSCodeDeployDeploymentGroup_autoRollbackConfiguration_create(t *tes "aws_codedeploy_deployment_group.foo_group", "auto_rollback_configuration.0.events.135881253", "DEPLOYMENT_FAILURE"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -408,6 +444,12 @@ func TestAccAWSCodeDeployDeploymentGroup_autoRollbackConfiguration_update(t *tes "aws_codedeploy_deployment_group.foo_group", "auto_rollback_configuration.0.events.135881253", "DEPLOYMENT_FAILURE"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -444,6 +486,12 @@ func TestAccAWSCodeDeployDeploymentGroup_autoRollbackConfiguration_delete(t *tes "aws_codedeploy_deployment_group.foo_group", "auto_rollback_configuration.#", "0"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -486,6 +534,12 @@ func TestAccAWSCodeDeployDeploymentGroup_autoRollbackConfiguration_disable(t *te "aws_codedeploy_deployment_group.foo_group", "auto_rollback_configuration.0.events.135881253", "DEPLOYMENT_FAILURE"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -524,6 +578,12 @@ func TestAccAWSCodeDeployDeploymentGroup_alarmConfiguration_create(t *testing.T) "aws_codedeploy_deployment_group.foo_group", "alarm_configuration.0.ignore_poll_alarm_failure", "false"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -572,6 +632,12 @@ func TestAccAWSCodeDeployDeploymentGroup_alarmConfiguration_update(t *testing.T) "aws_codedeploy_deployment_group.foo_group", "alarm_configuration.0.ignore_poll_alarm_failure", "true"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -610,6 +676,12 @@ func TestAccAWSCodeDeployDeploymentGroup_alarmConfiguration_delete(t *testing.T) "aws_codedeploy_deployment_group.foo_group", "alarm_configuration.#", "0"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -656,6 +728,12 @@ func TestAccAWSCodeDeployDeploymentGroup_alarmConfiguration_disable(t *testing.T "aws_codedeploy_deployment_group.foo_group", "alarm_configuration.0.ignore_poll_alarm_failure", "false"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -683,6 +761,12 @@ func TestAccAWSCodeDeployDeploymentGroup_deploymentStyle_default(t *testing.T) { "aws_codedeploy_deployment_group.foo_group", "deployment_style.0.deployment_type"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -728,6 +812,12 @@ func TestAccAWSCodeDeployDeploymentGroup_deploymentStyle_create(t *testing.T) { "aws_codedeploy_deployment_group.foo_group", "load_balancer_info.0.elb_info.2441772102.name", "foo-elb"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -766,6 +856,12 @@ func TestAccAWSCodeDeployDeploymentGroup_deploymentStyle_update(t *testing.T) { "aws_codedeploy_deployment_group.foo_group", "deployment_style.0.deployment_type", "IN_PLACE"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -806,6 +902,12 @@ func TestAccAWSCodeDeployDeploymentGroup_deploymentStyle_delete(t *testing.T) { "aws_codedeploy_deployment_group.foo_group", "deployment_style.0.deployment_type"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -840,6 +942,12 @@ func TestAccAWSCodeDeployDeploymentGroup_loadBalancerInfo_create(t *testing.T) { "aws_codedeploy_deployment_group.foo_group", "load_balancer_info.0.elb_info.2441772102.name", "foo-elb"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -878,6 +986,12 @@ func TestAccAWSCodeDeployDeploymentGroup_loadBalancerInfo_update(t *testing.T) { "aws_codedeploy_deployment_group.foo_group", "load_balancer_info.0.elb_info.4206303396.name", "bar-elb"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -914,6 +1028,12 @@ func TestAccAWSCodeDeployDeploymentGroup_loadBalancerInfo_delete(t *testing.T) { "aws_codedeploy_deployment_group.foo_group", "load_balancer_info.#", "1"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -949,6 +1069,12 @@ func TestAccAWSCodeDeployDeploymentGroup_loadBalancerInfo_targetGroupInfo_create "aws_codedeploy_deployment_group.foo_group", "load_balancer_info.0.target_group_info.4178177480.name", "foo-tg"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -987,6 +1113,12 @@ func TestAccAWSCodeDeployDeploymentGroup_loadBalancerInfo_targetGroupInfo_update "aws_codedeploy_deployment_group.foo_group", "load_balancer_info.0.target_group_info.2940009368.name", "bar-tg"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -1021,6 +1153,12 @@ func TestAccAWSCodeDeployDeploymentGroup_loadBalancerInfo_targetGroupInfo_delete "aws_codedeploy_deployment_group.foo_group", "load_balancer_info.#", "1"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -1068,6 +1206,12 @@ func TestAccAWSCodeDeployDeploymentGroup_in_place_deployment_with_traffic_contro "aws_codedeploy_deployment_group.foo_group", "load_balancer_info.0.elb_info.2441772102.name", "foo-elb"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -1135,6 +1279,12 @@ func TestAccAWSCodeDeployDeploymentGroup_in_place_deployment_with_traffic_contro "aws_codedeploy_deployment_group.foo_group", "blue_green_deployment_config.0.terminate_blue_instances_on_deployment_success.0.action", "KEEP_ALIVE"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -1184,6 +1334,12 @@ func TestAccAWSCodeDeployDeploymentGroup_blueGreenDeploymentConfiguration_create "aws_codedeploy_deployment_group.foo_group", "blue_green_deployment_config.0.terminate_blue_instances_on_deployment_success.0.termination_wait_time_in_minutes", "120"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -1365,6 +1521,12 @@ func TestAccAWSCodeDeployDeploymentGroup_blueGreenDeploymentConfiguration_delete "aws_codedeploy_deployment_group.foo_group", "blue_green_deployment_config.#", "1"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -1461,6 +1623,12 @@ func TestAccAWSCodeDeployDeploymentGroup_blueGreenDeployment_complete(t *testing "aws_codedeploy_deployment_group.foo_group", "blue_green_deployment_config.0.terminate_blue_instances_on_deployment_success.0.termination_wait_time_in_minutes", "0"), ), }, + { + ResourceName: "aws_codedeploy_deployment_group.foo_group", + ImportState: true, + ImportStateIdFunc: testAccAWSCodeDeployDeploymentGroupImportStateIdFunc("aws_codedeploy_deployment_group.foo_group"), + ImportStateVerify: true, + }, }, }) } @@ -2093,6 +2261,17 @@ func TestAWSCodeDeployDeploymentGroup_handleCodeDeployApiError(t *testing.T) { } } +func testAccAWSCodeDeployDeploymentGroupImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Not found: %s", resourceName) + } + + return fmt.Sprintf("%s:%s", rs.Primary.Attributes["app_name"], rs.Primary.Attributes["deployment_group_name"]), nil + } +} + func testAccAWSCodeDeployDeploymentGroup(rName string, tagGroup bool) string { var tagGroupOrFilter string if tagGroup { diff --git a/website/docs/r/codedeploy_app.html.markdown b/website/docs/r/codedeploy_app.html.markdown index 59f454b0440..1d17de0e15c 100644 --- a/website/docs/r/codedeploy_app.html.markdown +++ b/website/docs/r/codedeploy_app.html.markdown @@ -31,3 +31,11 @@ The following arguments are exported: * `id` - Amazon's assigned ID for the application. * `name` - The application's name. + +## Import + +CodeDeploy Applications can be imported using the `name`, e.g. + +``` +$ terraform import aws_codedeploy_app.example my-application +``` diff --git a/website/docs/r/codedeploy_deployment_config.html.markdown b/website/docs/r/codedeploy_deployment_config.html.markdown index 53818217fe4..0294e46b231 100644 --- a/website/docs/r/codedeploy_deployment_config.html.markdown +++ b/website/docs/r/codedeploy_deployment_config.html.markdown @@ -73,3 +73,11 @@ In addition to all arguments above, the following attributes are exported: * `id` - The deployment group's config name. * `deployment_config_id` - The AWS Assigned deployment config id + +## Import + +CodeDeploy Deployment Configurations can be imported using the `deployment_config_name`, e.g. + +``` +$ terraform import aws_codedeploy_app.example my-deployment-config +``` diff --git a/website/docs/r/codedeploy_deployment_group.html.markdown b/website/docs/r/codedeploy_deployment_group.html.markdown index f1d6fd5bb68..5589fcae253 100644 --- a/website/docs/r/codedeploy_deployment_group.html.markdown +++ b/website/docs/r/codedeploy_deployment_group.html.markdown @@ -257,4 +257,12 @@ In addition to all arguments above, the following attributes are exported: * `autoscaling_groups` - The autoscaling groups associated with the deployment group. * `deployment_config_name` - The name of the group's deployment config. +## Import + +CodeDeploy Deployment Groups can be imported by their `app_name`, a colon, and `deployment_group_name`, e.g. + +``` +$ terraform import aws_codedeploy_deployment_group.example my-application:my-deployment-group +``` + [1]: http://docs.aws.amazon.com/codedeploy/latest/userguide/monitoring-sns-event-notifications-create-trigger.html