Skip to content

Commit

Permalink
Merge pull request #4458 from terraform-providers/f-aws_acmpca_certif…
Browse files Browse the repository at this point in the history
…icate_authority

New Resource and Data Source: aws_acmpca_certificate_authority
  • Loading branch information
bflad authored May 9, 2018
2 parents c01b933 + 1c68376 commit a153dc2
Show file tree
Hide file tree
Showing 10 changed files with 2,028 additions and 0 deletions.
176 changes: 176 additions & 0 deletions aws/data_source_aws_acmpca_certificate_authority.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package aws

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/acmpca"
"github.com/hashicorp/terraform/helper/schema"
)

func dataSourceAwsAcmpcaCertificateAuthority() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsAcmpcaCertificateAuthorityRead,

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Required: true,
},
"certificate": {
Type: schema.TypeString,
Computed: true,
},
"certificate_chain": {
Type: schema.TypeString,
Computed: true,
},
"certificate_signing_request": {
Type: schema.TypeString,
Computed: true,
},
"not_after": {
Type: schema.TypeString,
Computed: true,
},
"not_before": {
Type: schema.TypeString,
Computed: true,
},
// https://docs.aws.amazon.com/acm-pca/latest/APIReference/API_RevocationConfiguration.html
"revocation_configuration": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
// https://docs.aws.amazon.com/acm-pca/latest/APIReference/API_CrlConfiguration.html
"crl_configuration": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"custom_cname": {
Type: schema.TypeString,
Computed: true,
},
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"expiration_in_days": {
Type: schema.TypeInt,
Computed: true,
},
"s3_bucket_name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
},
},
"serial": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"tags": tagsSchemaComputed(),
"type": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceAwsAcmpcaCertificateAuthorityRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).acmpcaconn
certificateAuthorityArn := d.Get("arn").(string)

describeCertificateAuthorityInput := &acmpca.DescribeCertificateAuthorityInput{
CertificateAuthorityArn: aws.String(certificateAuthorityArn),
}

log.Printf("[DEBUG] Reading ACMPCA Certificate Authority: %s", describeCertificateAuthorityInput)

describeCertificateAuthorityOutput, err := conn.DescribeCertificateAuthority(describeCertificateAuthorityInput)
if err != nil {
return fmt.Errorf("error reading ACMPCA Certificate Authority: %s", err)
}

if describeCertificateAuthorityOutput.CertificateAuthority == nil {
return fmt.Errorf("error reading ACMPCA Certificate Authority: not found")
}
certificateAuthority := describeCertificateAuthorityOutput.CertificateAuthority

d.Set("arn", certificateAuthority.Arn)
d.Set("not_after", certificateAuthority.NotAfter)
d.Set("not_before", certificateAuthority.NotBefore)

if err := d.Set("revocation_configuration", flattenAcmpcaRevocationConfiguration(certificateAuthority.RevocationConfiguration)); err != nil {
return fmt.Errorf("error setting tags: %s", err)
}

d.Set("serial", certificateAuthority.Serial)
d.Set("status", certificateAuthority.Status)
d.Set("type", certificateAuthority.Type)

getCertificateAuthorityCertificateInput := &acmpca.GetCertificateAuthorityCertificateInput{
CertificateAuthorityArn: aws.String(certificateAuthorityArn),
}

log.Printf("[DEBUG] Reading ACMPCA Certificate Authority Certificate: %s", getCertificateAuthorityCertificateInput)

getCertificateAuthorityCertificateOutput, err := conn.GetCertificateAuthorityCertificate(getCertificateAuthorityCertificateInput)
if err != nil {
// Returned when in PENDING_CERTIFICATE status
// InvalidStateException: The certificate authority XXXXX is not in the correct state to have a certificate signing request.
if !isAWSErr(err, acmpca.ErrCodeInvalidStateException, "") {
return fmt.Errorf("error reading ACMPCA Certificate Authority Certificate: %s", err)
}
}

d.Set("certificate", "")
d.Set("certificate_chain", "")
if getCertificateAuthorityCertificateOutput != nil {
d.Set("certificate", getCertificateAuthorityCertificateOutput.Certificate)
d.Set("certificate_chain", getCertificateAuthorityCertificateOutput.CertificateChain)
}

getCertificateAuthorityCsrInput := &acmpca.GetCertificateAuthorityCsrInput{
CertificateAuthorityArn: aws.String(certificateAuthorityArn),
}

log.Printf("[DEBUG] Reading ACMPCA Certificate Authority Certificate Signing Request: %s", getCertificateAuthorityCsrInput)

