Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provider/aws: Add AWS DMS (data migration service) resources #11122

Merged
merged 21 commits into from
Feb 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
01096bf
Add aws dms vendoring
jzbruno Jan 20, 2017
ad2cfb1
Add aws dms endpoint resource
jzbruno Jan 20, 2017
ff9beca
Add aws dms replication instance resource
jzbruno Jan 20, 2017
0853b9e
Add aws dms replication subnet group resource
jzbruno Jan 20, 2017
972caea
Add aws dms replication task resource
jzbruno Jan 20, 2017
2b95c0b
Fix aws dms resource go vet errors
jzbruno Jan 20, 2017
1dc36a0
Merge remote-tracking branch 'upstream/master' into aws-dms-resources
jzbruno Jan 23, 2017
02008a1
Review fixes: Add id validators for all resources. Add validator for …
jzbruno Jan 24, 2017
547f94d
Add aws dms resources to importability list
jzbruno Jan 24, 2017
e46367b
Review fixes: Add aws dms iam role dependencies to test cases
jzbruno Jan 24, 2017
485a40c
Review fixes: Adjustments for handling input values
jzbruno Jan 25, 2017
5ffe3e3
Add aws dms replication subnet group tagging
jzbruno Jan 25, 2017
28dbe12
Fix aws dms subnet group doesn't use standard error for resource not …
jzbruno Jan 25, 2017
12c20e7
Merge remote-tracking branch 'upstream/master' into aws-dms-resources
jzbruno Jan 25, 2017
34fe399
Missed update of aws dms vendored version
jzbruno Jan 25, 2017
5e1b72c
Merge remote-tracking branch 'upstream/master' into aws-dms-resources
jzbruno Jan 30, 2017
de0262f
Add aws dms certificate resource
jzbruno Jan 31, 2017
632c500
Update aws dms resources to force new for immutable attributes
jzbruno Jan 31, 2017
8a8b0bc
Merge remote-tracking branch 'upstream/master' into aws-dms-resources
jzbruno Feb 1, 2017
9af5dee
Fix tests failing on subnet deletion by adding explicit dependencies.…
jzbruno Feb 2, 2017
6b4c593
Merge branch 'master' into aws-dms-resources
stack72 Feb 2, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions builtin/providers/aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
"github.com/aws/aws-sdk-go/service/codecommit"
"github.com/aws/aws-sdk-go/service/codedeploy"
"github.com/aws/aws-sdk-go/service/databasemigrationservice"
"github.com/aws/aws-sdk-go/service/directoryservice"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/ec2"
Expand Down Expand Up @@ -106,6 +107,7 @@ type AWSClient struct {
cloudwatchconn *cloudwatch.CloudWatch
cloudwatchlogsconn *cloudwatchlogs.CloudWatchLogs
cloudwatcheventsconn *cloudwatchevents.CloudWatchEvents
dmsconn *databasemigrationservice.DatabaseMigrationService
dsconn *directoryservice.DirectoryService
dynamodbconn *dynamodb.DynamoDB
ec2conn *ec2.EC2
Expand Down Expand Up @@ -276,6 +278,7 @@ func (c *Config) Client() (interface{}, error) {
client.cloudwatchlogsconn = cloudwatchlogs.New(sess)
client.codecommitconn = codecommit.New(sess)
client.codedeployconn = codedeploy.New(sess)
client.dmsconn = databasemigrationservice.New(sess)
client.dsconn = directoryservice.New(sess)
client.dynamodbconn = dynamodb.New(dynamoSess)
client.ec2conn = ec2.New(awsEc2Sess)
Expand Down
5 changes: 5 additions & 0 deletions builtin/providers/aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@ func Provider() terraform.ResourceProvider {
"aws_db_security_group": resourceAwsDbSecurityGroup(),
"aws_db_subnet_group": resourceAwsDbSubnetGroup(),
"aws_directory_service_directory": resourceAwsDirectoryServiceDirectory(),
"aws_dms_certificate": resourceAwsDmsCertificate(),
"aws_dms_endpoint": resourceAwsDmsEndpoint(),
"aws_dms_replication_instance": resourceAwsDmsReplicationInstance(),
"aws_dms_replication_subnet_group": resourceAwsDmsReplicationSubnetGroup(),
"aws_dms_replication_task": resourceAwsDmsReplicationTask(),
"aws_dynamodb_table": resourceAwsDynamoDbTable(),
"aws_ebs_snapshot": resourceAwsEbsSnapshot(),
"aws_ebs_volume": resourceAwsEbsVolume(),
Expand Down
138 changes: 138 additions & 0 deletions builtin/providers/aws/resource_aws_dms_certificate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package aws

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
dms "github.com/aws/aws-sdk-go/service/databasemigrationservice"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsDmsCertificate() *schema.Resource {
return &schema.Resource{
Create: resourceAwsDmsCertificateCreate,
Read: resourceAwsDmsCertificateRead,
Delete: resourceAwsDmsCertificateDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"certificate_arn": {
Type: schema.TypeString,
Computed: true,
},
"certificate_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateDmsCertificateId,
},
"certificate_pem": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Sensitive: true,
},
"certificate_wallet": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Sensitive: true,
},
},
}
}

func resourceAwsDmsCertificateCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).dmsconn

request := &dms.ImportCertificateInput{
CertificateIdentifier: aws.String(d.Get("certificate_id").(string)),
}

pem, pemSet := d.GetOk("certificate_pem")
wallet, walletSet := d.GetOk("certificate_wallet")

if !pemSet && !walletSet {
return fmt.Errorf("Must set either certificate_pem and certificate_wallet.")
}
if pemSet && walletSet {
return fmt.Errorf("Cannot set both certificate_pem and certificate_wallet.")
}

if pemSet {
request.CertificatePem = aws.String(pem.(string))
}
if walletSet {
request.CertificateWallet = []byte(wallet.(string))
}

log.Println("[DEBUG] DMS import certificate:", request)

_, err := conn.ImportCertificate(request)
if err != nil {
return err
}

d.SetId(d.Get("certificate_id").(string))
return resourceAwsDmsCertificateRead(d, meta)
}

func resourceAwsDmsCertificateRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).dmsconn

response, err := conn.DescribeCertificates(&dms.DescribeCertificatesInput{
Filters: []*dms.Filter{
{
Name: aws.String("certificate-id"),
Values: []*string{aws.String(d.Id())}, // Must use d.Id() to work with import.
},
},
})
if err != nil {
if dmserr, ok := err.(awserr.Error); ok && dmserr.Code() == "ResourceNotFoundFault" {
d.SetId("")
return nil
}
return err
}

return resourceAwsDmsCertificateSetState(d, response.Certificates[0])
}

func resourceAwsDmsCertificateDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).dmsconn

request := &dms.DeleteCertificateInput{
CertificateArn: aws.String(d.Get("certificate_arn").(string)),
}

log.Printf("[DEBUG] DMS delete certificate: %#v", request)

_, err := conn.DeleteCertificate(request)
if err != nil {
return err
}

return nil
}

func resourceAwsDmsCertificateSetState(d *schema.ResourceData, cert *dms.Certificate) error {
d.SetId(*cert.CertificateIdentifier)

d.Set("certificate_id", cert.CertificateIdentifier)
d.Set("certificate_arn", cert.CertificateArn)

if cert.CertificatePem != nil && *cert.CertificatePem != "" {
d.Set("certificate_pem", cert.CertificatePem)
}
if cert.CertificateWallet != nil && len(cert.CertificateWallet) == 0 {
d.Set("certificate_wallet", cert.CertificateWallet)
}

return nil
}
103 changes: 103 additions & 0 deletions builtin/providers/aws/resource_aws_dms_certificate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package aws

import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/aws"
dms "github.com/aws/aws-sdk-go/service/databasemigrationservice"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)

