diff --git a/builtin/providers/aws/resource_aws_opsworks_application_test.go b/builtin/providers/aws/resource_aws_opsworks_application_test.go index df2ec07d0..78e48cacb 100644 --- a/builtin/providers/aws/resource_aws_opsworks_application_test.go +++ b/builtin/providers/aws/resource_aws_opsworks_application_test.go @@ -2,6 +2,7 @@ package aws import ( "fmt" + "reflect" "testing" "github.com/aws/aws-sdk-go/aws" @@ -12,6 +13,7 @@ import ( ) func TestAccAWSOpsworksApplication(t *testing.T) { + var opsapp opsworks.App resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -20,6 +22,9 @@ func TestAccAWSOpsworksApplication(t *testing.T) { resource.TestStep{ Config: testAccAwsOpsworksApplicationCreate, Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksApplicationExists( + "aws_opsworks_application.tf-acc-app", &opsapp), + testAccCheckAWSOpsworksCreateAppAttributes(&opsapp), resource.TestCheckResourceAttr( "aws_opsworks_application.tf-acc-app", "name", "tf-ops-acc-application", ), @@ -55,6 +60,9 @@ func TestAccAWSOpsworksApplication(t *testing.T) { resource.TestStep{ Config: testAccAwsOpsworksApplicationUpdate, Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksApplicationExists( + "aws_opsworks_application.tf-acc-app", &opsapp), + testAccCheckAWSOpsworksUpdateAppAttributes(&opsapp), resource.TestCheckResourceAttr( "aws_opsworks_application.tf-acc-app", "name", "tf-ops-acc-application", ), @@ -127,6 +135,148 @@ func TestAccAWSOpsworksApplication(t *testing.T) { }) } +func testAccCheckAWSOpsworksApplicationExists( + n string, opsapp *opsworks.App) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).opsworksconn + + params := &opsworks.DescribeAppsInput{ + AppIds: []*string{&rs.Primary.ID}, + } + resp, err := conn.DescribeApps(params) + + if err != nil { + return err + } + + if v := len(resp.Apps); v != 1 { + return fmt.Errorf("Expected 1 response returned, got %d", v) + } + + *opsapp = *resp.Apps[0] + + return nil + } +} + +func testAccCheckAWSOpsworksCreateAppAttributes( + opsapp *opsworks.App) resource.TestCheckFunc { + return func(s *terraform.State) error { + if *opsapp.EnableSsl { + return fmt.Errorf("Unexpected enable ssl: %s", *opsapp.EnableSsl) + } + + if *opsapp.Attributes["DocumentRoot"] != "foo" { + return fmt.Errorf("Unnexpected document root: %s", *opsapp.Attributes["DocumentRoot"]) + } + + if *opsapp.Type != "other" { + return fmt.Errorf("Unnexpected type: %s", *opsapp.Type) + } + + if *opsapp.AppSource.Type != "other" { + return fmt.Errorf("Unnexpected appsource type: %s", *opsapp.AppSource.Type) + } + + expectedEnv := []*opsworks.EnvironmentVariable{ + &opsworks.EnvironmentVariable{ + Key: aws.String("key1"), + Value: aws.String("value1"), + Secure: aws.Bool(false), + }, + } + + if !reflect.DeepEqual(expectedEnv, opsapp.Environment) { + return fmt.Errorf("Unnexpected environment: %s", opsapp.Environment) + } + + if v := len(opsapp.Domains); v != 0 { + return fmt.Errorf("Expected 0 domains returned, got %d", v) + } + + return nil + } +} + +func testAccCheckAWSOpsworksUpdateAppAttributes( + opsapp *opsworks.App) resource.TestCheckFunc { + return func(s *terraform.State) error { + if *opsapp.Type != "rails" { + return fmt.Errorf("Unnexpected type: %s", *opsapp.Type) + } + + if !*opsapp.EnableSsl { + return fmt.Errorf("Unexpected enable ssl: %s", *opsapp.EnableSsl) + } + + if *opsapp.SslConfiguration.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-----" { + return fmt.Errorf("Unexpected ssl configuration certificate: %s", *opsapp.SslConfiguration.Certificate) + } + + if *opsapp.SslConfiguration.PrivateKey != "-----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-----" { + return fmt.Errorf("Unexpected ssl configuration private key: %s", *opsapp.SslConfiguration.PrivateKey) + } + + expectedAttrs := map[string]*string{ + "DocumentRoot": aws.String("root"), + "RailsEnv": aws.String("staging"), + "AutoBundleOnDeploy": aws.String("true"), + "AwsFlowRubySettings": nil, + } + + if !reflect.DeepEqual(expectedAttrs, opsapp.Attributes) { + return fmt.Errorf("Unnexpected Attributes: %s", opsapp.Attributes) + } + + expectedAppSource := &opsworks.Source{ + Type: aws.String("git"), + Revision: aws.String("master"), + Url: aws.String("https://github.com/aws/example.git"), + } + + if !reflect.DeepEqual(expectedAppSource, opsapp.AppSource) { + return fmt.Errorf("Unnexpected appsource: %s", opsapp.AppSource) + } + + expectedEnv := []*opsworks.EnvironmentVariable{ + &opsworks.EnvironmentVariable{ + Key: aws.String("key2"), + Value: aws.String("*****FILTERED*****"), + Secure: aws.Bool(true), + }, + &opsworks.EnvironmentVariable{ + Key: aws.String("key1"), + Value: aws.String("value1"), + Secure: aws.Bool(false), + }, + } + + if !reflect.DeepEqual(expectedEnv, opsapp.Environment) { + return fmt.Errorf("Unnexpected environment: %s", opsapp.Environment) + } + + expectedDomains := []*string{ + aws.String("example.com"), + aws.String("sub.example.com"), + } + + if !reflect.DeepEqual(expectedDomains, opsapp.Domains) { + return fmt.Errorf("Unnexpected Daomins : %s", opsapp.Domains) + } + + return nil + } +} + func testAccCheckAwsOpsworksApplicationDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*AWSClient).opsworksconn diff --git a/builtin/providers/aws/resource_aws_opsworks_custom_layer_test.go b/builtin/providers/aws/resource_aws_opsworks_custom_layer_test.go index 67c6d8a7a..1969e66c4 100644 --- a/builtin/providers/aws/resource_aws_opsworks_custom_layer_test.go +++ b/builtin/providers/aws/resource_aws_opsworks_custom_layer_test.go @@ -2,6 +2,7 @@ package aws import ( "fmt" + "reflect" "testing" "github.com/aws/aws-sdk-go/aws" @@ -17,6 +18,7 @@ import ( func TestAccAWSOpsworksCustomLayer(t *testing.T) { stackName := fmt.Sprintf("tf-%d", acctest.RandInt()) + var opslayer opsworks.Layer resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -25,6 +27,9 @@ func TestAccAWSOpsworksCustomLayer(t *testing.T) { resource.TestStep{ Config: testAccAwsOpsworksCustomLayerConfigNoVpcCreate(stackName), Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksCustomLayerExists( + "aws_opsworks_custom_layer.tf-acc", &opslayer), + testAccCheckAWSOpsworksCreateLayerAttributes(&opslayer, stackName), resource.TestCheckResourceAttr( "aws_opsworks_custom_layer.tf-acc", "name", stackName, ), @@ -138,6 +143,99 @@ func TestAccAWSOpsworksCustomLayer(t *testing.T) { }) } +func testAccCheckAWSOpsworksCustomLayerExists( + n string, opslayer *opsworks.Layer) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).opsworksconn + + params := &opsworks.DescribeLayersInput{ + LayerIds: []*string{aws.String(rs.Primary.ID)}, + } + resp, err := conn.DescribeLayers(params) + + if err != nil { + return err + } + + if v := len(resp.Layers); v != 1 { + return fmt.Errorf("Expected 1 response returned, got %d", v) + } + + *opslayer = *resp.Layers[0] + + return nil + } +} + +func testAccCheckAWSOpsworksCreateLayerAttributes( + opslayer *opsworks.Layer, stackName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + if *opslayer.Name != stackName { + return fmt.Errorf("Unexpected name: %s", *opslayer.Name) + } + + if *opslayer.AutoAssignElasticIps { + return fmt.Errorf( + "Unexpected AutoAssignElasticIps: %s", *opslayer.AutoAssignElasticIps) + } + + if !*opslayer.EnableAutoHealing { + return fmt.Errorf( + "Unexpected EnableAutoHealing: %s", *opslayer.EnableAutoHealing) + } + + if !*opslayer.LifecycleEventConfiguration.Shutdown.DelayUntilElbConnectionsDrained { + return fmt.Errorf( + "Unexpected DelayUntilElbConnectionsDrained: %s", + *opslayer.LifecycleEventConfiguration.Shutdown.DelayUntilElbConnectionsDrained) + } + + if *opslayer.LifecycleEventConfiguration.Shutdown.ExecutionTimeout != 300 { + return fmt.Errorf( + "Unexpected ExecutionTimeout: %s", + *opslayer.LifecycleEventConfiguration.Shutdown.ExecutionTimeout) + } + + if v := len(opslayer.CustomSecurityGroupIds); v != 2 { + return fmt.Errorf("Expected 2 customSecurityGroupIds, got %d", v) + } + + expectedPackages := []*string{ + aws.String("git"), + aws.String("golang"), + } + + if !reflect.DeepEqual(expectedPackages, opslayer.Packages) { + return fmt.Errorf("Unexpected Packages: %s", opslayer.Packages) + } + + expectedEbsVolumes := []*opsworks.VolumeConfiguration{ + &opsworks.VolumeConfiguration{ + VolumeType: aws.String("gp2"), + NumberOfDisks: aws.Int64(2), + MountPoint: aws.String("/home"), + Size: aws.Int64(100), + RaidLevel: aws.Int64(0), + }, + } + + if !reflect.DeepEqual(expectedEbsVolumes, opslayer.VolumeConfigurations) { + return fmt.Errorf("Unnexpected VolumeConfiguration: %s", opslayer.VolumeConfigurations) + } + + return nil + } +} + func testAccCheckAwsOpsworksCustomLayerDestroy(s *terraform.State) error { opsworksconn := testAccProvider.Meta().(*AWSClient).opsworksconn for _, rs := range s.RootModule().Resources { diff --git a/builtin/providers/aws/resource_aws_opsworks_permission_test.go b/builtin/providers/aws/resource_aws_opsworks_permission_test.go index 0f70284ec..e0969cb3f 100644 --- a/builtin/providers/aws/resource_aws_opsworks_permission_test.go +++ b/builtin/providers/aws/resource_aws_opsworks_permission_test.go @@ -4,19 +4,28 @@ import ( "fmt" "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/helper/acctest" "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" ) func TestAccAWSOpsworksPermission(t *testing.T) { sName := fmt.Sprintf("tf-ops-perm-%d", acctest.RandInt()) + var opsperm opsworks.Permission resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsOpsworksPermissionDestroy, Steps: []resource.TestStep{ resource.TestStep{ Config: testAccAwsOpsworksPermissionCreate(sName, "true", "true", "iam_only"), Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksPermissionExists( + "aws_opsworks_permission.tf-acc-perm", &opsperm), + testAccCheckAWSOpsworksCreatePermissionAttributes(&opsperm, true, true, "iam_only"), resource.TestCheckResourceAttr( "aws_opsworks_permission.tf-acc-perm", "allow_ssh", "true", ), @@ -31,6 +40,9 @@ func TestAccAWSOpsworksPermission(t *testing.T) { resource.TestStep{ Config: testAccAwsOpsworksPermissionCreate(sName, "true", "false", "iam_only"), Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksPermissionExists( + "aws_opsworks_permission.tf-acc-perm", &opsperm), + testAccCheckAWSOpsworksCreatePermissionAttributes(&opsperm, true, false, "iam_only"), resource.TestCheckResourceAttr( "aws_opsworks_permission.tf-acc-perm", "allow_ssh", "true", ), @@ -45,6 +57,9 @@ func TestAccAWSOpsworksPermission(t *testing.T) { resource.TestStep{ Config: testAccAwsOpsworksPermissionCreate(sName, "false", "false", "deny"), Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksPermissionExists( + "aws_opsworks_permission.tf-acc-perm", &opsperm), + testAccCheckAWSOpsworksCreatePermissionAttributes(&opsperm, false, false, "deny"), resource.TestCheckResourceAttr( "aws_opsworks_permission.tf-acc-perm", "allow_ssh", "false", ), @@ -59,6 +74,9 @@ func TestAccAWSOpsworksPermission(t *testing.T) { resource.TestStep{ Config: testAccAwsOpsworksPermissionCreate(sName, "false", "false", "show"), Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksPermissionExists( + "aws_opsworks_permission.tf-acc-perm", &opsperm), + testAccCheckAWSOpsworksCreatePermissionAttributes(&opsperm, false, false, "show"), resource.TestCheckResourceAttr( "aws_opsworks_permission.tf-acc-perm", "allow_ssh", "false", ), @@ -74,6 +92,87 @@ func TestAccAWSOpsworksPermission(t *testing.T) { }) } +func testAccCheckAWSOpsworksPermissionExists( + n string, opsperm *opsworks.Permission) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).opsworksconn + + params := &opsworks.DescribePermissionsInput{ + StackId: aws.String(rs.Primary.Attributes["stack_id"]), + IamUserArn: aws.String(rs.Primary.Attributes["user_arn"]), + } + resp, err := conn.DescribePermissions(params) + + if err != nil { + return err + } + + if v := len(resp.Permissions); v != 1 { + return fmt.Errorf("Expected 1 response returned, got %d", v) + } + + *opsperm = *resp.Permissions[0] + + return nil + } +} + +func testAccCheckAWSOpsworksCreatePermissionAttributes( + opsperm *opsworks.Permission, allowSsh bool, allowSudo bool, level string) resource.TestCheckFunc { + return func(s *terraform.State) error { + if *opsperm.AllowSsh != allowSsh { + return fmt.Errorf("Unnexpected allowSsh: %s", *opsperm.AllowSsh) + } + + if *opsperm.AllowSudo != allowSudo { + return fmt.Errorf("Unnexpected allowSudo: %s", *opsperm.AllowSudo) + } + + if *opsperm.Level != level { + return fmt.Errorf("Unnexpected level: %s", *opsperm.Level) + } + + return nil + } +} + +func testAccCheckAwsOpsworksPermissionDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*AWSClient).opsworksconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_opsworks_permission" { + continue + } + + req := &opsworks.DescribePermissionsInput{ + IamUserArn: aws.String(rs.Primary.Attributes["user_arn"]), + } + + resp, err := client.DescribePermissions(req) + if err == nil { + if len(resp.Permissions) > 0 { + return fmt.Errorf("OpsWorks Permissions still exist.") + } + } + + if awserr, ok := err.(awserr.Error); ok { + if awserr.Code() != "ResourceNotFoundException" { + return err + } + } + } + return nil +} + func testAccAwsOpsworksPermissionCreate(name, ssh, sudo, level string) string { return fmt.Sprintf(` resource "aws_opsworks_permission" "tf-acc-perm" { diff --git a/builtin/providers/aws/resource_aws_opsworks_rds_db_instance_test.go b/builtin/providers/aws/resource_aws_opsworks_rds_db_instance_test.go index 0a3df85a1..8845ce2c1 100644 --- a/builtin/providers/aws/resource_aws_opsworks_rds_db_instance_test.go +++ b/builtin/providers/aws/resource_aws_opsworks_rds_db_instance_test.go @@ -4,19 +4,28 @@ import ( "fmt" "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/helper/acctest" "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" ) func TestAccAWSOpsworksRdsDbInstance(t *testing.T) { sName := fmt.Sprintf("test-db-instance-%d", acctest.RandInt()) + var opsdb opsworks.RdsDbInstance resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsOpsworksRdsDbDestroy, Steps: []resource.TestStep{ resource.TestStep{ Config: testAccAwsOpsworksRdsDbInstance(sName, "foo", "barbarbarbar"), Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksRdsDbExists( + "aws_opsworks_rds_db_instance.tf-acc-opsworks-db", &opsdb), + testAccCheckAWSOpsworksCreateRdsDbAttributes(&opsdb, "foo"), resource.TestCheckResourceAttr( "aws_opsworks_rds_db_instance.tf-acc-opsworks-db", "db_user", "foo", ), @@ -25,6 +34,9 @@ func TestAccAWSOpsworksRdsDbInstance(t *testing.T) { resource.TestStep{ Config: testAccAwsOpsworksRdsDbInstance(sName, "bar", "barbarbarbar"), Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksRdsDbExists( + "aws_opsworks_rds_db_instance.tf-acc-opsworks-db", &opsdb), + testAccCheckAWSOpsworksCreateRdsDbAttributes(&opsdb, "bar"), resource.TestCheckResourceAttr( "aws_opsworks_rds_db_instance.tf-acc-opsworks-db", "db_user", "bar", ), @@ -33,6 +45,9 @@ func TestAccAWSOpsworksRdsDbInstance(t *testing.T) { resource.TestStep{ Config: testAccAwsOpsworksRdsDbInstance(sName, "bar", "foofoofoofoofoo"), Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksRdsDbExists( + "aws_opsworks_rds_db_instance.tf-acc-opsworks-db", &opsdb), + testAccCheckAWSOpsworksCreateRdsDbAttributes(&opsdb, "bar"), resource.TestCheckResourceAttr( "aws_opsworks_rds_db_instance.tf-acc-opsworks-db", "db_user", "bar", ), @@ -41,6 +56,9 @@ func TestAccAWSOpsworksRdsDbInstance(t *testing.T) { resource.TestStep{ Config: testAccAwsOpsworksRdsDbInstanceForceNew(sName), Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksRdsDbExists( + "aws_opsworks_rds_db_instance.tf-acc-opsworks-db", &opsdb), + testAccCheckAWSOpsworksCreateRdsDbAttributes(&opsdb, "foo"), resource.TestCheckResourceAttr( "aws_opsworks_rds_db_instance.tf-acc-opsworks-db", "db_user", "foo", ), @@ -50,6 +68,84 @@ func TestAccAWSOpsworksRdsDbInstance(t *testing.T) { }) } +func testAccCheckAWSOpsworksRdsDbExists( + n string, opsdb *opsworks.RdsDbInstance) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + if _, ok := rs.Primary.Attributes["stack_id"]; !ok { + return fmt.Errorf("Rds Db stack id is missing, should be set.") + } + + conn := testAccProvider.Meta().(*AWSClient).opsworksconn + + params := &opsworks.DescribeRdsDbInstancesInput{ + StackId: aws.String(rs.Primary.Attributes["stack_id"]), + } + resp, err := conn.DescribeRdsDbInstances(params) + + if err != nil { + return err + } + + if v := len(resp.RdsDbInstances); v != 1 { + return fmt.Errorf("Expected 1 response returned, got %d", v) + } + + *opsdb = *resp.RdsDbInstances[0] + + return nil + } +} + +func testAccCheckAWSOpsworksCreateRdsDbAttributes( + opsdb *opsworks.RdsDbInstance, user string) resource.TestCheckFunc { + return func(s *terraform.State) error { + if *opsdb.DbUser != user { + return fmt.Errorf("Unnexpected user: %s", *opsdb.DbUser) + } + if *opsdb.Engine != "mysql" { + return fmt.Errorf("Unnexpected engine: %s", *opsdb.Engine) + } + return nil + } +} + +func testAccCheckAwsOpsworksRdsDbDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*AWSClient).opsworksconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_opsworks_rds_db_instance" { + continue + } + + req := &opsworks.DescribeRdsDbInstancesInput{ + StackId: aws.String(rs.Primary.Attributes["stack_id"]), + } + + resp, err := client.DescribeRdsDbInstances(req) + if err == nil { + if len(resp.RdsDbInstances) > 0 { + return fmt.Errorf("OpsWorks Rds db instances still exist.") + } + } + + if awserr, ok := err.(awserr.Error); ok { + if awserr.Code() != "ResourceNotFoundException" { + return err + } + } + } + return nil +} + func testAccAwsOpsworksRdsDbInstance(name, userName, password string) string { return fmt.Sprintf(` resource "aws_opsworks_rds_db_instance" "tf-acc-opsworks-db" { diff --git a/builtin/providers/aws/resource_aws_opsworks_stack_test.go b/builtin/providers/aws/resource_aws_opsworks_stack_test.go index 1bb9bba14..e8de10407 100644 --- a/builtin/providers/aws/resource_aws_opsworks_stack_test.go +++ b/builtin/providers/aws/resource_aws_opsworks_stack_test.go @@ -19,6 +19,7 @@ import ( func TestAccAWSOpsworksStackNoVpc(t *testing.T) { stackName := fmt.Sprintf("tf-opsworks-acc-%d", acctest.RandInt()) + var opsstack opsworks.Stack resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -26,7 +27,14 @@ func TestAccAWSOpsworksStackNoVpc(t *testing.T) { Steps: []resource.TestStep{ resource.TestStep{ Config: testAccAwsOpsworksStackConfigNoVpcCreate(stackName), - Check: testAccAwsOpsworksStackCheckResourceAttrsCreate("us-east-1a", stackName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksStackExists( + "aws_opsworks_stack.tf-acc", false, &opsstack), + testAccCheckAWSOpsworksCreateStackAttributes( + &opsstack, "us-east-1a", stackName), + testAccAwsOpsworksStackCheckResourceAttrsCreate( + "us-east-1a", stackName), + ), }, // resource.TestStep{ // Config: testAccAWSOpsworksStackConfigNoVpcUpdate(stackName), @@ -38,6 +46,7 @@ func TestAccAWSOpsworksStackNoVpc(t *testing.T) { func TestAccAWSOpsworksStackVpc(t *testing.T) { stackName := fmt.Sprintf("tf-opsworks-acc-%d", acctest.RandInt()) + var opsstack opsworks.Stack resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -45,13 +54,24 @@ func TestAccAWSOpsworksStackVpc(t *testing.T) { Steps: []resource.TestStep{ resource.TestStep{ Config: testAccAwsOpsworksStackConfigVpcCreate(stackName), - Check: testAccAwsOpsworksStackCheckResourceAttrsCreate("us-west-2a", stackName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksStackExists( + "aws_opsworks_stack.tf-acc", true, &opsstack), + testAccCheckAWSOpsworksCreateStackAttributes( + &opsstack, "us-west-2a", stackName), + testAccAwsOpsworksStackCheckResourceAttrsCreate( + "us-west-2a", stackName), + ), }, resource.TestStep{ Config: testAccAWSOpsworksStackConfigVpcUpdate(stackName), Check: resource.ComposeTestCheckFunc( - testAccAwsOpsworksStackCheckResourceAttrsUpdate("us-west-2a", stackName), - testAccAwsOpsworksCheckVpc, + testAccCheckAWSOpsworksStackExists( + "aws_opsworks_stack.tf-acc", true, &opsstack), + testAccCheckAWSOpsworksUpdateStackAttributes( + &opsstack, "us-west-2a", stackName), + testAccAwsOpsworksStackCheckResourceAttrsUpdate( + "us-west-2a", stackName), ), }, }, @@ -167,35 +187,132 @@ func testAccAwsOpsworksStackCheckResourceAttrsUpdate(zone, stackName string) res ) } -func testAccAwsOpsworksCheckVpc(s *terraform.State) error { - rs, ok := s.RootModule().Resources["aws_opsworks_stack.tf-acc"] - if !ok { - return fmt.Errorf("Not found: %s", "aws_opsworks_stack.tf-acc") - } - if rs.Primary.ID == "" { - return fmt.Errorf("No ID is set") - } +func testAccCheckAWSOpsworksStackExists( + n string, vpc bool, opsstack *opsworks.Stack) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } - p := rs.Primary + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } - opsworksconn := testAccProvider.Meta().(*AWSClient).opsworksconn - describeOpts := &opsworks.DescribeStacksInput{ - StackIds: []*string{aws.String(p.ID)}, + conn := testAccProvider.Meta().(*AWSClient).opsworksconn + + params := &opsworks.DescribeStacksInput{ + StackIds: []*string{aws.String(rs.Primary.ID)}, + } + resp, err := conn.DescribeStacks(params) + + if err != nil { + return err + } + + if v := len(resp.Stacks); v != 1 { + return fmt.Errorf("Expected 1 response returned, got %d", v) + } + + *opsstack = *resp.Stacks[0] + + if vpc { + if rs.Primary.Attributes["vpc_id"] != *opsstack.VpcId { + return fmt.Errorf("VPCID Got %s, expected %s", *opsstack.VpcId, rs.Primary.Attributes["vpc_id"]) + } + if rs.Primary.Attributes["default_subnet_id"] != *opsstack.DefaultSubnetId { + return fmt.Errorf("Default subnet Id Got %s, expected %s", *opsstack.DefaultSubnetId, rs.Primary.Attributes["default_subnet_id"]) + } + } + + return nil } - resp, err := opsworksconn.DescribeStacks(describeOpts) - if err != nil { - return err +} + +func testAccCheckAWSOpsworksCreateStackAttributes( + opsstack *opsworks.Stack, zone, stackName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + if *opsstack.Name != stackName { + return fmt.Errorf("Unnexpected stackName: %s", *opsstack.Name) + } + + if *opsstack.DefaultAvailabilityZone != zone { + return fmt.Errorf("Unnexpected DefaultAvailabilityZone: %s", *opsstack.DefaultAvailabilityZone) + } + + if *opsstack.DefaultOs != "Amazon Linux 2014.09" { + return fmt.Errorf("Unnexpected stackName: %s", *opsstack.DefaultOs) + } + + if *opsstack.DefaultRootDeviceType != "ebs" { + return fmt.Errorf("Unnexpected DefaultRootDeviceType: %s", *opsstack.DefaultRootDeviceType) + } + + if *opsstack.CustomJson != `{"key": "value"}` { + return fmt.Errorf("Unnexpected CustomJson: %s", *opsstack.CustomJson) + } + + if *opsstack.ConfigurationManager.Version != "11.10" { + return fmt.Errorf("Unnexpected Version: %s", *opsstack.ConfigurationManager.Version) + } + + if *opsstack.UseOpsworksSecurityGroups { + return fmt.Errorf("Unnexpected UseOpsworksSecurityGroups: %s", *opsstack.UseOpsworksSecurityGroups) + } + + return nil } - if len(resp.Stacks) == 0 { - return fmt.Errorf("No stack %s not found", p.ID) +} + +func testAccCheckAWSOpsworksUpdateStackAttributes( + opsstack *opsworks.Stack, zone, stackName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + if *opsstack.Name != stackName { + return fmt.Errorf("Unnexpected stackName: %s", *opsstack.Name) + } + + if *opsstack.DefaultAvailabilityZone != zone { + return fmt.Errorf("Unnexpected DefaultAvailabilityZone: %s", *opsstack.DefaultAvailabilityZone) + } + + if *opsstack.DefaultOs != "Amazon Linux 2014.09" { + return fmt.Errorf("Unnexpected stackName: %s", *opsstack.DefaultOs) + } + + if *opsstack.DefaultRootDeviceType != "ebs" { + return fmt.Errorf("Unnexpected DefaultRootDeviceType: %s", *opsstack.DefaultRootDeviceType) + } + + if *opsstack.CustomJson != `{"key": "value"}` { + return fmt.Errorf("Unnexpected CustomJson: %s", *opsstack.CustomJson) + } + + if *opsstack.ConfigurationManager.Version != "11.10" { + return fmt.Errorf("Unnexpected Version: %s", *opsstack.ConfigurationManager.Version) + } + + if !*opsstack.UseCustomCookbooks { + return fmt.Errorf("Unnexpected UseCustomCookbooks: %s", *opsstack.UseCustomCookbooks) + } + + if !*opsstack.ChefConfiguration.ManageBerkshelf { + return fmt.Errorf("Unnexpected ManageBerkshelf: %s", *opsstack.ChefConfiguration.ManageBerkshelf) + } + + if *opsstack.CustomCookbooksSource.Type != "git" { + return fmt.Errorf("Unnexpected *opsstack.CustomCookbooksSource.Type: %s", *opsstack.CustomCookbooksSource.Type) + } + + if *opsstack.CustomCookbooksSource.Revision != "master" { + return fmt.Errorf("Unnexpected *opsstack.CustomCookbooksSource.Type: %s", *opsstack.CustomCookbooksSource.Revision) + } + + if *opsstack.CustomCookbooksSource.Url != "https://github.com/aws/opsworks-example-cookbooks.git" { + return fmt.Errorf("Unnexpected *opsstack.CustomCookbooksSource.Type: %s", *opsstack.CustomCookbooksSource.Url) + } + + return nil } - if p.Attributes["vpc_id"] != *resp.Stacks[0].VpcId { - return fmt.Errorf("VPCID Got %s, expected %s", *resp.Stacks[0].VpcId, p.Attributes["vpc_id"]) - } - if p.Attributes["default_subnet_id"] != *resp.Stacks[0].DefaultSubnetId { - return fmt.Errorf("VPCID Got %s, expected %s", *resp.Stacks[0].DefaultSubnetId, p.Attributes["default_subnet_id"]) - } - return nil } func testAccCheckAwsOpsworksStackDestroy(s *terraform.State) error { diff --git a/builtin/providers/aws/resource_aws_opsworks_user_profile_test.go b/builtin/providers/aws/resource_aws_opsworks_user_profile_test.go index fc971e6b3..41ed6190e 100644 --- a/builtin/providers/aws/resource_aws_opsworks_user_profile_test.go +++ b/builtin/providers/aws/resource_aws_opsworks_user_profile_test.go @@ -4,20 +4,27 @@ import ( "fmt" "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/helper/acctest" "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" ) func TestAccAWSOpsworksUserProfile(t *testing.T) { rName := fmt.Sprintf("test-user-%d", acctest.RandInt()) roleName := fmt.Sprintf("tf-ops-user-profile-%d", acctest.RandInt()) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsOpsworksUserProfileDestroy, Steps: []resource.TestStep{ resource.TestStep{ Config: testAccAwsOpsworksUserProfileCreate(rName, roleName), Check: resource.ComposeTestCheckFunc( + testAccCheckAWSOpsworksUserProfileExists( + "aws_opsworks_user_profile.user", rName), resource.TestCheckResourceAttr( "aws_opsworks_user_profile.user", "ssh_public_key", "", ), @@ -33,6 +40,80 @@ func TestAccAWSOpsworksUserProfile(t *testing.T) { }) } +func testAccCheckAWSOpsworksUserProfileExists( + n, username string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + if _, ok := rs.Primary.Attributes["user_arn"]; !ok { + return fmt.Errorf("User Profile user arn is missing, should be set.") + } + + conn := testAccProvider.Meta().(*AWSClient).opsworksconn + + params := &opsworks.DescribeUserProfilesInput{ + IamUserArns: []*string{aws.String(rs.Primary.Attributes["user_arn"])}, + } + resp, err := conn.DescribeUserProfiles(params) + + if err != nil { + return err + } + + if v := len(resp.UserProfiles); v != 1 { + return fmt.Errorf("Expected 1 response returned, got %d", v) + } + + opsuserprofile := *resp.UserProfiles[0] + + if *opsuserprofile.AllowSelfManagement { + return fmt.Errorf("Unnexpected allowSelfManagement: %s", + *opsuserprofile.AllowSelfManagement) + } + + if *opsuserprofile.Name != username { + return fmt.Errorf("Unnexpected name: %s", *opsuserprofile.Name) + } + + return nil + } +} + +func testAccCheckAwsOpsworksUserProfileDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*AWSClient).opsworksconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_opsworks_user_profile" { + continue + } + + req := &opsworks.DescribeUserProfilesInput{ + IamUserArns: []*string{aws.String(rs.Primary.Attributes["user_arn"])}, + } + resp, err := client.DescribeUserProfiles(req) + + if err == nil { + if len(resp.UserProfiles) > 0 { + return fmt.Errorf("OpsWorks User Profiles still exist.") + } + } + + if awserr, ok := err.(awserr.Error); ok { + if awserr.Code() != "ResourceNotFoundException" { + return err + } + } + } + return nil +} + func testAccAwsOpsworksUserProfileCreate(rn, roleName string) string { return fmt.Sprintf(` resource "aws_opsworks_user_profile" "user" {