Skip to content

Commit

Permalink
Merge branch 'mattburgess-acm-cert-transparency-logging'
Browse files Browse the repository at this point in the history
  • Loading branch information
bflad committed Aug 5, 2019
2 parents d1dd229 + c9e86a6 commit 8c7b6cc
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 2 deletions.
60 changes: 59 additions & 1 deletion aws/resource_aws_acm_certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/aws/aws-sdk-go/service/acm"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsAcmCertificate() *schema.Resource {
Expand All @@ -22,7 +23,6 @@ func resourceAwsAcmCertificate() *schema.Resource {
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"certificate_body": {
Type: schema.TypeString,
Expand Down Expand Up @@ -108,6 +108,35 @@ func resourceAwsAcmCertificate() *schema.Resource {
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"options": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
if _, ok := d.GetOk("private_key"); ok {
// ignore diffs for imported certs; they have a different logging preference
// default to requested certs which can't be changed by the ImportCertificate API
return true
}
// behave just like suppressMissingOptionalConfigurationBlock() for requested certs
return old == "1" && new == "0"
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"certificate_transparency_logging_preference": {
Type: schema.TypeString,
Optional: true,
Default: acm.CertificateTransparencyLoggingPreferenceEnabled,
ForceNew: true,
ConflictsWith: []string{"private_key", "certificate_body", "certificate_chain"},
ValidateFunc: validation.StringInSlice([]string{
acm.CertificateTransparencyLoggingPreferenceEnabled,
acm.CertificateTransparencyLoggingPreferenceDisabled,
}, false),
},
},
},
},
"tags": tagsSchema(),
},
}
Expand Down Expand Up @@ -155,6 +184,7 @@ func resourceAwsAcmCertificateCreateRequested(d *schema.ResourceData, meta inter
acmconn := meta.(*AWSClient).acmconn
params := &acm.RequestCertificateInput{
DomainName: aws.String(strings.TrimSuffix(d.Get("domain_name").(string), ".")),
Options: expandAcmCertificateOptions(d.Get("options").([]interface{})),
ValidationMethod: aws.String(d.Get("validation_method").(string)),
}

Expand Down Expand Up @@ -229,6 +259,10 @@ func resourceAwsAcmCertificateRead(d *schema.ResourceData, meta interface{}) err

d.Set("validation_method", resourceAwsAcmCertificateGuessValidationMethod(domainValidationOptions, emailValidationOptions))

if err := d.Set("options", flattenAcmCertificateOptions(resp.Certificate.Options)); err != nil {
return resource.NonRetryableError(fmt.Errorf("error setting certificate options: %s", err))
}

params := &acm.ListTagsForCertificateInput{
CertificateArn: aws.String(d.Id()),
}
Expand Down Expand Up @@ -362,3 +396,27 @@ func resourceAwsAcmCertificateImport(conn *acm.ACM, d *schema.ResourceData, upda
log.Printf("[DEBUG] ACM Certificate Import: %#v", params)
return conn.ImportCertificate(params)
}

func expandAcmCertificateOptions(l []interface{}) *acm.CertificateOptions {
if len(l) == 0 || l[0] == nil {
return nil
}

m := l[0].(map[string]interface{})

options := &acm.CertificateOptions{}

if v, ok := m["certificate_transparency_logging_preference"]; ok {
options.CertificateTransparencyLoggingPreference = aws.String(v.(string))
}

return options
}

func flattenAcmCertificateOptions(co *acm.CertificateOptions) []interface{} {
m := map[string]interface{}{
"certificate_transparency_logging_preference": aws.StringValue(co.CertificateTransparencyLoggingPreference),
}

return []interface{}{m}
}
47 changes: 47 additions & 0 deletions aws/resource_aws_acm_certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,40 @@ func TestAccAWSAcmCertificate_wildcardAndRootSan(t *testing.T) {
})
}

func TestAccAWSAcmCertificate_disableCTLogging(t *testing.T) {
rootDomain := testAccAwsAcmCertificateDomainFromEnv(t)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAcmCertificateDestroy,
Steps: []resource.TestStep{
{
Config: testAccAcmCertificateConfig_disableCTLogging(rootDomain, acm.ValidationMethodDns),
Check: resource.ComposeTestCheckFunc(
resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex),
resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", rootDomain),
resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_validation_options.#", "1"),
resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_validation_options.0.domain_name", rootDomain),
resource.TestCheckResourceAttrSet("aws_acm_certificate.cert", "domain_validation_options.0.resource_record_name"),
resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_validation_options.0.resource_record_type", "CNAME"),
resource.TestCheckResourceAttrSet("aws_acm_certificate.cert", "domain_validation_options.0.resource_record_value"),
resource.TestCheckResourceAttr("aws_acm_certificate.cert", "subject_alternative_names.#", "0"),
resource.TestCheckResourceAttr("aws_acm_certificate.cert", "validation_emails.#", "0"),
resource.TestCheckResourceAttr("aws_acm_certificate.cert", "validation_method", acm.ValidationMethodDns),
resource.TestCheckResourceAttr("aws_acm_certificate.cert", "options.#", "1"),
resource.TestCheckResourceAttr("aws_acm_certificate.cert", "options.0.certificate_transparency_logging_preference", acm.CertificateTransparencyLoggingPreferenceDisabled),
),
},
{
ResourceName: "aws_acm_certificate.cert",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAWSAcmCertificate_tags(t *testing.T) {
rootDomain := testAccAwsAcmCertificateDomainFromEnv(t)
domain := testAccAwsAcmCertificateRandomSubDomain(rootDomain)
Expand Down Expand Up @@ -628,6 +662,19 @@ resource "aws_acm_certificate" "test" {
`, commonName)
}

func testAccAcmCertificateConfig_disableCTLogging(domainName, validationMethod string) string {
return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
domain_name = "%s"
validation_method = "%s"
options {
certificate_transparency_logging_preference = "DISABLED"
}
}
`, domainName, validationMethod)

}

func testAccCheckAcmCertificateDestroy(s *terraform.State) error {
acmconn := testAccProvider.Meta().(*AWSClient).acmconn

Expand Down
9 changes: 8 additions & 1 deletion website/docs/r/acm_certificate.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,19 @@ The following arguments are supported:
* `domain_name` - (Required) A domain name for which the certificate should be issued
* `subject_alternative_names` - (Optional) A list of domains that should be SANs in the issued certificate
* `validation_method` - (Required) Which method to use for validation. `DNS` or `EMAIL` are valid, `NONE` can be used for certificates that were imported into ACM and then into Terraform.
* `options` - (Optional) Configuration block used to set certificate options. Detailed below.
* Importing an existing certificate
* `private_key` - (Required) The certificate's PEM-formatted private key
* `certificate_body` - (Required) The certificate's PEM-formatted public key
* `certificate_chain` - (Optional) The certificate's PEM-formatted chain
* `tags` - (Optional) A mapping of tags to assign to the resource.

## options Configuration Block

Supported nested arguments for the `options` configuration block:

* `certificate_transparency_logging_preference` - (Optional) Specifies whether certificate details should be added to a certificate transparency log. Valid values are `ENABLED` or `DISABLED`. See https://docs.aws.amazon.com/acm/latest/userguide/acm-concepts.html#concept-transparency for more details.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:
Expand All @@ -115,4 +122,4 @@ Certificates can be imported using their ARN, e.g.

```
$ terraform import aws_acm_certificate.cert arn:aws:acm:eu-central-1:123456789012:certificate/7e7a28d2-163f-4b8f-b9cd-822f96c08d6a
```
```

0 comments on commit 8c7b6cc

Please sign in to comment.