From ccd745c96fa7fd3e9905052906fe5753cfc33102 Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Sun, 21 Aug 2016 17:17:19 -0500 Subject: [PATCH] provider/aws: New Data Source: aws_acm_certificate Use this data source to get the ARN of a certificate in AWS Certificate Manager (ACM). The process of requesting and verifying a certificate in ACM requires some manual steps, which means that Terraform cannot automate the creation of ACM certificates. But using this data source, you can reference them by domain without having to hard code the ARNs as input. The acceptance test included requires an ACM certificate be pre-created in and information about it passed in via environment variables. It's a bit sad but there's really no other way to do it. --- builtin/providers/aws/config.go | 3 + .../aws/data_source_aws_acm_certificate.go | 46 ++++++++++++++ .../data_source_aws_acm_certificate_test.go | 63 +++++++++++++++++++ builtin/providers/aws/provider.go | 1 + .../aws/d/acm_certificate.html.markdown | 31 +++++++++ 5 files changed, 144 insertions(+) create mode 100644 builtin/providers/aws/data_source_aws_acm_certificate.go create mode 100644 builtin/providers/aws/data_source_aws_acm_certificate_test.go create mode 100644 website/source/docs/providers/aws/d/acm_certificate.html.markdown diff --git a/builtin/providers/aws/config.go b/builtin/providers/aws/config.go index a4116ad2b2..fac29f0df4 100644 --- a/builtin/providers/aws/config.go +++ b/builtin/providers/aws/config.go @@ -14,6 +14,7 @@ import ( "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/acm" "github.com/aws/aws-sdk-go/service/apigateway" "github.com/aws/aws-sdk-go/service/applicationautoscaling" "github.com/aws/aws-sdk-go/service/autoscaling" @@ -110,6 +111,7 @@ type AWSClient struct { elbv2conn *elbv2.ELBV2 emrconn *emr.EMR esconn *elasticsearch.ElasticsearchService + acmconn *acm.ACM apigateway *apigateway.APIGateway appautoscalingconn *applicationautoscaling.ApplicationAutoScaling autoscalingconn *autoscaling.AutoScaling @@ -246,6 +248,7 @@ func (c *Config) Client() (interface{}, error) { return nil, authErr } + client.acmconn = acm.New(sess) client.apigateway = apigateway.New(sess) client.appautoscalingconn = applicationautoscaling.New(sess) client.autoscalingconn = autoscaling.New(sess) diff --git a/builtin/providers/aws/data_source_aws_acm_certificate.go b/builtin/providers/aws/data_source_aws_acm_certificate.go new file mode 100644 index 0000000000..e44137d99c --- /dev/null +++ b/builtin/providers/aws/data_source_aws_acm_certificate.go @@ -0,0 +1,46 @@ +package aws + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/service/acm" + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceAwsAcmCertificate() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsAcmCertificateRead, + Schema: map[string]*schema.Schema{ + "domain": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "arn": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceAwsAcmCertificateRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).acmconn + params := &acm.ListCertificatesInput{} + resp, err := conn.ListCertificates(params) + if err != nil { + return errwrap.Wrapf("Error describing certificates: {{err}}", err) + } + + target := d.Get("domain") + for _, cert := range resp.CertificateSummaryList { + if *cert.DomainName == target { + // Need to call SetId with a value or state won't be written. + d.SetId(time.Now().UTC().String()) + return d.Set("arn", cert.CertificateArn) + } + } + + return fmt.Errorf("No certificate with domain %s found in this region", target) +} diff --git a/builtin/providers/aws/data_source_aws_acm_certificate_test.go b/builtin/providers/aws/data_source_aws_acm_certificate_test.go new file mode 100644 index 0000000000..8130306cb8 --- /dev/null +++ b/builtin/providers/aws/data_source_aws_acm_certificate_test.go @@ -0,0 +1,63 @@ +package aws + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAwsAcmCertificateDataSource_basic(t *testing.T) { + region := os.Getenv("AWS_ACM_TEST_REGION") + domain := os.Getenv("AWS_ACM_TEST_DOMAIN") + certArn := os.Getenv("AWS_ACM_TEST_CERT_ARN") + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + if region == "" { + t.Skip("AWS_ACM_TEST_REGION must be set to a region an ACM certificate pre-created for this test.") + } + if domain == "" { + t.Skip("AWS_ACM_TEST_DOMAIN must be set to a domain with an ACM certificate pre-created for this test.") + } + if certArn == "" { + t.Skip("AWS_ACM_TEST_CERT_ARN must be set to the ARN of an ACM cert pre-created for this test.") + } + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckAwsAcmCertificateDataSourceConfig(region, domain), + Check: testAccCheckAcmArnMatches("data.aws_acm_certificate.test", certArn), + }, + }, + }) +} + +func testAccCheckAcmArnMatches(name, expectArn string) resource.TestCheckFunc { + return func(s *terraform.State) error { + ms := s.RootModule() + rs, ok := ms.Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + gotArn := rs.Primary.Attributes["arn"] + if gotArn != expectArn { + return fmt.Errorf("Expected cert to have arn: %s, got: %s", expectArn, gotArn) + } + return nil + } +} + +func testAccCheckAwsAcmCertificateDataSourceConfig(region, domain string) string { + return fmt.Sprintf(` +provider "aws" { + region = "%s" +} +data "aws_acm_certificate" "test" { + domain = "%s" +} + `, region, domain) +} diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index c6eb88e95d..ad6c318459 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -143,6 +143,7 @@ func Provider() terraform.ResourceProvider { }, DataSourcesMap: map[string]*schema.Resource{ + "aws_acm_certificate": dataSourceAwsAcmCertificate(), "aws_ami": dataSourceAwsAmi(), "aws_availability_zone": dataSourceAwsAvailabilityZone(), "aws_availability_zones": dataSourceAwsAvailabilityZones(), diff --git a/website/source/docs/providers/aws/d/acm_certificate.html.markdown b/website/source/docs/providers/aws/d/acm_certificate.html.markdown new file mode 100644 index 0000000000..a05ae97f46 --- /dev/null +++ b/website/source/docs/providers/aws/d/acm_certificate.html.markdown @@ -0,0 +1,31 @@ +--- +layout: "aws" +page_title: "AWS: aws_acm_certificate" +sidebar_current: "docs-aws-datasource-acm-certificate" +description: |- + Get information on a Amazon Certificate Manager (ACM) Certificate +--- + +# aws\_acm\_certificate + +Use this data source to get the ARN of a certificate in AWS Certificate +Manager (ACM). The process of requesting and verifying a certificate in ACM +requires some manual steps, which means that Terraform cannot automate the +creation of ACM certificates. But using this data source, you can reference +them by domain without having to hard code the ARNs as input. + +## Example Usage + +``` +data "aws_acm_certificate" "example" { + domain = "tf.example.com" +} +``` + +## Argument Reference + + * `domain` - (Required) The domain of the certificate to look up. If no certificate is found with this name, an error will be returned. + +## Attributes Reference + + * `arn` - Set to the ARN of the found certificate, suitable for referencing in other resources that support ACM certificates.