aws-cdk: DNS Validated Certificate Error: Failed to create resource. Cannot read property 'Name' of undefined

When deploying a new DNS Validated Certificate, I keep getting an error:

 26/41 | 5:34:32 PM | CREATE_FAILED        | AWS::CloudFormation::CustomResource        | sslCert/CertificateRequestorResource/Default (sslCertCertificateRequestorResource595CEBB2) Failed to create resource. Cannot read property 'Name' of undefined
	new CustomResource (/Users/rbowen/dev/git/rapticore/glass-comb/Infrastructure/cdk/node_modules/@aws-cdk/core/lib/custom-resource.ts:115:21)
	\_ new DnsValidatedCertificate (/Users/rbowen/dev/git/rapticore/glass-comb/Infrastructure/cdk/node_modules/@aws-cdk/aws-certificatemanager/lib/dns-validated-certificate.ts:96:25)
	\_ new SharedService (/Users/rbowen/dev/git/rapticore/glass-comb/Infrastructure/cdk/src/services/shared.ts:64:28)
	\_ /Users/rbowen/dev/git/rapticore/glass-comb/Infrastructure/cdk/src/index.ts:32:26
	\_ Generator.next (<anonymous>)
	\_ fulfilled (/Users/rbowen/dev/git/rapticore/glass-comb/Infrastructure/cdk/src/index.ts:6:58)
	\_ processTicksAndRejections (internal/process/task_queues.js:97:5)

Reproduction Steps

    const hostedZone = route53.HostedZone.fromLookup(scope, 'HostedZone', {
      domainName: 'foo.example.com',
    });
    const sslCertificate = new acm.DnsValidatedCertificate(this, 'sslCert', {
      domainName: 'foo.example.com',
      subjectAlternativeNames: [`*.foo.example.com`, `*.ecs.foo.example.com`],
      hostedZone,
    });

Error Log

Error log from cdk deploy:

 26/41 | 5:34:32 PM | CREATE_FAILED        | AWS::CloudFormation::CustomResource        | sslCert/CertificateRequestorResource/Default (sslCertCertificateRequestorResource595CEBB2) Failed to create resource. Cannot read property 'Name' of undefined
	new CustomResource (/Users/rbowen/dev/git/rapticore/glass-comb/Infrastructure/cdk/node_modules/@aws-cdk/core/lib/custom-resource.ts:115:21)
	\_ new DnsValidatedCertificate (/Users/rbowen/dev/git/rapticore/glass-comb/Infrastructure/cdk/node_modules/@aws-cdk/aws-certificatemanager/lib/dns-validated-certificate.ts:96:25)
	\_ new SharedService (/Users/rbowen/dev/git/rapticore/glass-comb/Infrastructure/cdk/src/services/shared.ts:64:28)
	\_ /Users/rbowen/dev/git/rapticore/glass-comb/Infrastructure/cdk/src/index.ts:32:26
	\_ Generator.next (<anonymous>)
	\_ fulfilled (/Users/rbowen/dev/git/rapticore/glass-comb/Infrastructure/cdk/src/index.ts:6:58)
	\_ processTicksAndRejections (internal/process/task_queues.js:97:5)

Error log from Custom Resource Lambda Function:

