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

Hosted Zone NameServers & Nested Stack Output Not a String #33208

Open
1 task
aubsamai opened this issue Jan 28, 2025 · 3 comments
Open
1 task

Hosted Zone NameServers & Nested Stack Output Not a String #33208

aubsamai opened this issue Jan 28, 2025 · 3 comments
Labels
@aws-cdk/core Related to core CDK functionality bug This issue is a bug. effort/small Small work item – less than a day of effort p1

Comments

@aubsamai
Copy link

aubsamai commented Jan 28, 2025

Describe the bug

Scenario:

  • Parent and nested stack.
  • The parent and nested stack each contain a HostedZone.
  • The nested stack contains a a hosted zone which is a subdomain of a hosted zone in the parent stack.\
  • Performing delegation between the parent and subdomain hosted zones.

Issue:

When deploying this change the following error occurs:

HostedZoneCdkTestStack-NestedStackNestedStackNestedStackNestedStackResourceB70834FD-DK2CLX636OMC | 1/5 | 1:34:36 AM | CREATE_FAILED        | AWS::CloudFormation::Stack | HostedZoneCdkTestStack-NestedStackNestedStackNestedStackNestedStackResourceB70834FD-DK2CLX636OMC Template format error: Every Value member must be a string.
HostedZoneCdkTestStack | 1/5 | 1:34:40 AM | CREATE_FAILED        | AWS::CloudFormation::Stack | NestedStack.NestedStack/NestedStack.NestedStackResource (NestedStackNestedStackNestedStackNestedStackResourceB70834FD) Embedded stack arn:aws:cloudformation:us-east-1:651706759746:stack/HostedZoneCdkTestStack-NestedStackNestedStackNestedStackNestedStackResourceB70834FD-DK2CLX636OMC/f490a510-dd5a-11ef-97cb-0e87fe3d5aad was not successfully created: Template format error: Every Value member must be a string.
H

Related past issue: #22846

Regression Issue

  • Select this option if this issue appears to be a regression.

Last Known Working CDK Version

No response

Expected Behavior

CDK generated CloudFormation Output should be valid for a NameServer in a nested stack.

Current Behavior

NestedStack.NestedStack/NestedStack.NestedStackResource (NestedStackNestedStackNestedStackNestedStackResourceB70834FD) Embedded stack arn:aws:cloudformation:us-east-1:651706759746:stack/HostedZoneCdkTestStack-NestedStackNestedStackNestedStackNestedStackResourceB70834FD-DK2CLX636OMC/f490a510-dd5a-11ef-97cb-0e87fe3d5aad was not successfully created: Template format error: Every Value member must be a string.

Reproduction Steps

import * as cdk from 'aws-cdk-lib';
import { NestedStack } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { PublicHostedZone } from "aws-cdk-lib/aws-route53";

export class HostedZoneCdkTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const parentHostedZone = new PublicHostedZone(this, "ParentHostedZone", {
      zoneName: "parent-hosted-zone.com"
    });

    const nestedStack = new NestedStack(this, "NestedStack");
    const subdomainHostedZoneInNestedStack = new PublicHostedZone(nestedStack, "NestedStackHostedZone", {
      zoneName: "nested.parent-hosted-zone.com",
    });
    parentHostedZone.addDelegation(subdomainHostedZoneInNestedStack);
  }
}

CDK Output for the Nested Stack

{
 "Resources": {
  "NestedStackHostedZone787B1110": {
   "Type": "AWS::Route53::HostedZone",
   "Properties": {
    "Name": "nested.parent-hosted-zone.com."
   },
   "Metadata": {
    "aws:cdk:path": "HostedZoneCdkTestStack/NestedStack/NestedStackHostedZone/Resource"
   }
  },
  "CDKMetadata": {
    ...
  }
 },
 "Conditions": {
  ...
 },
 "Outputs": {
  "HostedZoneCdkTestStackNestedStackNestedStackHostedZoneEEBF045ENameServers": {
   "Value": {
    "Fn::GetAtt": [
     "NestedStackHostedZone787B1110",
     "NameServers"
    ]
   }
  }
 }
}

The NameServer delegation in the CloudFormation output in the nested stack is not identified as a string which is causing the error. This output is generated by CDK.

CDK Version: 2.177.0

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.177.0 (build b396961)

Framework Version

No response

Node.js Version

v22.7.0

OS

MacOS 14.6.1

Language

TypeScript

Language Version

No response

Other information

No response

@aubsamai aubsamai added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jan 28, 2025
@github-actions github-actions bot added the @aws-cdk/core Related to core CDK functionality label Jan 28, 2025
@ashishdhingra
Copy link
Contributor