func TestAccAwsDmsCertificateBasic(t *testing.T) {
resourceName := "aws_dms_certificate.dms_certificate"
randId := acctest.RandString(8)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: dmsCertificateDestroy,
Steps: []resource.TestStep{
{
Config: dmsCertificateConfig(randId),
Check: resource.ComposeTestCheckFunc(
checkDmsCertificateExists(resourceName),
resource.TestCheckResourceAttrSet(resourceName, "certificate_arn"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func dmsCertificateDestroy(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_dms_certificate" {
continue
}

err := checkDmsCertificateExists(rs.Primary.ID)
if err == nil {
return fmt.Errorf("Found a certificate that was not destroyed: %s", rs.Primary.ID)
}
}

return nil
}

func checkDmsCertificateExists(n string) resource.TestCheckFunc {
providers := []*schema.Provider{testAccProvider}
return checkDmsCertificateExistsWithProviders(n, &providers)
}

func checkDmsCertificateExistsWithProviders(n string, providers *[]*schema.Provider) 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")
}
for _, provider := range *providers {
// Ignore if Meta is empty, this can happen for validation providers
if provider.Meta() == nil {
continue
}

conn := provider.Meta().(*AWSClient).dmsconn
_, err := conn.DescribeCertificates(&dms.DescribeCertificatesInput{
Filters: []*dms.Filter{
{
Name: aws.String("certificate-id"),
Values: []*string{aws.String(rs.Primary.ID)},
},
},
})

if err != nil {
return fmt.Errorf("DMS certificate error: %v", err)
}
return nil
}

return fmt.Errorf("DMS certificate not found")
}
}

func dmsCertificateConfig(randId string) string {
return fmt.Sprintf(`
resource "aws_dms_certificate" "dms_certificate" {
certificate_id = "tf-test-dms-certificate-%[1]s"
certificate_pem = "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIJAJ58TJVjU7G1MA0GCSqGSIb3DQEBBQUAMFExCzAJBgNV\nBAYTAlVTMREwDwYDVQQIEwhDb2xvcmFkbzEPMA0GA1UEBxMGRGVudmVyMRAwDgYD\nVQQKEwdDaGFydGVyMQwwCgYDVQQLEwNDU0UwHhcNMTcwMTMwMTkyMDA4WhcNMjYx\nMjA5MTkyMDA4WjBRMQswCQYDVQQGEwJVUzERMA8GA1UECBMIQ29sb3JhZG8xDzAN\nBgNVBAcTBkRlbnZlcjEQMA4GA1UEChMHQ2hhcnRlcjEMMAoGA1UECxMDQ1NFMIIB\nIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv6dq6VLIImlAaTrckb5w3X6J\nWP7EGz2ChGAXlkEYto6dPCba0v5+f+8UlMOpeB25XGoai7gdItqNWVFpYsgmndx3\nvTad3ukO1zeElKtw5oHPH2plOaiv/gVJaDa9NTeINj0EtGZs74fCOclAzGFX5vBc\nb08ESWBceRgGjGv3nlij4JzHfqTkCKQz6P6pBivQBfk62rcOkkH5rKoaGltRHROS\nMbkwOhu2hN0KmSYTXRvts0LXnZU4N0l2ms39gmr7UNNNlKYINL2JoTs9dNBc7APD\ndZvlEHd+/FjcLCI8hC3t4g4AbfW0okIBCNG0+oVjqGb2DeONSJKsThahXt89MQID\nAQABo4G0MIGxMB0GA1UdDgQWBBQKq8JxjY1GmeZXJjfOMfW0kBIzPDCBgQYDVR0j\nBHoweIAUCqvCcY2NRpnmVyY3zjH1tJASMzyhVaRTMFExCzAJBgNVBAYTAlVTMREw\nDwYDVQQIEwhDb2xvcmFkbzEPMA0GA1UEBxMGRGVudmVyMRAwDgYDVQQKEwdDaGFy\ndGVyMQwwCgYDVQQLEwNDU0WCCQCefEyVY1OxtTAMBgNVHRMEBTADAQH/MA0GCSqG\nSIb3DQEBBQUAA4IBAQAWifoMk5kbv+yuWXvFwHiB4dWUUmMlUlPU/E300yVTRl58\np6DfOgJs7MMftd1KeWqTO+uW134QlTt7+jwI8Jq0uyKCu/O2kJhVtH/Ryog14tGl\n+wLcuIPLbwJI9CwZX4WMBrq4DnYss+6F47i8NCc+Z3MAiG4vtq9ytBmaod0dj2bI\ng4/Lac0e00dql9RnqENh1+dF0V+QgTJCoPkMqDNAlSB8vOodBW81UAb2z12t+IFi\n3X9J3WtCK2+T5brXL6itzewWJ2ALvX3QpmZx7fMHJ3tE+SjjyivE1BbOlzYHx83t\nTeYnm7pS9un7A/UzTDHbs7hPUezLek+H3xTPAnnq\n-----END CERTIFICATE-----\n"
}
`, randId)
}
Loading