Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ownership-verification-cert. to API Gateway #21076

Merged
merged 25 commits into from
Feb 9, 2022
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changelog/21076.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```release-note:enhancement
resource/aws_api_gateway_domain_name: Add `ownership_verification_certificate_arn` argument.
```

```release-note:enhancement
resource/aws_apigatewayv2_domain_name: Add `domain_name_configuration.ownership_verification_certificate_arn` argument.
```

```release-note:enhancement
resource/aws_s3_bucket_versioning: Add eventual consistency handling to help ensure bucket versioning is stabilized.
```
54 changes: 27 additions & 27 deletions internal/service/apigateway/acc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,42 @@ import (

// API Gateway Edge-Optimized Domain Name can only be created with ACM Certificates in specific regions.

// testAccApigatewayEdgeDomainNameRegion is the chosen API Gateway Domain Name testing region
// testAccEdgeDomainNameRegion is the chosen API Gateway Domain Name testing region
//
// Cached to prevent issues should multiple regions become available.
var testAccApigatewayEdgeDomainNameRegion string
var testAccEdgeDomainNameRegion string

// testAccProviderApigatewayEdgeDomainName is the API Gateway Domain Name provider instance
// testAccProviderEdgeDomainName is the API Gateway Domain Name provider instance
//
// This Provider can be used in testing code for API calls without requiring
// the use of saving and referencing specific ProviderFactories instances.
//
// testAccPreCheckApigatewayEdgeDomainName(t) must be called before using this provider instance.
var testAccProviderApigatewayEdgeDomainName *schema.Provider
// testAccPreCheckEdgeDomainName(t) must be called before using this provider instance.
var testAccProviderEdgeDomainName *schema.Provider

// testAccProviderApigatewayEdgeDomainNameConfigure ensures the provider is only configured once
var testAccProviderApigatewayEdgeDomainNameConfigure sync.Once
// testAccProviderEdgeDomainNameConfigure ensures the provider is only configured once
var testAccProviderEdgeDomainNameConfigure sync.Once

// testAccPreCheckApigatewayEdgeDomainName verifies AWS credentials and that API Gateway Domain Name is supported
func testAccPreCheckApigatewayEdgeDomainName(t *testing.T) {
// testAccPreCheckEdgeDomainName verifies AWS credentials and that API Gateway Domain Name is supported
func testAccPreCheckEdgeDomainName(t *testing.T) {
acctest.PreCheckPartitionHasService(apigateway.EndpointsID, t)

region := testAccGetApigatewayEdgeDomainNameRegion()
region := testAccGetEdgeDomainNameRegion()

if region == "" {
t.Skip("API Gateway Domain Name not available in this AWS Partition")
}

// Since we are outside the scope of the Terraform configuration we must
// call Configure() to properly initialize the provider configuration.
testAccProviderApigatewayEdgeDomainNameConfigure.Do(func() {
testAccProviderApigatewayEdgeDomainName = provider.Provider()
testAccProviderEdgeDomainNameConfigure.Do(func() {
testAccProviderEdgeDomainName = provider.Provider()

config := map[string]interface{}{
"region": region,
}

diags := testAccProviderApigatewayEdgeDomainName.Configure(context.Background(), terraform.NewResourceConfigRaw(config))
diags := testAccProviderEdgeDomainName.Configure(context.Background(), terraform.NewResourceConfigRaw(config))

if diags != nil && diags.HasError() {
for _, d := range diags {
Expand All @@ -66,37 +66,37 @@ func testAccPreCheckApigatewayEdgeDomainName(t *testing.T) {
})
}

// testAccApigatewayEdgeDomainNameRegionProviderConfig is the Terraform provider configuration for API Gateway Domain Name region testing
// testAccEdgeDomainNameRegionProviderConfig is the Terraform provider configuration for API Gateway Domain Name region testing
//
// Testing API Gateway Domain Name assumes no other provider configurations
// are necessary and overwrites the "aws" provider configuration.
func testAccApigatewayEdgeDomainNameRegionProviderConfig() string {
return acctest.ConfigRegionalProvider(testAccGetApigatewayEdgeDomainNameRegion())
func testAccEdgeDomainNameRegionProviderConfig() string {
return acctest.ConfigRegionalProvider(testAccGetEdgeDomainNameRegion())
}

// testAccGetApigatewayEdgeDomainNameRegion returns the API Gateway Domain Name region for testing
func testAccGetApigatewayEdgeDomainNameRegion() string {
if testAccApigatewayEdgeDomainNameRegion != "" {
return testAccApigatewayEdgeDomainNameRegion
// testAccEdgeDomainNameRegion returns the API Gateway Domain Name region for testing
func testAccGetEdgeDomainNameRegion() string {
if testAccEdgeDomainNameRegion != "" {
return testAccEdgeDomainNameRegion
}

// AWS Commercial: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html
// AWS GovCloud (US) - edge custom domain names not supported: https://docs.aws.amazon.com/govcloud-us/latest/UserGuide/govcloud-abp.html
// AWS China - edge custom domain names not supported: https://docs.amazonaws.cn/en_us/aws/latest/userguide/api-gateway.html
switch acctest.Partition() {
case endpoints.AwsPartitionID:
testAccApigatewayEdgeDomainNameRegion = endpoints.UsEast1RegionID
testAccEdgeDomainNameRegion = endpoints.UsEast1RegionID
}

return testAccApigatewayEdgeDomainNameRegion
return testAccEdgeDomainNameRegion
}

// testAccCheckResourceAttrRegionalARNApigatewayEdgeDomainName ensures the Terraform state exactly matches the expected API Gateway Edge Domain Name format
func testAccCheckResourceAttrRegionalARNApigatewayEdgeDomainName(resourceName, attributeName, arnService string, domain string) resource.TestCheckFunc {
// testAccCheckResourceAttrRegionalARNEdgeDomainName ensures the Terraform state exactly matches the expected API Gateway Edge Domain Name format
func testAccCheckResourceAttrRegionalARNEdgeDomainName(resourceName, attributeName, arnService string, domain string) resource.TestCheckFunc {
return func(s *terraform.State) error {
attributeValue := arn.ARN{
Partition: acctest.Partition(),
Region: testAccGetApigatewayEdgeDomainNameRegion(),
Region: testAccGetEdgeDomainNameRegion(),
Resource: fmt.Sprintf("/domainnames/%s", domain),
Service: arnService,
}.String()
Expand All @@ -105,8 +105,8 @@ func testAccCheckResourceAttrRegionalARNApigatewayEdgeDomainName(resourceName, a
}
}

// testAccCheckResourceAttrRegionalARNApigatewayRegionalDomainName ensures the Terraform state exactly matches the expected API Gateway Regional Domain Name format
func testAccCheckResourceAttrRegionalARNApigatewayRegionalDomainName(resourceName, attributeName, arnService string, domain string) resource.TestCheckFunc {
// testAccCheckResourceAttrRegionalARNRegionalDomainName ensures the Terraform state exactly matches the expected API Gateway Regional Domain Name format
func testAccCheckResourceAttrRegionalARNRegionalDomainName(resourceName, attributeName, arnService string, domain string) resource.TestCheckFunc {
return func(s *terraform.State) error {
attributeValue := arn.ARN{
Partition: acctest.Partition(),
Expand Down
66 changes: 44 additions & 22 deletions internal/service/apigateway/domain_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,13 @@ func ResourceDomainName() *schema.Resource {
},
},

"ownership_verification_certificate_arn": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: verify.ValidARN,
},

"regional_certificate_arn": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -182,7 +189,7 @@ func resourceDomainNameCreate(d *schema.ResourceData, meta interface{}) error {

params := &apigateway.CreateDomainNameInput{
DomainName: aws.String(d.Get("domain_name").(string)),
MutualTlsAuthentication: expandApiGatewayMutualTlsAuthentication(d.Get("mutual_tls_authentication").([]interface{})),
MutualTlsAuthentication: expandMutualTLSAuthentication(d.Get("mutual_tls_authentication").([]interface{})),
}

if v, ok := d.GetOk("certificate_arn"); ok {
Expand Down Expand Up @@ -221,6 +228,10 @@ func resourceDomainNameCreate(d *schema.ResourceData, meta interface{}) error {
params.SecurityPolicy = aws.String(v.(string))
}

if v, ok := d.GetOk("ownership_verification_certificate_arn"); ok {
params.OwnershipVerificationCertificateArn = aws.String(v.(string))
}

if len(tags) > 0 {
params.Tags = Tags(tags.IgnoreAWS())
}
Expand Down Expand Up @@ -281,13 +292,14 @@ func resourceDomainNameRead(d *schema.ResourceData, meta interface{}) error {
d.Set("cloudfront_zone_id", cloudFrontRoute53ZoneID)
d.Set("domain_name", domainName.DomainName)
d.Set("security_policy", domainName.SecurityPolicy)
d.Set("ownership_verification_certificate_arn", domainName.OwnershipVerificationCertificateArn)

if err := d.Set("endpoint_configuration", flattenApiGatewayEndpointConfiguration(domainName.EndpointConfiguration)); err != nil {
return fmt.Errorf("error setting endpoint_configuration: %s", err)
}
err = d.Set("mutual_tls_authentication", flattenApiGatewayMutualTlsAuthentication(domainName.MutualTlsAuthentication))
if err != nil {
return fmt.Errorf("error setting mutual_tls_authentication: %s", err)

if err = d.Set("mutual_tls_authentication", flattenMutualTLSAuthentication(domainName.MutualTlsAuthentication)); err != nil {
return fmt.Errorf("error setting mutual_tls_authentication: %w", err)
}

d.Set("regional_certificate_arn", domainName.RegionalCertificateArn)
Expand Down Expand Up @@ -356,9 +368,9 @@ func resourceDomainNameUpdateOperations(d *schema.ResourceData) []*apigateway.Pa
}

if d.HasChange("mutual_tls_authentication") {
vMutualTlsAuthentication := d.Get("mutual_tls_authentication").([]interface{})
mutTLSAuth := d.Get("mutual_tls_authentication").([]interface{})

if len(vMutualTlsAuthentication) == 0 || vMutualTlsAuthentication[0] == nil {
if len(mutTLSAuth) == 0 || mutTLSAuth[0] == nil {
// To disable mutual TLS for a custom domain name, remove the truststore from your custom domain name.
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String(apigateway.OpReplace),
Expand All @@ -369,7 +381,7 @@ func resourceDomainNameUpdateOperations(d *schema.ResourceData) []*apigateway.Pa
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String(apigateway.OpReplace),
Path: aws.String("/mutualTlsAuthentication/truststoreVersion"),
Value: aws.String(vMutualTlsAuthentication[0].(map[string]interface{})["truststore_version"].(string)),
Value: aws.String(mutTLSAuth[0].(map[string]interface{})["truststore_version"].(string)),
})
}
}
Expand Down Expand Up @@ -419,30 +431,40 @@ func resourceDomainNameDelete(d *schema.ResourceData, meta interface{}) error {
return nil
}

func expandApiGatewayMutualTlsAuthentication(vMutualTlsAuthentication []interface{}) *apigateway.MutualTlsAuthenticationInput {
if len(vMutualTlsAuthentication) == 0 || vMutualTlsAuthentication[0] == nil {
func expandMutualTLSAuthentication(tfList []interface{}) *apigateway.MutualTlsAuthenticationInput {
if len(tfList) == 0 || tfList[0] == nil {
return nil
}
mMutualTlsAuthentication := vMutualTlsAuthentication[0].(map[string]interface{})

mutualTlsAuthentication := &apigateway.MutualTlsAuthenticationInput{
TruststoreUri: aws.String(mMutualTlsAuthentication["truststore_uri"].(string)),
tfMap := tfList[0].(map[string]interface{})

apiObject := &apigateway.MutualTlsAuthenticationInput{}

if v, ok := tfMap["truststore_uri"].(string); ok && v != "" {
apiObject.TruststoreUri = aws.String(v)
}

if vTruststoreVersion, ok := mMutualTlsAuthentication["truststore_version"].(string); ok && vTruststoreVersion != "" {
mutualTlsAuthentication.TruststoreVersion = aws.String(vTruststoreVersion)
if v, ok := tfMap["truststore_version"].(string); ok && v != "" {
apiObject.TruststoreVersion = aws.String(v)
}

return mutualTlsAuthentication
return apiObject
}

func flattenApiGatewayMutualTlsAuthentication(mutualTlsAuthentication *apigateway.MutualTlsAuthentication) []interface{} {
if mutualTlsAuthentication == nil {
return []interface{}{}
func flattenMutualTLSAuthentication(apiObject *apigateway.MutualTlsAuthentication) []interface{} {
if apiObject == nil {
return nil
}

tfMap := map[string]interface{}{}

if v := apiObject.TruststoreUri; v != nil {
tfMap["truststore_uri"] = aws.StringValue(v)
}

if v := apiObject.TruststoreVersion; v != nil {
tfMap["truststore_version"] = aws.StringValue(v)
}

return []interface{}{map[string]interface{}{
"truststore_uri": aws.StringValue(mutualTlsAuthentication.TruststoreUri),
"truststore_version": aws.StringValue(mutualTlsAuthentication.TruststoreVersion),
}}
return []interface{}{tfMap}
}
Loading