@aubsamai Good morning. Could you please share the complete CDK code which includes NestedStack as well. Looking at the CFN output in issue description, it appears that CfnOutput is created for NestedStackHostedZone787B1110 > NameServers. hostedZoneNameServers is a string[]. CfnOutput only supports string which is the limitation of CloudFormation. As a workaround, you could export string list in nested stack using Stack.exportStringListValue() and use the import in the parent stack. exportStringListValue() support was added as part of PR #22873 for issue #21682.

Thanks,
Ashish

@ashishdhingra ashishdhingra added p2 response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed needs-triage This issue or PR still needs to be triaged. labels Jan 28, 2025
@aubsamai
Copy link
Author

aubsamai commented Jan 28, 2025 via email

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Jan 28, 2025
@ashishdhingra
Copy link
Contributor

Using the below CDK code:

import * as cdk from 'aws-cdk-lib';
import * as route53 from "aws-cdk-lib/aws-route53";

export class CdktestStackNew extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const parentHostedZone = new route53.PublicHostedZone(this, "ParentHostedZone", {
      zoneName: "parent-hosted-zone.com"
    });

    const nestedStack = new cdk.NestedStack(this, "NestedStack");
    const subdomainHostedZoneInNestedStack = new route53.PublicHostedZone(nestedStack, "NestedStackHostedZone", {
      zoneName: "nested.parent-hosted-zone.com",
    });
    parentHostedZone.addDelegation(subdomainHostedZoneInNestedStack);
  }
}

generates the below CloudFormation template:

Resources:
  ParentHostedZoneC2BD86E1:
    Type: AWS::Route53::HostedZone
    Properties:
      Name: parent-hosted-zone.com.
    Metadata:
      aws:cdk:path: CdktestStackNew/ParentHostedZone/Resource
  ParentHostedZoneparenthostedzonecomnestedparenthostedzonecom6CB48059:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneId:
        Ref: ParentHostedZoneC2BD86E1
      Name: nested.parent-hosted-zone.com.
      ResourceRecords:
        Fn::GetAtt:
          - NestedStackNestedStackNestedStackNestedStackResourceB70834FD
          - Outputs.CdktestStackNewNestedStackNestedStackHostedZoneDA4D61A4NameServers
      TTL: "172800"
      Type: NS
    Metadata:
      aws:cdk:path: CdktestStackNew/ParentHostedZone/parent-hosted-zone.com -> nested.parent-hosted-zone.com/Resource
  NestedStackNestedStackNestedStackNestedStackResourceB70834FD:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL:
        Fn::Join:
          - ""
          - - https://s3.us-east-2.
            - Ref: AWS::URLSuffix
            - /cdk-hnb659fds-assets-139480602983-us-east-2/dcc43473be1d9a3b6db62bc98c7bc0c6566b958a2a99666ee4213b8c768c7fb6.json
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
    Metadata:
      aws:cdk:path: CdktestStackNew/NestedStack.NestedStack/NestedStack.NestedStackResource
      aws:asset:path: CdktestStackNewNestedStack0D3B3725.nested.template.json
      aws:asset:property: TemplateURL
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/02MsQ7CMBBDv6V7crQFVHYYGFG7saA0OVDakJNyCR2q/jsKWVhsP8tyC03XQV2phaU2s3R2hHWISs9CLfwIlCIe97De0uisvhJHNHfyKM5P/0dZLujwpaIl36OmYPKkpAHjlqn8/mqmFDRuwpNBmHj3aU7Q1nCoJrZWhuSjfSP0xb/FzucQpQAAAA==
    Metadata:
      aws:cdk:path: CdktestStackNew/CDKMetadata/Default

For below resource:

...
  ParentHostedZoneparenthostedzonecomnestedparenthostedzonecom6CB48059:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneId:
        Ref: ParentHostedZoneC2BD86E1
      Name: nested.parent-hosted-zone.com.
      ResourceRecords:
        Fn::GetAtt:
          - NestedStackNestedStackNestedStackNestedStackResourceB70834FD
          - Outputs.CdktestStackNewNestedStackNestedStackHostedZoneDA4D61A4NameServers
      TTL: "172800"
      Type: NS
    Metadata:
      aws:cdk:path: CdktestStackNew/ParentHostedZone/parent-hosted-zone.com -> nested.parent-hosted-zone.com/Resource

the ResourceRecords is using Fn::GetAtt to get Outputs.CdktestStackNewNestedStackNestedStackHostedZoneDA4D61A4NameServers from nested stack NestedStackNestedStackNestedStackNestedStackResourceB70834FD. This reference is added due to call to addDelegation() which adds reference to delegate.hostedZoneNameServers! here.

Output might not be prevented from automatically generated since the code here explicitly accesses delegate.hostedZoneNameServers!.

Marking the issue as p1 since there might not be any workaround.

@ashishdhingra ashishdhingra added p1 effort/small Small work item – less than a day of effort and removed p2 labels Jan 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/core Related to core CDK functionality bug This issue is a bug. effort/small Small work item – less than a day of effort p1
Projects
None yet
Development

No branches or pull requests

2 participants