aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.65k stars 3.91k forks source link

aws-cdk: `cdk import` can't import a DyanmoDB Table #24954

Closed joehillen closed 1 year ago

joehillen commented 1 year ago

Describe the bug

This is my first time trying to import a DynamoDB Table using cdk import

Expected Behavior

It should be able to create a stack with the imported table.

Current Behavior

The import fails with the following message:

$ npx cdk import -c import_table=true
The 'cdk import' feature is currently in preview.
restore-phoenix-api-storage
restore-phoenix-api-storage/Table/Resource (AWS::DynamoDB::Table): enter TableName [undefined]: restore-phoenix-api-storage-Table-RestoreUAT_2023-04-04
restore-phoenix-api-storage: importing resources into stack...
restore-phoenix-api-storage: creating CloudFormation changeset...

 ❌  restore-phoenix-api-storage failed: Error [ValidationError]: As part of the import operation, you cannot modify or add [RoleArn]
    at Request.extractError (/home/joe/src/sbi/phx-api/node_modules/aws-cdk/lib/index.js:275:46127)
    at Request.callListeners (/home/joe/src/sbi/phx-api/node_modules/aws-cdk/lib/index.js:275:88989)
    at Request.emit (/home/joe/src/sbi/phx-api/node_modules/aws-cdk/lib/index.js:275:88437)
    at Request.emit (/home/joe/src/sbi/phx-api/node_modules/aws-cdk/lib/index.js:275:194844)
    at Request.transition (/home/joe/src/sbi/phx-api/node_modules/aws-cdk/lib/index.js:275:188396)
    at AcceptorStateMachine.runTo (/home/joe/src/sbi/phx-api/node_modules/aws-cdk/lib/index.js:275:153268)
    at /home/joe/src/sbi/phx-api/node_modules/aws-cdk/lib/index.js:275:153598
    at Request.<anonymous> (/home/joe/src/sbi/phx-api/node_modules/aws-cdk/lib/index.js:275:188688)
    at Request.<anonymous> (/home/joe/src/sbi/phx-api/node_modules/aws-cdk/lib/index.js:275:194919)
    at Request.callListeners (/home/joe/src/sbi/phx-api/node_modules/aws-cdk/lib/index.js:275:89157) {
  code: 'ValidationError',
  time: 2023-04-05T17:21:47.302Z,
  requestId: 'd62534bc-18c8-46d3-82dc-7818e8d22bf5',
  statusCode: 400,
  retryable: false,
  retryDelay: 213.46187653870373
}

As part of the import operation, you cannot modify or add [RoleArn]

It complains about a RoleArn but as you can see there is no RoleArn defined in the generated CloudFormation:

cdk synth -c import_table=true restore-phoenix-api-storage:

Resources:
  TableCD117FA1:
    Type: AWS::DynamoDB::Table
    Properties:
      KeySchema:
        - AttributeName: pk
          KeyType: HASH
        - AttributeName: sk
          KeyType: RANGE
      AttributeDefinitions:
        - AttributeName: pk
          AttributeType: S
        - AttributeName: sk
          AttributeType: S
        - AttributeName: GSI1pk
          AttributeType: S
        - AttributeName: GSI1sk
          AttributeType: S
        - AttributeName: GSI2pk
          AttributeType: S
        - AttributeName: GSI2sk
          AttributeType: S
        - AttributeName: GSI3pk
          AttributeType: S
        - AttributeName: GSI3sk
          AttributeType: S
      BillingMode: PAY_PER_REQUEST
      DeletionProtectionEnabled: false
      GlobalSecondaryIndexes:
        - IndexName: GSI1
          KeySchema:
            - AttributeName: GSI1pk
              KeyType: HASH
            - AttributeName: GSI1sk
              KeyType: RANGE
          Projection:
            ProjectionType: ALL
        - IndexName: GSI2
          KeySchema:
            - AttributeName: GSI2pk
              KeyType: HASH
            - AttributeName: GSI2sk
              KeyType: RANGE
          Projection:
            ProjectionType: ALL
        - IndexName: GSI3
          KeySchema:
            - AttributeName: GSI3pk
              KeyType: HASH
            - AttributeName: GSI3sk
              KeyType: RANGE
          Projection:
            ProjectionType: ALL
      PointInTimeRecoverySpecification:
        PointInTimeRecoveryEnabled: false
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
    Metadata:
      aws:cdk:path: restore-phoenix-api-storage/Table/Resource
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/zPSMzfSM1RMLC/WTU7J1s3JTNKrDi5JTM7WAQrFp1TmJebmpwDFQhKTclJ1nNPywIxanaDU4vzSomSwEIxdq5OXn5Kql1WsX2ZooWdoqmegmFWcmalbVJpXkpmbqhcEoQE8TzxdcwAAAA==
    Metadata:
      aws:cdk:path: restore-phoenix-api-storage/CDKMetadata/Default
