Skip to content

Commit

Permalink
Added support for dynamodb as dms endpoint (with tests). For issue: (h…
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisjharding authored and stack72 committed Jun 29, 2017
1 parent b256203 commit 84e031a
Show file tree
Hide file tree
Showing 2 changed files with 211 additions and 23 deletions.
67 changes: 49 additions & 18 deletions aws/resource_aws_dms_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ func resourceAwsDmsEndpoint() *schema.Resource {
ForceNew: true,
ValidateFunc: validateDmsEndpointId,
},
"service_access_role": {
Type: schema.TypeString,
Optional: true,
},
"endpoint_type": {
Type: schema.TypeString,
Required: true,
Expand All @@ -58,6 +62,7 @@ func resourceAwsDmsEndpoint() *schema.Resource {
"mysql",
"oracle",
"postgres",
"dynamodb",
"mariadb",
"aurora",
"redshift",
Expand All @@ -79,16 +84,16 @@ func resourceAwsDmsEndpoint() *schema.Resource {
},
"password": {
Type: schema.TypeString,
Required: true,
Optional: true,
Sensitive: true,
},
"port": {
Type: schema.TypeInt,
Required: true,
Optional: true,
},
"server_name": {
Type: schema.TypeString,
Required: true,
Optional: true,
},
"ssl_mode": {
Type: schema.TypeString,
Expand All @@ -107,7 +112,7 @@ func resourceAwsDmsEndpoint() *schema.Resource {
},
"username": {
Type: schema.TypeString,
Required: true,
Optional: true,
},
},
}
Expand All @@ -120,22 +125,31 @@ func resourceAwsDmsEndpointCreate(d *schema.ResourceData, meta interface{}) erro
EndpointIdentifier: aws.String(d.Get("endpoint_id").(string)),
EndpointType: aws.String(d.Get("endpoint_type").(string)),
EngineName: aws.String(d.Get("engine_name").(string)),
Password: aws.String(d.Get("password").(string)),
Port: aws.Int64(int64(d.Get("port").(int))),
ServerName: aws.String(d.Get("server_name").(string)),
Tags: dmsTagsFromMap(d.Get("tags").(map[string]interface{})),
Username: aws.String(d.Get("username").(string)),
}

if v, ok := d.GetOk("database_name"); ok {
request.DatabaseName = aws.String(v.(string))
// if dynamodb then add required params
if d.Get("engine_name").(string) == "dynamodb" {
request.DynamoDbSettings = &dms.DynamoDbSettings{
ServiceAccessRoleArn: aws.String(d.Get("service_access_role").(string)),
}
} else {
request.Password = aws.String(d.Get("password").(string))
request.Port = aws.Int64(int64(d.Get("port").(int)))
request.ServerName = aws.String(d.Get("server_name").(string))
request.Username = aws.String(d.Get("username").(string))

if v, ok := d.GetOk("database_name"); ok {
request.DatabaseName = aws.String(v.(string))
}
if v, ok := d.GetOk("extra_connection_attributes"); ok {
request.ExtraConnectionAttributes = aws.String(v.(string))
}
}

if v, ok := d.GetOk("certificate_arn"); ok {
request.CertificateArn = aws.String(v.(string))
}
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))
}
Expand Down Expand Up @@ -208,6 +222,13 @@ func resourceAwsDmsEndpointUpdate(d *schema.ResourceData, meta interface{}) erro
hasChanges = true
}

if d.HasChange("service_access_role") {
request.DynamoDbSettings = &dms.DynamoDbSettings{
ServiceAccessRoleArn: aws.String(d.Get("service_access_role").(string)),
}
hasChanges = true
}

