Skip to content

Commit

Permalink
tests/resource/aws_cognito_user_pool_domain: Remove hardcoded region …
Browse files Browse the repository at this point in the history
…handling and create public ACM Certificate (#16140)

Reference: #8316
Reference: #15737

Output from acceptance testing in AWS Commercial:

```
--- PASS: TestAccAWSCognitoUserPoolDomain_custom (816.97s)
```

Output from acceptance testing in AWS GovCloud (US):

```
--- SKIP: TestAccAWSCognitoUserPoolDomain_custom (1.64s)
```
  • Loading branch information
bflad committed Nov 17, 2020
1 parent ebf0eba commit 956f615
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 48 deletions.
87 changes: 87 additions & 0 deletions aws/cognito_user_pool_domain_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package aws

import (
"context"
"sync"
"testing"

"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

// Cognito User Pool Custom Domains can only be created with ACM Certificates in specific regions.

// testAccCognitoUserPoolCustomDomainRegion is the chosen Cognito User Pool Custom Domains testing region
//
// Cached to prevent issues should multiple regions become available.
var testAccCognitoUserPoolCustomDomainRegion string

// testAccProviderCognitoUserPoolCustomDomain is the Cognito User Pool Custom Domains provider instance
//
// This Provider can be used in testing code for API calls without requiring
// the use of saving and referencing specific ProviderFactories instances.
//
// testAccPreCheckCognitoUserPoolCustomDomain(t) must be called before using this provider instance.
var testAccProviderCognitoUserPoolCustomDomain *schema.Provider

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

// testAccPreCheckCognitoUserPoolCustomDomain verifies AWS credentials and that Cognito User Pool Custom Domains is supported
func testAccPreCheckCognitoUserPoolCustomDomain(t *testing.T) {
testAccPartitionHasServicePreCheck(cognitoidentityprovider.EndpointsID, t)

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

region := testAccGetCognitoUserPoolCustomDomainRegion()

if region == "" {
t.Skip("Cognito User Pool Custom Domains not available in this AWS Partition")
}

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

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

if diags != nil && diags.HasError() {
for _, d := range diags {
if d.Severity == diag.Error {
t.Fatalf("error configuring Cognito User Pool Custom Domains provider: %s", d.Summary)
}
}
}
})
}

// testAccCognitoUserPoolCustomDomainRegionProviderConfig is the Terraform provider configuration for Cognito User Pool Custom Domains region testing
//
// Testing Cognito User Pool Custom Domains assumes no other provider configurations
// are necessary and overwrites the "aws" provider configuration.
func testAccCognitoUserPoolCustomDomainRegionProviderConfig() string {
return testAccRegionalProviderConfig(testAccGetCognitoUserPoolCustomDomainRegion())
}

// testAccGetCognitoUserPoolCustomDomainRegion returns the Cognito User Pool Custom Domains region for testing
func testAccGetCognitoUserPoolCustomDomainRegion() string {
if testAccCognitoUserPoolCustomDomainRegion != "" {
return testAccCognitoUserPoolCustomDomainRegion
}

// AWS Commercial: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-add-custom-domain.html
// AWS GovCloud (US) - not supported: https://docs.aws.amazon.com/govcloud-us/latest/UserGuide/govcloud-cog.html
// AWS China - not supported: https://docs.amazonaws.cn/en_us/aws/latest/userguide/cognito.html
switch testAccGetPartition() {
case endpoints.AwsPartitionID:
testAccCognitoUserPoolCustomDomainRegion = endpoints.UsEast1RegionID
}

return testAccCognitoUserPoolCustomDomainRegion
}
5 changes: 3 additions & 2 deletions aws/resource_aws_acm_certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,13 @@ func testAccAwsAcmCertificateDomainFromEnv(t *testing.T) string {
}

// ACM domain names cannot be longer than 64 characters
// Other resources, e.g. Cognito User Pool Domains, limit this to 63
func testAccAwsAcmCertificateRandomSubDomain(rootDomain string) string {
// Max length (64)
// Max length (63)
// Subtract "tf-acc-" prefix (7)
// Subtract "." between prefix and root domain (1)
// Subtract length of root domain
return fmt.Sprintf("tf-acc-%s.%s", acctest.RandString(56-len(rootDomain)), rootDomain)
return fmt.Sprintf("tf-acc-%s.%s", acctest.RandString(55-len(rootDomain)), rootDomain)
}

