Skip to content

Commit

Permalink
provider/aws: New Data Source: aws_acm_certificate
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
phinze authored and jen20 committed Nov 3, 2016
1 parent 194d7c6 commit ccd745c
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 0 deletions.
3 changes: 3 additions & 0 deletions builtin/providers/aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
46 changes: 46 additions & 0 deletions builtin/providers/aws/data_source_aws_acm_certificate.go
Original file line number Diff line number Diff line change
@@ -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)
}
63 changes: 63 additions & 0 deletions builtin/providers/aws/data_source_aws_acm_certificate_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
1 change: 1 addition & 0 deletions builtin/providers/aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
31 changes: 31 additions & 0 deletions website/source/docs/providers/aws/d/acm_certificate.html.markdown
Original file line number Diff line number Diff line change
@@ -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.

0 comments on commit ccd745c

Please sign in to comment.