diff --git a/.changelog/19578.txt b/.changelog/19578.txt new file mode 100644 index 000000000000..c02aad104ece --- /dev/null +++ b/.changelog/19578.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_acmpca_certificate_authority: Add `s3_object_acl` argument to `revocation_configuration.crl_configuration` configuration block +``` \ No newline at end of file diff --git a/aws/resource_aws_acmpca_certificate_authority.go b/aws/resource_aws_acmpca_certificate_authority.go index a569d394a812..c667f22507e2 100644 --- a/aws/resource_aws_acmpca_certificate_authority.go +++ b/aws/resource_aws_acmpca_certificate_authority.go @@ -236,6 +236,12 @@ func resourceAwsAcmpcaCertificateAuthority() *schema.Resource { Optional: true, ValidateFunc: validation.StringLenBetween(0, 255), }, + "s3_object_acl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice(acmpca.S3ObjectAcl_Values(), false), + }, }, }, }, @@ -602,6 +608,9 @@ func expandAcmpcaCrlConfiguration(l []interface{}) *acmpca.CrlConfiguration { if v, ok := m["s3_bucket_name"]; ok && v.(string) != "" { config.S3BucketName = aws.String(v.(string)) } + if v, ok := m["s3_object_acl"]; ok && v.(string) != "" { + config.S3ObjectAcl = aws.String(v.(string)) + } return config } @@ -668,6 +677,7 @@ func flattenAcmpcaCrlConfiguration(config *acmpca.CrlConfiguration) []interface{ "enabled": aws.BoolValue(config.Enabled), "expiration_in_days": int(aws.Int64Value(config.ExpirationInDays)), "s3_bucket_name": aws.StringValue(config.S3BucketName), + "s3_object_acl": aws.StringValue(config.S3ObjectAcl), } return []interface{}{m} diff --git a/aws/resource_aws_acmpca_certificate_authority_test.go b/aws/resource_aws_acmpca_certificate_authority_test.go index f2543d6ce261..274be1562785 100644 --- a/aws/resource_aws_acmpca_certificate_authority_test.go +++ b/aws/resource_aws_acmpca_certificate_authority_test.go @@ -403,6 +403,7 @@ func TestAccAwsAcmpcaCertificateAuthority_RevocationConfiguration_CrlConfigurati resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.enabled", "true"), resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.expiration_in_days", "1"), resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.s3_bucket_name", rName), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.s3_object_acl", "PUBLIC_READ"), ), }, // Test importing revocation configuration @@ -440,6 +441,56 @@ func TestAccAwsAcmpcaCertificateAuthority_RevocationConfiguration_CrlConfigurati }) } +func TestAccAwsAcmpcaCertificateAuthority_RevocationConfiguration_CrlConfiguration_S3ObjectAcl(t *testing.T) { + var certificateAuthority acmpca.CertificateAuthority + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_acmpca_certificate_authority.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, acmpca.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsAcmpcaCertificateAuthorityDestroy, + Steps: []resource.TestStep{ + // Test creating revocation configuration on resource creation + { + Config: testAccAwsAcmpcaCertificateAuthorityConfig_RevocationConfiguration_CrlConfiguration_s3ObjectAcl(rName, "BUCKET_OWNER_FULL_CONTROL"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsAcmpcaCertificateAuthorityExists(resourceName, &certificateAuthority), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.expiration_in_days", "1"), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.s3_bucket_name", rName), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.s3_object_acl", "BUCKET_OWNER_FULL_CONTROL"), + ), + }, + // Test importing revocation configuration + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "permanent_deletion_time_in_days", + }, + }, + // Test updating revocation configuration + { + Config: testAccAwsAcmpcaCertificateAuthorityConfig_RevocationConfiguration_CrlConfiguration_s3ObjectAcl(rName, "PUBLIC_READ"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsAcmpcaCertificateAuthorityExists(resourceName, &certificateAuthority), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.expiration_in_days", "1"), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.s3_bucket_name", rName), + resource.TestCheckResourceAttr(resourceName, "revocation_configuration.0.crl_configuration.0.s3_object_acl", "PUBLIC_READ"), + ), + }, + }, + }) +} + func TestAccAwsAcmpcaCertificateAuthority_Tags(t *testing.T) { var certificateAuthority acmpca.CertificateAuthority resourceName := "aws_acmpca_certificate_authority.test" @@ -797,6 +848,36 @@ resource "aws_acmpca_certificate_authority" "test" { `, testAccAwsAcmpcaCertificateAuthorityConfig_S3Bucket(rName), expirationInDays) } +func testAccAwsAcmpcaCertificateAuthorityConfig_RevocationConfiguration_CrlConfiguration_s3ObjectAcl(rName, s3ObjectAcl string) string { + return fmt.Sprintf(` +%s + +resource "aws_acmpca_certificate_authority" "test" { + permanent_deletion_time_in_days = 7 + + certificate_authority_configuration { + key_algorithm = "RSA_4096" + signing_algorithm = "SHA512WITHRSA" + + subject { + common_name = "terraformtesting.com" + } + } + + revocation_configuration { + crl_configuration { + enabled = true + expiration_in_days = 1 + s3_bucket_name = aws_s3_bucket.test.id + s3_object_acl = "%s" + } + } + + depends_on = [aws_s3_bucket_policy.test] +} +`, testAccAwsAcmpcaCertificateAuthorityConfig_S3Bucket(rName), s3ObjectAcl) +} + func testAccAwsAcmpcaCertificateAuthorityConfig_S3Bucket(rName string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { diff --git a/website/docs/r/acmpca_certificate_authority.html.markdown b/website/docs/r/acmpca_certificate_authority.html.markdown index b01d4fb27553..8e53c7298ce6 100644 --- a/website/docs/r/acmpca_certificate_authority.html.markdown +++ b/website/docs/r/acmpca_certificate_authority.html.markdown @@ -132,6 +132,7 @@ Contains information about the certificate subject. Identifies the entity that o * `enabled` - (Optional) Boolean value that specifies whether certificate revocation lists (CRLs) are enabled. Defaults to `false`. * `expiration_in_days` - (Required) Number of days until a certificate expires. Must be between 1 and 5000. * `s3_bucket_name` - (Optional) Name of the S3 bucket that contains the CRL. If you do not provide a value for the `custom_cname` argument, the name of your S3 bucket is placed into the CRL Distribution Points extension of the issued certificate. You must specify a bucket policy that allows ACM PCA to write the CRL to your bucket. Must be less than or equal to 255 characters in length. +* `s3_object_acl` - (Optional) Determines whether the CRL will be publicly readable or privately held in the CRL Amazon S3 bucket. Defaults to `PUBLIC_READ`. ## Attributes Reference