START RequestId: 95303a13-0749-445a-a0c8-d28bbb2f9300 Version: $LATEST
--
  | 2020-05-30T00:16:53.288Z 95303a13-0749-445a-a0c8-d28bbb2f9300 INFO Requesting certificate for foo.example.com
  | 2020-05-30T00:16:54.706Z 95303a13-0749-445a-a0c8-d28bbb2f9300 INFO Certificate ARN: arn:aws:acm:us-west-2:422753814403:certificate/bb2aa334-6823-4b41-ad85-776b2148179f
  | 2020-05-30T00:16:54.706Z 95303a13-0749-445a-a0c8-d28bbb2f9300 INFO Waiting for ACM to provide DNS records for validation...
  | 2020-05-30T00:16:59.198Z 95303a13-0749-445a-a0c8-d28bbb2f9300 INFO Caught error TypeError: Cannot read property 'Name' of undefined. Uploading FAILED message to S3.
  | END RequestId: 95303a13-0749-445a-a0c8-d28bbb2f9300
  | REPORT RequestId: 95303a13-0749-445a-a0c8-d28bbb2f9300 Duration: 6166.16 ms Billed Duration: 6200 ms Memory Size: 128 MB Max Memory Used: 87 MB Init Duration: 419.89 ms
  | START RequestId: 15f7c8db-a5a7-4bd5-9eb1-2b387cc7a1bf Version: $LATEST
  | 2020-05-30T00:17:22.071Z 15f7c8db-a5a7-4bd5-9eb1-2b387cc7a1bf INFO Uploading SUCCESS response to S3...
  | 2020-05-30T00:17:22.145Z 15f7c8db-a5a7-4bd5-9eb1-2b387cc7a1bf INFO Done.
  | END RequestId: 15f7c8db-a5a7-4bd5-9eb1-2b387cc7a1bf
  | REPORT RequestId: 15f7c8db-a5a7-4bd5-9eb1-2b387cc7a1bf Duration: 76.01 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 87 MB

Environment

  • CLI Version : 1.42.0 (build 3b64241)
  • Framework Version: TypeScript 3.9.3 / Node.js 14.1.0
  • OS : MacOS 10.15.4
  • Language : TypeScript

Other

I can only find two places where there’s a reference to a .Name property in the DNS Validated Certificate Lambda function:

https://github.com/aws/aws-cdk/blob/cb71f340343011a2a2de9758879a56e898b8e12c/packages/%40aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/lib/index.js#L116

https://github.com/aws/aws-cdk/blob/cb71f340343011a2a2de9758879a56e898b8e12c/packages/%40aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/lib/index.js#L137

I believe it’s the first, (dns_validated_certificate_handler/lib/index.js#L116) since the last message to appear before the error is thrown is Waiting for ACM to provide DNS records for validation....

Here’s the code in question:

  let records;
  for (let attempt = 0; attempt < maxAttempts && !records; attempt++) {
    const { Certificate } = await acm.describeCertificate({
      CertificateArn: reqCertResponse.CertificateArn
    }).promise();
    const options = Certificate.DomainValidationOptions || [];
    if (options.length > 0 && options[0].ResourceRecord) {
      // some alternative names will produce the same validation record
      // as the main domain (eg. example.com + *.example.com)
      // filtering duplicates to avoid errors with adding the same record
      // to the route53 zone twice
      const unique = options
        .map((val) => val.ResourceRecord)
        .reduce((acc, cur) => {
          acc[cur.Name] = cur;
          return acc;
        }, {});
      records = Object.keys(unique).sort().map(key => unique[key]);
    } else {
      // Exponential backoff with jitter based on 200ms base
      // component of backoff fixed to ensure minimum total wait time on
      // slow targets.
      const base = Math.pow(2, attempt);
      await sleep(random() * base * 50 + base * 150);
    }
  }

A note regarding the Certificate naming and Route53 hosted zone:

The hosted zone is a subdomain (e.g. foo.example.com - changed for anonymity), and I’m adding a few extra wildcards:

  • foo.example.com (‘DomainName’)
  • *.foo.example.com (SAN)
  • *.ecs.foo.example.com (SAN)

Here’s the generated CloudFormation Resource:

    "sslCertCertificateRequestorResource595CEBB2": {
      "Type": "AWS::CloudFormation::CustomResource",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": [
            "sslCertCertificateRequestorFunction9B246BD8",
            "Arn"
          ]
        },
        "DomainName": "foo.example.com",
        "SubjectAlternativeNames": [
          "*.foo.example.com",
          "*.ecs.foo.example.com"
        ],
        "HostedZoneId": "Z03098442SVHOB89V0UJ8"
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "rapticore-shared-dev1/sslCert/CertificateRequestorResource/Default"
      }
    },

Here’s the Certificate Object being queried over in the referenced code:

