From d7cc6d9ed81d10574ff86fbd7a13a0d62b61bfc6 Mon Sep 17 00:00:00 2001 From: Keisuke Nishida Date: Fri, 7 Feb 2020 01:12:23 +0900 Subject: [PATCH] Add aws_amplify_backend_environment resource --- aws/provider.go | 1 + ...esource_aws_amplify_backend_environment.go | 145 ++++++++++++++++ ...ce_aws_amplify_backend_environment_test.go | 156 ++++++++++++++++++ .../amplify_backend_environment.html.markdown | 50 ++++++ 4 files changed, 352 insertions(+) create mode 100644 aws/resource_aws_amplify_backend_environment.go create mode 100644 aws/resource_aws_amplify_backend_environment_test.go create mode 100644 website/docs/r/amplify_backend_environment.html.markdown diff --git a/aws/provider.go b/aws/provider.go index a66754c0123..847612d67a5 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -451,6 +451,7 @@ func Provider() *schema.Provider { "aws_ami_from_instance": resourceAwsAmiFromInstance(), "aws_ami_launch_permission": resourceAwsAmiLaunchPermission(), "aws_amplify_app": resourceAwsAmplifyApp(), + "aws_amplify_backend_environment": resourceAwsAmplifyBackendEnvironment(), "aws_api_gateway_account": resourceAwsApiGatewayAccount(), "aws_api_gateway_api_key": resourceAwsApiGatewayApiKey(), "aws_api_gateway_authorizer": resourceAwsApiGatewayAuthorizer(), diff --git a/aws/resource_aws_amplify_backend_environment.go b/aws/resource_aws_amplify_backend_environment.go new file mode 100644 index 00000000000..c4cca6f4a33 --- /dev/null +++ b/aws/resource_aws_amplify_backend_environment.go @@ -0,0 +1,145 @@ +package aws + +import ( + "fmt" + "log" + "regexp" + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/amplify" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" +) + +func resourceAwsAmplifyBackendEnvironment() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsAmplifyBackendEnvironmentCreate, + Read: resourceAwsAmplifyBackendEnvironmentRead, + Delete: resourceAwsAmplifyBackendEnvironmentDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "app_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "deployment_artifacts": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 100), + validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9-]+$`), "should not contain special characters"), + ), + }, + "environment_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.All( + validation.StringLenBetween(2, 10), + validation.StringMatch(regexp.MustCompile(`^[a-z]+$`), "should only contain lowercase alphabets"), + ), + }, + "stack_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 100), + validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9-]+$`), "should not contain special characters"), + ), + }, + }, + } +} + +func resourceAwsAmplifyBackendEnvironmentCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).amplifyconn + log.Print("[DEBUG] Creating Amplify BackendEnvironment") + + params := &lify.CreateBackendEnvironmentInput{ + AppId: aws.String(d.Get("app_id").(string)), + EnvironmentName: aws.String(d.Get("environment_name").(string)), + } + + if v, ok := d.GetOk("deployment_artifacts"); ok { + params.DeploymentArtifacts = aws.String(v.(string)) + } + + if v, ok := d.GetOk("stack_name"); ok { + params.StackName = aws.String(v.(string)) + } + + resp, err := conn.CreateBackendEnvironment(params) + if err != nil { + return fmt.Errorf("Error creating Amplify BackendEnvironment: %s", err) + } + + arn := *resp.BackendEnvironment.BackendEnvironmentArn + d.SetId(arn[strings.Index(arn, ":apps/")+len(":apps/"):]) + + return resourceAwsAmplifyBackendEnvironmentRead(d, meta) +} + +func resourceAwsAmplifyBackendEnvironmentRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).amplifyconn + log.Printf("[DEBUG] Reading Amplify BackendEnvironment: %s", d.Id()) + + s := strings.Split(d.Id(), "/") + app_id := s[0] + environment_name := s[2] + + resp, err := conn.GetBackendEnvironment(&lify.GetBackendEnvironmentInput{ + AppId: aws.String(app_id), + EnvironmentName: aws.String(environment_name), + }) + if err != nil { + if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == amplify.ErrCodeNotFoundException { + log.Printf("[WARN] Amplify BackendEnvironment (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + return err + } + + d.Set("app_id", app_id) + d.Set("arn", resp.BackendEnvironment.BackendEnvironmentArn) + d.Set("deployment_artifacts", resp.BackendEnvironment.DeploymentArtifacts) + d.Set("environment_name", resp.BackendEnvironment.EnvironmentName) + d.Set("stack_name", resp.BackendEnvironment.StackName) + + return nil +} + +func resourceAwsAmplifyBackendEnvironmentDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).amplifyconn + log.Printf("[DEBUG] Deleting Amplify BackendEnvironment: %s", d.Id()) + + s := strings.Split(d.Id(), "/") + app_id := s[0] + environment_name := s[2] + + params := &lify.DeleteBackendEnvironmentInput{ + AppId: aws.String(app_id), + EnvironmentName: aws.String(environment_name), + } + + _, err := conn.DeleteBackendEnvironment(params) + if err != nil { + return fmt.Errorf("Error deleting Amplify BackendEnvironment: %s", err) + } + + return nil +} diff --git a/aws/resource_aws_amplify_backend_environment_test.go b/aws/resource_aws_amplify_backend_environment_test.go new file mode 100644 index 00000000000..902eda55b15 --- /dev/null +++ b/aws/resource_aws_amplify_backend_environment_test.go @@ -0,0 +1,156 @@ +package aws + +import ( + "errors" + "fmt" + "regexp" + "strings" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/amplify" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccAWSAmplifyBackendEnvironment_basic(t *testing.T) { + var env1, env2 amplify.BackendEnvironment + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_amplify_backend_environment.test" + + envName := "backend" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAmplifyBackendEnvironmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSAmplifyBackendEnvironmentConfig_Required(rName, envName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSAmplifyBackendEnvironmentExists(resourceName, &env1), + resource.TestMatchResourceAttr(resourceName, "arn", regexp.MustCompile("^arn:[^:]+:amplify:[^:]+:[^:]+:apps/[^/]+/backendenvironments/"+envName)), + resource.TestCheckResourceAttr(resourceName, "environment_name", envName), + resource.TestMatchResourceAttr(resourceName, "deployment_artifacts", regexp.MustCompile(fmt.Sprintf("^tf-acc-test-.*-%s-.*-deployment$", envName))), + resource.TestMatchResourceAttr(resourceName, "stack_name", regexp.MustCompile(fmt.Sprintf("^amplify-tf-acc-test-.*-%s-.*$", envName))), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSAmplifyBackendEnvironmentConfigAll(rName, envName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSAmplifyBackendEnvironmentExists(resourceName, &env2), + testAccCheckAWSAmplifyBackendEnvironmentRecreated(&env1, &env2), + resource.TestMatchResourceAttr(resourceName, "arn", regexp.MustCompile("^arn:[^:]+:amplify:[^:]+:[^:]+:apps/[^/]+/backendenvironments/"+envName)), + resource.TestCheckResourceAttr(resourceName, "environment_name", envName), + resource.TestCheckResourceAttr(resourceName, "deployment_artifacts", rName), + resource.TestCheckResourceAttr(resourceName, "stack_name", rName), + ), + }, + }, + }) +} + +func testAccCheckAWSAmplifyBackendEnvironmentExists(resourceName string, v *amplify.BackendEnvironment) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + conn := testAccProvider.Meta().(*AWSClient).amplifyconn + + id := strings.Split(rs.Primary.ID, "/") + app_id := id[0] + environment_name := id[2] + + output, err := conn.GetBackendEnvironment(&lify.GetBackendEnvironmentInput{ + AppId: aws.String(app_id), + EnvironmentName: aws.String(environment_name), + }) + if err != nil { + return err + } + + if output == nil || output.BackendEnvironment == nil { + return fmt.Errorf("Amplify BackendEnvironment (%s) not found", rs.Primary.ID) + } + + *v = *output.BackendEnvironment + + return nil + } +} + +func testAccCheckAWSAmplifyBackendEnvironmentDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_amplify_backend_environment" { + continue + } + + conn := testAccProvider.Meta().(*AWSClient).amplifyconn + + id := strings.Split(rs.Primary.ID, "/") + app_id := id[0] + environment_name := id[2] + + _, err := conn.GetBackendEnvironment(&lify.GetBackendEnvironmentInput{ + AppId: aws.String(app_id), + EnvironmentName: aws.String(environment_name), + }) + + if isAWSErr(err, amplify.ErrCodeNotFoundException, "") { + continue + } + + if err != nil { + return err + } + } + + return nil +} + +func testAccCheckAWSAmplifyBackendEnvironmentRecreated(i, j *amplify.BackendEnvironment) resource.TestCheckFunc { + return func(s *terraform.State) error { + if aws.TimeValue(i.CreateTime) == aws.TimeValue(j.CreateTime) { + return errors.New("Amplify BackendEnvironment was not recreated") + } + + return nil + } +} + +func testAccAWSAmplifyBackendEnvironmentConfig_Required(rName string, envName string) string { + return fmt.Sprintf(` +resource "aws_amplify_app" "test" { + name = "%s" +} + +resource "aws_amplify_backend_environment" "test" { + app_id = aws_amplify_app.test.id + environment_name = "%s" +} +`, rName, envName) +} + +func testAccAWSAmplifyBackendEnvironmentConfigAll(rName string, envName string) string { + return fmt.Sprintf(` +resource "aws_amplify_app" "test" { + name = "%s" +} + +resource "aws_amplify_backend_environment" "test" { + app_id = aws_amplify_app.test.id + environment_name = "%s" + + deployment_artifacts = "%s" + stack_name = "%s" +} +`, rName, envName, rName, rName) +} diff --git a/website/docs/r/amplify_backend_environment.html.markdown b/website/docs/r/amplify_backend_environment.html.markdown new file mode 100644 index 00000000000..bf8a1782673 --- /dev/null +++ b/website/docs/r/amplify_backend_environment.html.markdown @@ -0,0 +1,50 @@ +--- +subcategory: "Amplify" +layout: "aws" +page_title: "AWS: aws_amplify_backend_environment" +description: |- + Provides an Amplify backend environment resource. +--- + +# Resource: aws_amplify_backend_environment + +Provides an Amplify backend environment resource. + +## Example Usage + +```hcl +resource "aws_amplify_app" "app" { + name = "app" +} + +resource "aws_amplify_backend_environment" "prod" { + app_id = aws_amplify_app.app.id + environment_name = "prod" + + deployment_artifacts = "app-prod-deployment" + stack_name = "amplify-app-prod" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `app_id` - (Required) Unique Id for an Amplify App. +* `environment_name` - (Required) Name for the backend environment. +* `deployment_artifacts` - (Optional) Name of deployment artifacts. +* `stack_name` - (Optional) CloudFormation stack name of backend environment. + +## Attribute Reference + +The following attributes are exported: + +* `arn` - Arn for the backend environment. + +## Import + +Amplify backend environment can be imported using `app_id` and `environment_name`, e.g. + +``` +$ terraform import aws_amplify_backend_environment.prod d2ypk4k47z8u6/backendenvironments/prod +```