if d.HasChange("endpoint_type") {
request.EndpointType = aws.String(d.Get("endpoint_type").(string))
hasChanges = true
Expand Down Expand Up @@ -290,18 +311,28 @@ func resourceAwsDmsEndpointSetState(d *schema.ResourceData, endpoint *dms.Endpoi
d.SetId(*endpoint.EndpointIdentifier)

d.Set("certificate_arn", endpoint.CertificateArn)
d.Set("database_name", endpoint.DatabaseName)
d.Set("endpoint_arn", endpoint.EndpointArn)
d.Set("endpoint_id", endpoint.EndpointIdentifier)
// For some reason the AWS API only accepts lowercase type but returns it as uppercase
d.Set("endpoint_type", strings.ToLower(*endpoint.EndpointType))
d.Set("engine_name", endpoint.EngineName)
d.Set("extra_connection_attributes", endpoint.ExtraConnectionAttributes)

if *endpoint.EngineName == "dynamodb" {
if endpoint.DynamoDbSettings != nil {
d.Set("service_access_role", endpoint.DynamoDbSettings.ServiceAccessRoleArn)
} else {
d.Set("service_access_role", "")
}
} else {
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("port", endpoint.Port)
d.Set("server_name", endpoint.ServerName)
d.Set("ssl_mode", endpoint.SslMode)
d.Set("username", endpoint.Username)

return nil
}
167 changes: 162 additions & 5 deletions aws/resource_aws_dms_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import (

func TestAccAwsDmsEndpointBasic(t *testing.T) {
resourceName := "aws_dms_endpoint.dms_endpoint"
randId := acctest.RandString(8)
randId := acctest.RandString(8) + "-basic"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: dmsEndpointDestroy,
Steps: []resource.TestStep{
{
Config: dmsEndpointConfig(randId),
Config: dmsEndpointBasicConfig(randId),
Check: resource.ComposeTestCheckFunc(
checkDmsEndpointExists(resourceName),
resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"),
Expand All @@ -34,7 +34,7 @@ func TestAccAwsDmsEndpointBasic(t *testing.T) {
ImportStateVerifyIgnore: []string{"password"},
},
{
Config: dmsEndpointConfigUpdate(randId),
Config: dmsEndpointBasicConfigUpdate(randId),
Check: resource.ComposeTestCheckFunc(
checkDmsEndpointExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "database_name", "tf-test-dms-db-updated"),
Expand All @@ -50,6 +50,40 @@ func TestAccAwsDmsEndpointBasic(t *testing.T) {
})
}

func TestAccAwsDmsEndpointDynamoDb(t *testing.T) {
resourceName := "aws_dms_endpoint.dms_endpoint"
randId := acctest.RandString(8) + "-dynamodb"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: dmsEndpointDestroy,
Steps: []resource.TestStep{
{
Config: dmsEndpointDynamoDbConfig(randId),
Check: resource.ComposeTestCheckFunc(
checkDmsEndpointExists(resourceName),
resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"password"},
},
{
Config: dmsEndpointDynamoDbConfigUpdate(randId),
Check: resource.ComposeTestCheckFunc(
checkDmsEndpointExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "ssl_mode", "none"),
resource.TestCheckResourceAttr(resourceName, "server_name", "tftestupdate"),
),
},
},
})
}

func dmsEndpointDestroy(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_dms_endpoint" {
Expand Down Expand Up @@ -98,7 +132,7 @@ func checkDmsEndpointExists(n string) resource.TestCheckFunc {
}
}

func dmsEndpointConfig(randId string) string {
func dmsEndpointBasicConfig(randId string) string {
return fmt.Sprintf(`
resource "aws_dms_endpoint" "dms_endpoint" {
database_name = "tf-test-dms-db"
Expand All @@ -120,7 +154,7 @@ resource "aws_dms_endpoint" "dms_endpoint" {
`, randId)
}

func dmsEndpointConfigUpdate(randId string) string {
func dmsEndpointBasicConfigUpdate(randId string) string {
return fmt.Sprintf(`
resource "aws_dms_endpoint" "dms_endpoint" {
database_name = "tf-test-dms-db-updated"
Expand All @@ -141,3 +175,126 @@ resource "aws_dms_endpoint" "dms_endpoint" {
}
`, randId)
}

func dmsEndpointDynamoDbConfig(randId string) string {
return fmt.Sprintf(`
resource "aws_dms_endpoint" "dms_endpoint" {
endpoint_id = "tf-test-dms-endpoint-%[1]s"
endpoint_type = "target"
engine_name = "dynamodb"
server_name = "tftest"
service_access_role = "${aws_iam_role.iam_role.arn}"
ssl_mode = "none"
tags {
Name = "tf-test-dynamodb-endpoint-%[1]s"
Update = "to-update"
Remove = "to-remove"
}
}
resource "aws_iam_role" "iam_role" {
name = "tf-test-iam-dynamodb-role-%[1]s"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "dms.amazonaws.com"
},
"Effect": "Allow"
}
]
}
EOF
}
resource "aws_iam_role_policy" "dms_dynamodb_access" {
name = "tf-test-iam-dynamodb-role-policy-%[1]s"
role = "${aws_iam_role.iam_role.name}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:PutItem",
"dynamodb:CreateTable",
"dynamodb:DescribeTable",
"dynamodb:DeleteTable",
"dynamodb:DeleteItem",
"dynamodb:ListTables"
],
"Resource": "*"
}
]
}
EOF
}
`, randId)
}

func dmsEndpointDynamoDbConfigUpdate(randId string) string {
return fmt.Sprintf(`
resource "aws_dms_endpoint" "dms_endpoint" {
endpoint_id = "tf-test-dms-endpoint-%[1]s"
endpoint_type = "target"
engine_name = "dynamodb"
server_name = "tftestupdate"
service_access_role = "${aws_iam_role.iam_role.arn}"
ssl_mode = "none"
tags {
Name = "tf-test-dynamodb-endpoint-%[1]s"
Update = "updated"
Add = "added"
}
}
resource "aws_iam_role" "iam_role" {
name = "tf-test-iam-dynamodb-role-%[1]s"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "dms.amazonaws.com"
},
"Effect": "Allow"
}
]
}
EOF
}
resource "aws_iam_role_policy" "dms_dynamodb_access" {
name = "tf-test-iam-dynamodb-role-policy-%[1]s"
role = "${aws_iam_role.iam_role.name}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:PutItem",
"dynamodb:CreateTable",
"dynamodb:DescribeTable",
"dynamodb:DeleteTable",
"dynamodb:DeleteItem",
"dynamodb:ListTables"
],
"Resource": "*"
}
]
}
EOF
}
`, randId)
}

0 comments on commit 84e031a

Please sign in to comment.