func TestAccAWSAcmCertificate_emailValidation(t *testing.T) {
Expand Down
124 changes: 80 additions & 44 deletions aws/resource_aws_cognito_user_pool_domain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"errors"
"fmt"
"log"
"os"
"regexp"
"testing"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -104,49 +104,38 @@ func TestAccAWSCognitoUserPoolDomain_basic(t *testing.T) {
}

func TestAccAWSCognitoUserPoolDomain_custom(t *testing.T) {
rootDomain := testAccAwsAcmCertificateDomainFromEnv(t)
domain := testAccAwsAcmCertificateRandomSubDomain(rootDomain)
poolName := fmt.Sprintf("tf-acc-test-pool-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
// This test must always run in us-east-1
// BadRequestException: Invalid certificate ARN: arn:aws:acm:us-west-2:123456789012:certificate/xxxxx. Certificate must be in 'us-east-1'.
oldvar := os.Getenv("AWS_DEFAULT_REGION")
os.Setenv("AWS_DEFAULT_REGION", "us-east-1")
defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

customDomainName := os.Getenv("AWS_COGNITO_USER_POOL_DOMAIN_ROOT_DOMAIN")
if customDomainName == "" {
t.Skip(
"Environment variable AWS_COGNITO_USER_POOL_DOMAIN_ROOT_DOMAIN is not set. " +
"This environment variable must be set to the fqdn of " +
"an ISSUED ACM certificate in us-east-1 to enable this test.")
}

customSubDomainName := fmt.Sprintf("%s.%s", fmt.Sprintf("tf-acc-test-domain-%d", acctest.RandInt()), customDomainName)
// For now, use an environment variable to limit running this test
certificateArn := os.Getenv("AWS_COGNITO_USER_POOL_DOMAIN_CERTIFICATE_ARN")
if certificateArn == "" {
t.Skip(
"Environment variable AWS_COGNITO_USER_POOL_DOMAIN_CERTIFICATE_ARN is not set. " +
"This environment variable must be set to the ARN of " +
"an ISSUED ACM certificate in us-east-1 to enable this test.")
}
acmCertificateResourceName := "aws_acm_certificate.test"
cognitoUserPoolResourceName := "aws_cognito_user_pool.test"
resourceName := "aws_cognito_user_pool_domain.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCognitoIdentityProvider(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSCognitoUserPoolDomainDestroy,
PreCheck: func() { testAccPreCheck(t); testAccPreCheckCognitoUserPoolCustomDomain(t) },
ProviderFactories: testAccProviderFactories,
CheckDestroy: testAccCheckAWSCognitoUserPoolDomainDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSCognitoUserPoolDomainConfig_custom(customSubDomainName, poolName, certificateArn),
Config: testAccAWSCognitoUserPoolDomainConfig_custom(rootDomain, domain, poolName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAWSCognitoUserPoolDomainExists("aws_cognito_user_pool_domain.main"),
resource.TestCheckResourceAttr("aws_cognito_user_pool_domain.main", "domain", customSubDomainName),
resource.TestCheckResourceAttr("aws_cognito_user_pool_domain.main", "certificate_arn", certificateArn),
resource.TestCheckResourceAttr("aws_cognito_user_pool.main", "name", poolName),
resource.TestCheckResourceAttrSet("aws_cognito_user_pool_domain.main", "aws_account_id"),
resource.TestCheckResourceAttrSet("aws_cognito_user_pool_domain.main", "cloudfront_distribution_arn"),
resource.TestCheckResourceAttrSet("aws_cognito_user_pool_domain.main", "s3_bucket"),
resource.TestCheckResourceAttrSet("aws_cognito_user_pool_domain.main", "version"),
testAccCheckAWSCognitoUserPoolDomainExists(resourceName),
testAccCheckResourceAttrAccountID(resourceName, "aws_account_id"),
resource.TestCheckResourceAttrPair(resourceName, "certificate_arn", acmCertificateResourceName, "arn"),
//lintignore:AWSAT001 // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/11666
resource.TestMatchResourceAttr(resourceName, "cloudfront_distribution_arn", regexp.MustCompile(`[a-z0-9]+.cloudfront.net$`)),
resource.TestCheckResourceAttrPair(resourceName, "domain", acmCertificateResourceName, "domain_name"),
resource.TestMatchResourceAttr(resourceName, "s3_bucket", regexp.MustCompile(`^.+$`)),
resource.TestCheckResourceAttrPair(resourceName, "user_pool_id", cognitoUserPoolResourceName, "id"),
resource.TestMatchResourceAttr(resourceName, "version", regexp.MustCompile(`^.+$`)),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
Expand Down Expand Up @@ -230,16 +219,63 @@ resource "aws_cognito_user_pool" "main" {
`, domainName, poolName)
}

func testAccAWSCognitoUserPoolDomainConfig_custom(customSubDomainName, poolName, certificateArn string) string {
return fmt.Sprintf(`
resource "aws_cognito_user_pool_domain" "main" {
domain = "%s"
user_pool_id = aws_cognito_user_pool.main.id
certificate_arn = "%s"
func testAccAWSCognitoUserPoolDomainConfig_custom(rootDomain string, domain string, poolName string) string {
return composeConfig(
testAccCognitoUserPoolCustomDomainRegionProviderConfig(),
fmt.Sprintf(`
data "aws_route53_zone" "test" {
name = %[1]q
private_zone = false
}
resource "aws_cognito_user_pool" "main" {
name = "%s"
resource "aws_acm_certificate" "test" {
domain_name = %[2]q
validation_method = "DNS"
}
#
# for_each acceptance testing requires:
# https://github.com/hashicorp/terraform-plugin-sdk/issues/536
#
# resource "aws_route53_record" "test" {
# for_each = {
# for dvo in aws_acm_certificate.test.domain_validation_options: dvo.domain_name => {
# name = dvo.resource_record_name
# record = dvo.resource_record_value
# type = dvo.resource_record_type
# }
# }
# allow_overwrite = true
# name = each.value.name
# records = [each.value.record]
# ttl = 60
# type = each.value.type
# zone_id = data.aws_route53_zone.test.zone_id
# }
resource "aws_route53_record" "test" {
allow_overwrite = true
name = tolist(aws_acm_certificate.test.domain_validation_options)[0].resource_record_name
records = [tolist(aws_acm_certificate.test.domain_validation_options)[0].resource_record_value]
ttl = 60
type = tolist(aws_acm_certificate.test.domain_validation_options)[0].resource_record_type
zone_id = data.aws_route53_zone.test.zone_id
}
resource "aws_acm_certificate_validation" "test" {
certificate_arn = aws_acm_certificate.test.arn
validation_record_fqdns = [aws_route53_record.test.fqdn]
}
resource "aws_cognito_user_pool" "test" {
name = %[3]q
}
resource "aws_cognito_user_pool_domain" "test" {
certificate_arn = aws_acm_certificate_validation.test.certificate_arn
domain = aws_acm_certificate.test.domain_name
user_pool_id = aws_cognito_user_pool.test.id
}
`, customSubDomainName, certificateArn, poolName)
`, rootDomain, domain, poolName))
}
2 changes: 0 additions & 2 deletions docs/MAINTAINING.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,6 @@ Environment variables (beyond standard AWS Go SDK ones) used by acceptance testi
| `AWS_API_GATEWAY_DOMAIN_NAME_REGIONAL_CERTIFICATE_NAME_ENABLED` | Flag to enable API Gateway Domain Name regional certificate upload testing. |
| `AWS_CODEBUILD_BITBUCKET_SOURCE_LOCATION` | BitBucket source URL for CodeBuild testing. CodeBuild must have access to this repository via OAuth or Source Credentials. Defaults to `https://terraform@bitbucket.org/terraform/aws-test.git`. |
| `AWS_CODEBUILD_GITHUB_SOURCE_LOCATION` | GitHub source URL for CodeBuild testing. CodeBuild must have access to this repository via OAuth or Source Credentials. Defaults to `https://github.com/hashibot-test/aws-test.git`. |
| `AWS_COGNITO_USER_POOL_DOMAIN_CERTIFICATE_ARN` | Amazon Resource Name of ACM Certificate in `us-east-1` for Cognito User Pool Domain Name testing. |
| `AWS_COGNITO_USER_POOL_DOMAIN_ROOT_DOMAIN` | Root domain name to use with Cognito User Pool Domain testing. |
| `AWS_DEFAULT_REGION` | Primary AWS region for tests. Defaults to `us-west-2`. |
| `AWS_EC2_CLASSIC_REGION` | AWS region for EC2-Classic testing. Defaults to `us-east-1` in AWS Commercial and `AWS_DEFAULT_REGION` otherwise. |
| `AWS_EC2_CLIENT_VPN_LIMIT` | Concurrency limit for Client VPN acceptance tests. [Default is 5](https://docs.aws.amazon.com/vpn/latest/clientvpn-admin/limits.html) if not specified. |
Expand Down

0 comments on commit 956f615

Please sign in to comment.