{
  CertificateArn: 'arn:aws:acm:us-west-2:xxxxxxxxxxxx:certificate/xxxxxxx-xxxx-xxxx-xxxx-c11448b8b212',
  DomainName: 'foo.example.com',
  SubjectAlternativeNames: [
    'foo.example.com',
    '*.foo.example.com',
    '*.ecs.foo.example.com'
  ],
  DomainValidationOptions: [
    {
      DomainName: 'foo.example.com',
      ValidationDomain: 'foo.example.com',
      ValidationStatus: 'PENDING_VALIDATION',
      ResourceRecord: {
        Name: '_6a2843a8394c544fd6b25e23c55b4f54.foo.example.com.',
        Type: 'CNAME',
        Value: '_19a5e04eef1d6f5abxxxxxxxxx.auiqqraehs.acm-validations.aws.'
      },
      ValidationMethod: 'DNS'
    },
    {
      DomainName: '*.foo.example.com',
      ValidationDomain: '*.foo.example.com',
      ValidationStatus: 'PENDING_VALIDATION',
      ResourceRecord: {
        Name: '_6a2843a8394c544fd6b25e23c55b4f54.foo.example.com.',
        Type: 'CNAME',
        Value: '_19a5e04eef1dxxxxxxxxxxxxxxxx.auiqqraehs.acm-validations.aws.'
      },
      ValidationMethod: 'DNS'
    },
    {
      DomainName: '*.ecs.foo.example.com',
      ValidationDomain: '*.ecs.foo.example.com',
      ValidationStatus: 'PENDING_VALIDATION',
      ResourceRecord: {
        Name: '_7b0601b191a2975acf066452963eaa76.ecs.foo.example.com.',
        Type: 'CNAME',
        Value: '_03e3b0d8b31e48fe9xxxxxxxxxxxxx.auiqqraehs.acm-validations.aws.'
      },
      ValidationMethod: 'DNS'
    }
  ],
  Subject: 'CN=foo.example.com',
  Issuer: 'Amazon',
  CreatedAt: 2020-05-30T00:34:28.000Z,
  Status: 'PENDING_VALIDATION',
  KeyAlgorithm: 'RSA-2048',
  SignatureAlgorithm: 'SHA256WITHRSA',
  InUseBy: [],
  Type: 'AMAZON_ISSUED',
  KeyUsages: [],
  ExtendedKeyUsages: [],
  RenewalEligibility: 'INELIGIBLE',
  Options: { CertificateTransparencyLoggingPreference: 'ENABLED' }
}

This is 🐛 Bug Report

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 17 (4 by maintainers)

Commits related to this issue

Most upvoted comments

This issue should be reopened. I got the same error using DnsValidatedCertificate with v1.61.0 today. I was able to get it working by switching to using Certificate with CertificateValidation.fromDns.

Similar problem with 1.63.0. Thank @mikestopcontinues for workaround solution.

From doc (https://docs.aws.amazon.com/cdk/api/latest/docs/aws-certificatemanager-readme.html) I noticed DnsValidatedCertificate is used only cross-account validation and all other examples are done Certificate and CertificationValidation.fromDns().

Reopening because customers have still been experiencing this issue

Pinging @jogold and @njlynch for awareness

I’m having this same issue with “aws-cdk”: “1.105.0”,

Same as @strottos The first time it failed and the second run it pass…

CDK version: 1.45.0 (build 0cfab15)

    // Get hosted zone
    const hostedZone = route53.HostedZone.fromLookup(this, `hosted-zone-${props.envName}`, { domainName })

    // Certificate
    const certificate = new certificatemanager.DnsValidatedCertificate(this, `certificate-${domainName}`, {
        domainName: domainName,
        hostedZone: hostedZone,
        region: props.region,
        subjectAlternativeNames: [`*.${domainName}`],
      })

I did a bit more research on this, and it turns out there’s actually two Open PR’s that aim to fix this:

  • fix(acm-certificatemanager): DnsValidatedCertificate doesn't wait long enough: #6516
  • fix(DnsValidatedCertificate): add support for subjectAlternativeNames: #7150

Unfortunately both are getting a bit stale, as both PR’s have pending, unfinished changes requested by the CDK Team. I think #6516 looks like the better PR, as it solves the root cause of the problem, rather than creating an arbitrary wait mechanism as #7150 does.