diff --git a/aws/resource_aws_dms_endpoint.go b/aws/resource_aws_dms_endpoint.go index 65ee9a4c928..bb96a8c9bf0 100644 --- a/aws/resource_aws_dms_endpoint.go +++ b/aws/resource_aws_dms_endpoint.go @@ -73,6 +73,7 @@ func resourceAwsDmsEndpoint() *schema.Resource { "sybase", "sqlserver", "mongodb", + "s3", }, false), }, "extra_connection_attributes": { @@ -165,6 +166,56 @@ func resourceAwsDmsEndpoint() *schema.Resource { }, }, }, + "s3_settings": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == "1" && new == "0" { + return true + } + return false + }, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "service_access_role_arn": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + "external_table_definition": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + "csv_row_delimiter": { + Type: schema.TypeString, + Optional: true, + Default: "\\n", + }, + "csv_delimiter": { + Type: schema.TypeString, + Optional: true, + Default: ",", + }, + "bucket_folder": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + "bucket_name": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + "compression_type": { + Type: schema.TypeString, + Optional: true, + Default: "NONE", + }, + }, + }, + }, }, } } @@ -200,6 +251,16 @@ func resourceAwsDmsEndpointCreate(d *schema.ResourceData, meta interface{}) erro DocsToInvestigate: aws.String(d.Get("mongodb_settings.0.docs_to_investigate").(string)), AuthSource: aws.String(d.Get("mongodb_settings.0.auth_source").(string)), } + case "s3": + request.S3Settings = &dms.S3Settings{ + ServiceAccessRoleArn: aws.String(d.Get("s3_settings.0.service_access_role_arn").(string)), + ExternalTableDefinition: aws.String(d.Get("s3_settings.0.external_table_definition").(string)), + CsvRowDelimiter: aws.String(d.Get("s3_settings.0.csv_row_delimiter").(string)), + CsvDelimiter: aws.String(d.Get("s3_settings.0.csv_delimiter").(string)), + BucketFolder: aws.String(d.Get("s3_settings.0.bucket_folder").(string)), + BucketName: aws.String(d.Get("s3_settings.0.bucket_name").(string)), + CompressionType: aws.String(d.Get("s3_settings.0.compression_type").(string)), + } default: request.Password = aws.String(d.Get("password").(string)) request.Port = aws.Int64(int64(d.Get("port").(int))) @@ -212,14 +273,14 @@ func resourceAwsDmsEndpointCreate(d *schema.ResourceData, meta interface{}) erro if v, ok := d.GetOk("extra_connection_attributes"); ok { request.ExtraConnectionAttributes = aws.String(v.(string)) } + if v, ok := d.GetOk("kms_key_arn"); ok { + request.KmsKeyId = aws.String(v.(string)) + } } if v, ok := d.GetOk("certificate_arn"); ok { request.CertificateArn = aws.String(v.(string)) } - if v, ok := d.GetOk("kms_key_arn"); ok { - request.KmsKeyId = aws.String(v.(string)) - } if v, ok := d.GetOk("ssl_mode"); ok { request.SslMode = aws.String(v.(string)) } @@ -290,6 +351,11 @@ func resourceAwsDmsEndpointUpdate(d *schema.ResourceData, meta interface{}) erro } hasChanges := false + if d.HasChange("endpoint_type") { + request.EndpointType = aws.String(d.Get("endpoint_type").(string)) + hasChanges = true + } + if d.HasChange("certificate_arn") { request.CertificateArn = aws.String(d.Get("certificate_arn").(string)) hasChanges = true @@ -330,6 +396,13 @@ func resourceAwsDmsEndpointUpdate(d *schema.ResourceData, meta interface{}) erro } switch d.Get("engine_name").(string) { + case "dynamodb": + if d.HasChange("service_access_role") { + request.DynamoDbSettings = &dms.DynamoDbSettings{ + ServiceAccessRoleArn: aws.String(d.Get("service_access_role").(string)), + } + hasChanges = true + } case "mongodb": if d.HasChange("username") || d.HasChange("password") || @@ -359,6 +432,26 @@ func resourceAwsDmsEndpointUpdate(d *schema.ResourceData, meta interface{}) erro request.EngineName = aws.String(d.Get("engine_name").(string)) // Must be included (should be 'mongodb') hasChanges = true } + case "s3": + if d.HasChange("s3_settings.0.service_access_role_arn") || + d.HasChange("s3_settings.0.external_table_definition") || + d.HasChange("s3_settings.0.csv_row_delimiter") || + d.HasChange("s3_settings.0.csv_delimiter") || + d.HasChange("s3_settings.0.bucket_folder") || + d.HasChange("s3_settings.0.bucket_name") || + d.HasChange("s3_settings.0.compression_type") { + request.S3Settings = &dms.S3Settings{ + ServiceAccessRoleArn: aws.String(d.Get("s3_settings.0.service_access_role_arn").(string)), + ExternalTableDefinition: aws.String(d.Get("s3_settings.0.external_table_definition").(string)), + CsvRowDelimiter: aws.String(d.Get("s3_settings.0.csv_row_delimiter").(string)), + CsvDelimiter: aws.String(d.Get("s3_settings.0.csv_delimiter").(string)), + BucketFolder: aws.String(d.Get("s3_settings.0.bucket_folder").(string)), + BucketName: aws.String(d.Get("s3_settings.0.bucket_name").(string)), + CompressionType: aws.String(d.Get("s3_settings.0.compression_type").(string)), + } + request.EngineName = aws.String(d.Get("engine_name").(string)) // Must be included (should be 's3') + hasChanges = true + } default: if d.HasChange("database_name") { request.DatabaseName = aws.String(d.Get("database_name").(string)) @@ -436,25 +529,28 @@ func resourceAwsDmsEndpointSetState(d *schema.ResourceData, endpoint *dms.Endpoi d.Set("server_name", endpoint.MongoDbSettings.ServerName) d.Set("port", endpoint.MongoDbSettings.Port) d.Set("database_name", endpoint.MongoDbSettings.DatabaseName) - - if err := d.Set("mongodb_settings", flattenDmsMongoDbSettings(endpoint.MongoDbSettings)); err != nil { - return fmt.Errorf("Error setting mongodb_settings for DMS: %s", err) - } } else { d.Set("username", endpoint.Username) d.Set("server_name", endpoint.ServerName) d.Set("port", endpoint.Port) d.Set("database_name", endpoint.DatabaseName) } + if err := d.Set("mongodb_settings", flattenDmsMongoDbSettings(endpoint.MongoDbSettings)); err != nil { + return fmt.Errorf("Error setting mongodb_settings for DMS: %s", err) + } + case "s3": + if err := d.Set("s3_settings", flattenDmsS3Settings(endpoint.S3Settings)); err != nil { + return fmt.Errorf("Error setting s3_settings for DMS: %s", err) + } default: d.Set("database_name", endpoint.DatabaseName) d.Set("extra_connection_attributes", endpoint.ExtraConnectionAttributes) d.Set("port", endpoint.Port) d.Set("server_name", endpoint.ServerName) d.Set("username", endpoint.Username) + d.Set("kms_key_arn", endpoint.KmsKeyId) } - d.Set("kms_key_arn", endpoint.KmsKeyId) d.Set("ssl_mode", endpoint.SslMode) return nil @@ -476,3 +572,21 @@ func flattenDmsMongoDbSettings(settings *dms.MongoDbSettings) []map[string]inter return []map[string]interface{}{m} } + +func flattenDmsS3Settings(settings *dms.S3Settings) []map[string]interface{} { + if settings == nil { + return []map[string]interface{}{} + } + + m := map[string]interface{}{ + "service_access_role_arn": aws.StringValue(settings.ServiceAccessRoleArn), + "external_table_definition": aws.StringValue(settings.ExternalTableDefinition), + "csv_row_delimiter": aws.StringValue(settings.CsvRowDelimiter), + "csv_delimiter": aws.StringValue(settings.CsvDelimiter), + "bucket_folder": aws.StringValue(settings.BucketFolder), + "bucket_name": aws.StringValue(settings.BucketName), + "compression_type": aws.StringValue(settings.CompressionType), + } + + return []map[string]interface{}{m} +} diff --git a/aws/resource_aws_dms_endpoint_test.go b/aws/resource_aws_dms_endpoint_test.go index 58fef7d8862..d832843b314 100644 --- a/aws/resource_aws_dms_endpoint_test.go +++ b/aws/resource_aws_dms_endpoint_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestAccAWSDmsEndpointBasic(t *testing.T) { +func TestAccAwsDmsEndpointBasic(t *testing.T) { resourceName := "aws_dms_endpoint.dms_endpoint" randId := acctest.RandString(8) + "-basic" @@ -50,7 +50,47 @@ func TestAccAWSDmsEndpointBasic(t *testing.T) { }) } -func TestAccAWSDmsEndpointDynamoDb(t *testing.T) { +func TestAccAwsDmsEndpointS3(t *testing.T) { + resourceName := "aws_dms_endpoint.dms_endpoint" + randId := acctest.RandString(8) + "-s3" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: dmsEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: dmsEndpointS3Config(randId), + Check: resource.ComposeTestCheckFunc( + checkDmsEndpointExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"password"}, + }, + { + Config: dmsEndpointS3ConfigUpdate(randId), + Check: resource.ComposeTestCheckFunc( + checkDmsEndpointExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "extra_connection_attributes", "key=value;"), + resource.TestCheckResourceAttr(resourceName, "s3_settings.#", "1"), + resource.TestCheckResourceAttr(resourceName, "s3_settings.0.external_table_definition", "new-external_table_definition"), + resource.TestCheckResourceAttr(resourceName, "s3_settings.0.csv_row_delimiter", "\\r"), + resource.TestCheckResourceAttr(resourceName, "s3_settings.0.csv_delimiter", "."), + resource.TestCheckResourceAttr(resourceName, "s3_settings.0.bucket_folder", "new-bucket_folder"), + resource.TestCheckResourceAttr(resourceName, "s3_settings.0.bucket_name", "new-bucket_name"), + resource.TestCheckResourceAttr(resourceName, "s3_settings.0.compression_type", "GZIP"), + ), + }, + }, + }) +} + +func TestAccAwsDmsEndpointDynamoDb(t *testing.T) { resourceName := "aws_dms_endpoint.dms_endpoint" randId := acctest.RandString(8) + "-dynamodb" @@ -82,7 +122,7 @@ func TestAccAWSDmsEndpointDynamoDb(t *testing.T) { }) } -func TestAccAWSDmsEndpointMongoDb(t *testing.T) { +func TestAccAwsDmsEndpointMongoDb(t *testing.T) { resourceName := "aws_dms_endpoint.dms_endpoint" randId := acctest.RandString(8) + "-mongodb" @@ -101,6 +141,7 @@ func TestAccAWSDmsEndpointMongoDb(t *testing.T) { { ResourceName: resourceName, ImportState: true, + ImportStateVerify: true, ImportStateVerifyIgnore: []string{"password"}, }, { @@ -233,50 +274,50 @@ resource "aws_dms_endpoint" "dms_endpoint" { depends_on = ["aws_iam_role_policy.dms_dynamodb_access"] } + resource "aws_iam_role" "iam_role" { - name = "tf-test-iam-dynamodb-role-%[1]s" + name = "tf-test-iam-dynamodb-role-%[1]s" - assume_role_policy = <