From 1862dc04cbc776b7dd339ee7e4f204895ed8438a Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 13 Mar 2020 15:05:20 +0200 Subject: [PATCH] add import support add plan time validation to `app_source.type`, `data_source_type`, `data_source_arn` --- aws/resource_aws_opsworks_application.go | 38 ++-- aws/resource_aws_opsworks_application_test.go | 164 ++++++------------ .../docs/r/opsworks_application.html.markdown | 8 + 3 files changed, 85 insertions(+), 125 deletions(-) diff --git a/aws/resource_aws_opsworks_application.go b/aws/resource_aws_opsworks_application.go index 1e5ba805801..98e67a89107 100644 --- a/aws/resource_aws_opsworks_application.go +++ b/aws/resource_aws_opsworks_application.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/opsworks" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" @@ -19,6 +18,10 @@ func resourceAwsOpsworksApplication() *schema.Resource { Read: resourceAwsOpsworksApplicationRead, Update: resourceAwsOpsworksApplicationUpdate, Delete: resourceAwsOpsworksApplicationDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -76,6 +79,13 @@ func resourceAwsOpsworksApplication() *schema.Resource { "type": { Type: schema.TypeString, Required: true, + ValidateFunc: validation.StringInSlice([]string{ + opsworks.SourceTypeGit, + opsworks.SourceTypeSvn, + opsworks.SourceTypeArchive, + opsworks.SourceTypeS3, + "other", + }, false), }, "url": { @@ -106,20 +116,24 @@ func resourceAwsOpsworksApplication() *schema.Resource { }, }, }, - // AutoSelectOpsworksMysqlInstance, OpsworksMysqlInstance, or RdsDbInstance. - // anything beside auto select will lead into failure in case the instance doesn't exist - // XXX: validation? "data_source_type": { Type: schema.TypeString, Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "AutoSelectOpsworksMysqlInstance", + "OpsworksMysqlInstance", + "RdsDbInstance", + "None", + }, false), }, "data_source_database_name": { Type: schema.TypeString, Optional: true, }, "data_source_arn": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateArn, }, "description": { Type: schema.TypeString, @@ -261,17 +275,16 @@ func resourceAwsOpsworksApplicationRead(d *schema.ResourceData, meta interface{} resp, err := client.DescribeApps(req) if err != nil { - if awserr, ok := err.(awserr.Error); ok { - if awserr.Code() == "ResourceNotFoundException" { - log.Printf("[INFO] App not found: %s", d.Id()) - d.SetId("") - return nil - } + if isAWSErr(err, opsworks.ErrCodeResourceNotFoundException, "") { + log.Printf("[INFO] App not found: %s", d.Id()) + d.SetId("") + return nil } return err } app := resp.Apps[0] + log.Printf("[DEBUG] Opsworks Application: %#v", app) d.Set("name", app.Name) d.Set("stack_id", app.StackId) @@ -284,6 +297,7 @@ func resourceAwsOpsworksApplicationRead(d *schema.ResourceData, meta interface{} resourceAwsOpsworksSetApplicationDataSources(d, app.DataSources) resourceAwsOpsworksSetApplicationEnvironmentVariable(d, app.Environment) resourceAwsOpsworksSetApplicationAttributes(d, app.Attributes) + return nil } diff --git a/aws/resource_aws_opsworks_application_test.go b/aws/resource_aws_opsworks_application_test.go index 24f682c407c..2fe0d6a3864 100644 --- a/aws/resource_aws_opsworks_application_test.go +++ b/aws/resource_aws_opsworks_application_test.go @@ -6,18 +6,17 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/opsworks" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) -func TestAccAWSOpsworksApplication(t *testing.T) { +func TestAccAWSOpsworksApplication_basic(t *testing.T) { var opsapp opsworks.App - rInt := acctest.RandInt() - name := fmt.Sprintf("tf-ops-acc-application-%d", rInt) + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_opsworks_application.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -25,115 +24,56 @@ func TestAccAWSOpsworksApplication(t *testing.T) { CheckDestroy: testAccCheckAwsOpsworksApplicationDestroy, Steps: []resource.TestStep{ { - Config: testAccAwsOpsworksApplicationCreate(name), + Config: testAccAwsOpsworksApplicationCreate(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSOpsworksApplicationExists( - "aws_opsworks_application.tf-acc-app", &opsapp), + testAccCheckAWSOpsworksApplicationExists(resourceName, &opsapp), testAccCheckAWSOpsworksCreateAppAttributes(&opsapp), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "name", name, - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "type", "other", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "enable_ssl", "false", - ), - resource.TestCheckNoResourceAttr( - "aws_opsworks_application.tf-acc-app", "ssl_configuration", - ), - resource.TestCheckNoResourceAttr( - "aws_opsworks_application.tf-acc-app", "domains", - ), - resource.TestCheckNoResourceAttr( - "aws_opsworks_application.tf-acc-app", "app_source", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "environment.3077298702.key", "key1", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "environment.3077298702.value", "value1", - ), - resource.TestCheckNoResourceAttr( - "aws_opsworks_application.tf-acc-app", "environment.3077298702.secret", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "document_root", "foo", - ), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "type", "other"), + resource.TestCheckResourceAttr(resourceName, "enable_ssl", "false"), + resource.TestCheckNoResourceAttr(resourceName, "ssl_configuration"), + resource.TestCheckNoResourceAttr(resourceName, "domains"), + resource.TestCheckNoResourceAttr(resourceName, "app_source"), + resource.TestCheckResourceAttr(resourceName, "environment.3077298702.key", "key1"), + resource.TestCheckResourceAttr(resourceName, "environment.3077298702.value", "value1"), + resource.TestCheckNoResourceAttr(resourceName, "environment.3077298702.secret"), + resource.TestCheckResourceAttr(resourceName, "document_root", "foo"), ), }, { - Config: testAccAwsOpsworksApplicationUpdate(name), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"environment.3077298702.key", "environment.#", + "environment.3077298702.secure", "environment.3077298702.value"}, + }, + { + Config: testAccAwsOpsworksApplicationUpdate(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSOpsworksApplicationExists( - "aws_opsworks_application.tf-acc-app", &opsapp), + testAccCheckAWSOpsworksApplicationExists(resourceName, &opsapp), testAccCheckAWSOpsworksUpdateAppAttributes(&opsapp), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "name", name, - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "type", "rails", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "enable_ssl", "true", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "ssl_configuration.0.certificate", "-----BEGIN CERTIFICATE-----\nMIIBkDCB+gIJALoScFD0sJq3MA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAYTAkRF\nMB4XDTE1MTIxOTIwMzU1MVoXDTE2MDExODIwMzU1MVowDTELMAkGA1UEBhMCREUw\ngZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKKQKbTTH/Julz16xY7ArYlzJYCP\nedTCx1bopuryCx/+d1gC94MtRdlPSpQl8mfc9iBdtXbJppp73Qh/DzLzO9Ns25xZ\n+kUQMhbIyLsaCBzuEGLgAaVdGpNvRBw++UoYtd0U7QczFAreTGLH8n8+FIzuI5Mc\n+MJ1TKbbt5gFfRSzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEALARo96wCDmaHKCaX\nS0IGLGnZCfiIUfCmBxOXBSJxDBwter95QHR0dMGxYIujee5n4vvavpVsqZnfMC3I\nOZWPlwiUJbNIpK+04Bg2vd5m/NMMrvi75RfmyeMtSfq/NrIX2Q3+nyWI7DLq7yZI\nV/YEvOqdAiy5NEWBztHx8HvB9G4=\n-----END CERTIFICATE-----", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "ssl_configuration.0.private_key", "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQCikCm00x/ybpc9esWOwK2JcyWAj3nUwsdW6Kbq8gsf/ndYAveD\nLUXZT0qUJfJn3PYgXbV2yaaae90Ifw8y8zvTbNucWfpFEDIWyMi7Gggc7hBi4AGl\nXRqTb0QcPvlKGLXdFO0HMxQK3kxix/J/PhSM7iOTHPjCdUym27eYBX0UswIDAQAB\nAoGBAIYcrvuqDboguI8U4TUjCkfSAgds1pLLWk79wu8jXkA329d1IyNKT0y3WIye\nPbyoEzmidZmZROQ/+ZsPz8c12Y0DrX73WSVzKNyJeP7XMk9HSzA1D9RX0U0S+5Kh\nFAMc2NEVVFIfQtVtoVmHdKDpnRYtOCHLW9rRpvqOOjd4mYk5AkEAzeiFr1mtlnsa\n67shMxzDaOTAFMchRz6G7aSovvCztxcB63ulFI/w9OTUMdTQ7ff7pet+lVihLc2W\nefIL0HvsjQJBAMocNTKaR/TnsV5GSk2kPAdR+zFP5sQy8sfMy0lEXTylc7zN4ajX\nMeHVoxp+GZgpfDcZ3ya808H1umyXh+xA1j8CQE9x9ZKQYT98RAjL7KVR5btk9w+N\nPTPF1j1+mHUDXfO4ds8qp6jlWKzEVXLcj7ghRADiebaZuaZ4eiSW1SQdjEkCQQC4\nwDhQ3X9RfEpCp3ZcqvjEqEg6t5N3XitYQPjDLN8eBRBbUsgpEy3iBuxl10eGNMX7\niIbYXlwkPYAArDPv3wT5AkAwp4vym+YKmDqh6gseKfRDuJqRiW9yD5A8VGr/w88k\n5rkuduVGP7tK3uIp00Its3aEyKF8mLGWYszVGeeLxAMH\n-----END RSA PRIVATE KEY-----", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "domains.0", "example.com", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "domains.1", "sub.example.com", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "app_source.0.password", "", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "app_source.0.revision", "master", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "app_source.0.ssh_key", "", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "app_source.0.type", "git", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "app_source.0.url", "https://github.com/aws/example.git", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "app_source.0.username", "", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "environment.2107898637.key", "key2", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "environment.2107898637.value", "value2", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "environment.2107898637.secure", "true", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "environment.3077298702.key", "key1", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "environment.3077298702.value", "value1", - ), - resource.TestCheckNoResourceAttr( - "aws_opsworks_application.tf-acc-app", "environment.3077298702.secret", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "document_root", "root", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "auto_bundle_on_deploy", "true", - ), - resource.TestCheckResourceAttr( - "aws_opsworks_application.tf-acc-app", "rails_env", "staging", - ), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "type", "rails"), + resource.TestCheckResourceAttr(resourceName, "enable_ssl", "true"), + resource.TestCheckResourceAttr(resourceName, "ssl_configuration.0.certificate", "-----BEGIN CERTIFICATE-----\nMIIBkDCB+gIJALoScFD0sJq3MA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAYTAkRF\nMB4XDTE1MTIxOTIwMzU1MVoXDTE2MDExODIwMzU1MVowDTELMAkGA1UEBhMCREUw\ngZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKKQKbTTH/Julz16xY7ArYlzJYCP\nedTCx1bopuryCx/+d1gC94MtRdlPSpQl8mfc9iBdtXbJppp73Qh/DzLzO9Ns25xZ\n+kUQMhbIyLsaCBzuEGLgAaVdGpNvRBw++UoYtd0U7QczFAreTGLH8n8+FIzuI5Mc\n+MJ1TKbbt5gFfRSzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEALARo96wCDmaHKCaX\nS0IGLGnZCfiIUfCmBxOXBSJxDBwter95QHR0dMGxYIujee5n4vvavpVsqZnfMC3I\nOZWPlwiUJbNIpK+04Bg2vd5m/NMMrvi75RfmyeMtSfq/NrIX2Q3+nyWI7DLq7yZI\nV/YEvOqdAiy5NEWBztHx8HvB9G4=\n-----END CERTIFICATE-----"), + resource.TestCheckResourceAttr(resourceName, "ssl_configuration.0.private_key", "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQCikCm00x/ybpc9esWOwK2JcyWAj3nUwsdW6Kbq8gsf/ndYAveD\nLUXZT0qUJfJn3PYgXbV2yaaae90Ifw8y8zvTbNucWfpFEDIWyMi7Gggc7hBi4AGl\nXRqTb0QcPvlKGLXdFO0HMxQK3kxix/J/PhSM7iOTHPjCdUym27eYBX0UswIDAQAB\nAoGBAIYcrvuqDboguI8U4TUjCkfSAgds1pLLWk79wu8jXkA329d1IyNKT0y3WIye\nPbyoEzmidZmZROQ/+ZsPz8c12Y0DrX73WSVzKNyJeP7XMk9HSzA1D9RX0U0S+5Kh\nFAMc2NEVVFIfQtVtoVmHdKDpnRYtOCHLW9rRpvqOOjd4mYk5AkEAzeiFr1mtlnsa\n67shMxzDaOTAFMchRz6G7aSovvCztxcB63ulFI/w9OTUMdTQ7ff7pet+lVihLc2W\nefIL0HvsjQJBAMocNTKaR/TnsV5GSk2kPAdR+zFP5sQy8sfMy0lEXTylc7zN4ajX\nMeHVoxp+GZgpfDcZ3ya808H1umyXh+xA1j8CQE9x9ZKQYT98RAjL7KVR5btk9w+N\nPTPF1j1+mHUDXfO4ds8qp6jlWKzEVXLcj7ghRADiebaZuaZ4eiSW1SQdjEkCQQC4\nwDhQ3X9RfEpCp3ZcqvjEqEg6t5N3XitYQPjDLN8eBRBbUsgpEy3iBuxl10eGNMX7\niIbYXlwkPYAArDPv3wT5AkAwp4vym+YKmDqh6gseKfRDuJqRiW9yD5A8VGr/w88k\n5rkuduVGP7tK3uIp00Its3aEyKF8mLGWYszVGeeLxAMH\n-----END RSA PRIVATE KEY-----"), + resource.TestCheckResourceAttr(resourceName, "domains.0", "example.com"), + resource.TestCheckResourceAttr(resourceName, "domains.1", "sub.example.com"), + resource.TestCheckResourceAttr(resourceName, "app_source.0.password", ""), + resource.TestCheckResourceAttr(resourceName, "app_source.0.revision", "master"), + resource.TestCheckResourceAttr(resourceName, "app_source.0.ssh_key", ""), + resource.TestCheckResourceAttr(resourceName, "app_source.0.type", "git"), + resource.TestCheckResourceAttr(resourceName, "app_source.0.url", "https://github.com/aws/example.git"), + resource.TestCheckResourceAttr(resourceName, "app_source.0.username", ""), + resource.TestCheckResourceAttr(resourceName, "environment.2107898637.key", "key2"), + resource.TestCheckResourceAttr(resourceName, "environment.2107898637.value", "value2"), + resource.TestCheckResourceAttr(resourceName, "environment.2107898637.secure", "true"), + resource.TestCheckResourceAttr(resourceName, "environment.3077298702.key", "key1"), + resource.TestCheckResourceAttr(resourceName, "environment.3077298702.value", "value1"), + resource.TestCheckNoResourceAttr(resourceName, "environment.3077298702.secret"), + resource.TestCheckResourceAttr(resourceName, "document_root", "root"), + resource.TestCheckResourceAttr(resourceName, "auto_bundle_on_deploy", "true"), + resource.TestCheckResourceAttr(resourceName, "rails_env", "staging"), ), }, }, @@ -184,7 +124,7 @@ func testAccCheckAWSOpsworksCreateAppAttributes( return fmt.Errorf("Unnexpected document root: %s", *opsapp.Attributes["DocumentRoot"]) } - if *opsapp.Type != "other" { + if *opsapp.Type != opsworks.AppTypeOther { return fmt.Errorf("Unnexpected type: %s", *opsapp.Type) } @@ -303,10 +243,8 @@ func testAccCheckAwsOpsworksApplicationDestroy(s *terraform.State) error { } } - if awserr, ok := err.(awserr.Error); ok { - if awserr.Code() != "ResourceNotFoundException" { - return err - } + if !isAWSErr(err, opsworks.ErrCodeResourceNotFoundException, "") { + return err } } @@ -316,7 +254,7 @@ func testAccCheckAwsOpsworksApplicationDestroy(s *terraform.State) error { func testAccAwsOpsworksApplicationCreate(name string) string { return testAccAwsOpsworksStackConfigVpcCreate(name) + fmt.Sprintf(` -resource "aws_opsworks_application" "tf-acc-app" { +resource "aws_opsworks_application" "test" { document_root = "foo" enable_ssl = false name = %q @@ -339,7 +277,7 @@ resource "aws_opsworks_application" "tf-acc-app" { func testAccAwsOpsworksApplicationUpdate(name string) string { return testAccAwsOpsworksStackConfigVpcCreate(name) + fmt.Sprintf(` -resource "aws_opsworks_application" "tf-acc-app" { +resource "aws_opsworks_application" "test" { auto_bundle_on_deploy = "true" document_root = "root" domains = ["example.com", "sub.example.com"] diff --git a/website/docs/r/opsworks_application.html.markdown b/website/docs/r/opsworks_application.html.markdown index 6b08f978b71..a2b4feb1241 100644 --- a/website/docs/r/opsworks_application.html.markdown +++ b/website/docs/r/opsworks_application.html.markdown @@ -98,3 +98,11 @@ A `ssl_configuration` block supports the following arguments (can only be define In addition to all arguments above, the following attributes are exported: * `id` - The id of the application. + +## Import + +Opsworks Application can be imported using the `id`, e.g. + +``` +$ terraform import aws_opsworks_application.test +```