getCertificateAuthorityCsrOutput, err := conn.GetCertificateAuthorityCsr(getCertificateAuthorityCsrInput)
if err != nil {
return fmt.Errorf("error reading ACMPCA Certificate Authority Certificate Signing Request: %s", err)
}

d.Set("certificate_signing_request", "")
if getCertificateAuthorityCsrOutput != nil {
d.Set("certificate_signing_request", getCertificateAuthorityCsrOutput.Csr)
}

tags, err := listAcmpcaTags(conn, certificateAuthorityArn)
if err != nil {
return fmt.Errorf("error reading ACMPCA Certificate Authority %q tags: %s", certificateAuthorityArn, err)
}

if err := d.Set("tags", tagsToMapACMPCA(tags)); err != nil {
return fmt.Errorf("error setting tags: %s", err)
}

d.SetId(certificateAuthorityArn)

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

import (
"fmt"
"regexp"
"testing"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccDataSourceAwsAcmpcaCertificateAuthority_Basic(t *testing.T) {
resourceName := "aws_acmpca_certificate_authority.test"
datasourceName := "data.aws_acmpca_certificate_authority.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAwsAcmpcaCertificateAuthorityConfig_NonExistent,
ExpectError: regexp.MustCompile(`ResourceNotFoundException`),
},
{
Config: testAccDataSourceAwsAcmpcaCertificateAuthorityConfig_ARN,
Check: resource.ComposeTestCheckFunc(
testAccDataSourceAwsAcmpcaCertificateAuthorityCheck(datasourceName, resourceName),
),
},
},
})
}

func testAccDataSourceAwsAcmpcaCertificateAuthorityCheck(datasourceName, resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
resource, ok := s.RootModule().Resources[datasourceName]
if !ok {
return fmt.Errorf("root module has no resource called %s", datasourceName)
}

dataSource, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("root module has no resource called %s", resourceName)
}

attrNames := []string{
"arn",
"certificate",
"certificate_chain",
"certificate_signing_request",
"not_after",
"not_before",
"revocation_configuration.#",
"revocation_configuration.0.crl_configuration.#",
"revocation_configuration.0.crl_configuration.0.enabled",
"serial",
"status",
"tags.%",
"type",
}

for _, attrName := range attrNames {
if resource.Primary.Attributes[attrName] != dataSource.Primary.Attributes[attrName] {
return fmt.Errorf(
"%s is %s; want %s",
attrName,
resource.Primary.Attributes[attrName],
dataSource.Primary.Attributes[attrName],
)
}
}

return nil
}
}

const testAccDataSourceAwsAcmpcaCertificateAuthorityConfig_ARN = `
resource "aws_acmpca_certificate_authority" "wrong" {
certificate_authority_configuration {
key_algorithm = "RSA_4096"
signing_algorithm = "SHA512WITHRSA"
subject {
common_name = "terraformtesting.com"
}
}
}
resource "aws_acmpca_certificate_authority" "test" {
certificate_authority_configuration {
key_algorithm = "RSA_4096"
signing_algorithm = "SHA512WITHRSA"
subject {
common_name = "terraformtesting.com"
}
}
}
data "aws_acmpca_certificate_authority" "test" {
arn = "${aws_acmpca_certificate_authority.test.arn}"
}
`

const testAccDataSourceAwsAcmpcaCertificateAuthorityConfig_NonExistent = `
data "aws_acmpca_certificate_authority" "test" {
arn = "arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/tf-acc-test-does-not-exist"
}
`
2 changes: 2 additions & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ func Provider() terraform.ResourceProvider {

DataSourcesMap: map[string]*schema.Resource{
"aws_acm_certificate": dataSourceAwsAcmCertificate(),
"aws_acmpca_certificate_authority": dataSourceAwsAcmpcaCertificateAuthority(),
"aws_ami": dataSourceAwsAmi(),
"aws_ami_ids": dataSourceAwsAmiIds(),
"aws_api_gateway_rest_api": dataSourceAwsApiGatewayRestApi(),
Expand Down Expand Up @@ -255,6 +256,7 @@ func Provider() terraform.ResourceProvider {
ResourcesMap: map[string]*schema.Resource{
"aws_acm_certificate": resourceAwsAcmCertificate(),
"aws_acm_certificate_validation": resourceAwsAcmCertificateValidation(),
"aws_acmpca_certificate_authority": resourceAwsAcmpcaCertificateAuthority(),
"aws_ami": resourceAwsAmi(),
"aws_ami_copy": resourceAwsAmiCopy(),
"aws_ami_from_instance": resourceAwsAmiFromInstance(),
Expand Down
Loading

0 comments on commit a153dc2

Please sign in to comment.