Parameters:
  BootstrapVersion:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /cdk-bootstrap/hnb659fds/version
    Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
Rules:
  CheckBootstrapVersion:
    Assertions:
      - Assert:
          Fn::Not:
            - Fn::Contains:
                - - "1"
                  - "2"
                  - "3"
                  - "4"
                  - "5"
                - Ref: BootstrapVersion
        AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.

Reproduction Steps

The stack is relatively simple:

        // ==== DynamoDB ====
        const table = new Table(this, 'Table', {
            billingMode: BillingMode.PAY_PER_REQUEST,
            deletionProtection: this.isPersistentStage,
            removalPolicy,
            pointInTimeRecovery: this.isPersistentStage,
            partitionKey: {name: 'pk', type: AttributeType.STRING},
            sortKey: {name: 'sk', type: AttributeType.STRING},
        });

        table.addGlobalSecondaryIndex({
            indexName: 'GSI1',
            partitionKey: {name: 'GSI1pk', type: AttributeType.STRING},
            sortKey: {name: 'GSI1sk', type: AttributeType.STRING},
        });

        table.addGlobalSecondaryIndex({
            indexName: 'GSI2',
            partitionKey: {name: 'GSI2pk', type: AttributeType.STRING},
            sortKey: {name: 'GSI2sk', type: AttributeType.STRING},
        });

        table.addGlobalSecondaryIndex({
            indexName: 'GSI3',
            partitionKey: {name: 'GSI3pk', type: AttributeType.STRING},
            sortKey: {name: 'GSI3sk', type: AttributeType.STRING},
        });

        this.dynamoDbTable = table;

        /**
         * Import an existing table with `cdk import`
         * https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk/README.md#cdk-import
         *
         * Usage: cdk import -c import_table=true mystage-phoenix-api-storage
         *
         * CAUTION: Only use during `cdk import`
         **/
        const importTable = this.node.tryGetContext('import_table');
        if (importTable) {
            // Only the table should be created when importing an existing table.
            // This is a restriction imposed by CloudFormation's import feature.
            return;
        }

Possible Solution

The only reason I can think of the source of the RoleArn is we're using a Permissions Boundary with this (yet undocumented) feature https://github.com/aws/aws-cdk/issues/24882

Additional Information/Context

I don't have another account where I can test cdk bootstrap without a Permission Boundary, as it is enforced by our security team.

CDK CLI Version

2.72.1 (build ddbfac7)

Framework Version

No response

Node.js Version

v18.15.0

OS

Linux

Language

Typescript

Language Version

5.0.3

Other information

No response

peterwoodworth commented 1 year ago

What's the output when you run cdk diff? Is it empty?

joehillen commented 1 year ago

It's a fresh stack so there is nothing. The template posted above is entire stack.

$ cdk diff -c import_table=true
Stack restore-phoenix-api-storage
Parameters
[+] Parameter BootstrapVersion BootstrapVersion: {"Type":"AWS::SSM::Parameter::Value<String>","Default":"/cdk-bootstrap/hnb659fds/version","Description":"Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"}

Resources
[+] AWS::DynamoDB::Table Table TableCD117FA1

Other Changes
[+] Unknown Rules: {"CheckBootstrapVersion":{"Assertions":[{"Assert":{"Fn::Not":[{"Fn::Contains":[["1","2","3","4","5"],{"Ref":"BootstrapVersion"}]}]},"AssertDescription":"CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."}]}}
peterwoodworth commented 1 year ago

I reproduced the issue and fixed it, sorry for the delay in response

Run a cdk diff to make sure there are no pending changes to the CDK stack you want to import resources into. The only changes allowed in an "import" operation are the addition of new resources which you want to import.

(from here)

If you're creating a brand new stack and are only populating it with a single table, you need to deploy the brand new stack first with the table commented out. Then, run cdk import and it will work. Running import with these additional Parameter and Other changes will cause the RoleArn error

github-actions[bot] commented 1 year ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.