amazon-web-servicesaws-cdkamazon-kms

Import existing AWS resources using CDK


Many resources are created manually in our cloud platform. How this resources can be imported and manage/update through cdk? The update on the AWS resources can be tags, status e.t.c.
I found few examples but deploying each resources using mentioned steps might take long time.

To start the migration, started with KMS keys and found there is a method fromKeyArn this return the entire details of KMS key but not sure how this can be used as template and deploy again. Sample code and output of kmsKey is below

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Tags, RemovalPolicy } from 'aws-cdk-lib';
import { Key } from 'aws-cdk-lib/aws-kms'

export class CoreAwsInfraStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    Tags.of(this).add('Environment', 'Production');
    Tags.of(this).add('Project', 'MyProject');
    const kmsKeyArn = 'arn:aws:kms:<region>:<account>:key/<kmskeyid>';
    const kmsKey = Key.fromKeyArn(this, 'ImportedKmsKey', kmsKeyArn);
    console.log("here is kms key",kmsKey)
  }
}
<ref *1> Import {
  node: Node {
    host: [Circular *1],
    _locked: false,
    _children: {},
    _context: {},
    _metadata: [],
    _dependencies: Set(0) {},
    _validations: [ [Object] ],
    id: 'ImportedKmsKey',
    scope: CoreAwsInfraStack {
      node: [Node],
      _missingContext: [],
      _stackDependencies: {},
      templateOptions: {},
      _crossRegionReferences: false,
      _suppressTemplateIndentation: false,
      _logicalIds: [LogicalIDs],
      account: '52xxxxxx',
      region: 'ap-southeast-2',
      environment: 'aws://526129xxx/ap-souxxxxx',
      _terminationProtection: false,
      _stackName: 'CoreAwsInfraStack',
      tags: [TagManager],
      artifactId: 'CoreAwsInfraStack',
      templateFile: 'CoreAwsInfraStack.template.json',
      _versionReportingEnabled: true,
      synthesizer: [DefaultStackSynthesizer],
      [Symbol(@aws-cdk/core.DependableTrait)]: [Object]
    }
  },
  stack: <ref *2> CoreAwsInfraStack {
    node: Node {
      host: [Circular *2],
      _locked: false,
      _children: [Object],
      _context: {},
      _metadata: [],
      _dependencies: Set(0) {},
      _validations: [],
      id: 'CoreAwsInfraStack',
      scope: [App]
    },
    _missingContext: [],
    _stackDependencies: {},
    templateOptions: {},
    _crossRegionReferences: false,
    _suppressTemplateIndentation: false,
    _logicalIds: LogicalIDs { renames: {}, reverse: {} },
    account: '52xxxxxx',
    region: 'ap-southeast-2',
    environment: 'aws://xxxxxx/ap-soxxxxx',
    _terminationProtection: false,
    _stackName: 'CoreAwsInfraStack',
    tags: TagManager {
      tags: Map(0) {},
      priorities: Map(0) {},
      externalTagPriority: 50,
      resourceTypeName: 'aws:cdk:stack',
      tagFormatter: KeyValueFormatter {},
      tagPropertyName: 'tags',
      didHaveInitialTags: false,
      renderedTags: [LazyAny]
    },
    artifactId: 'CoreAwsInfraStack',
    templateFile: 'CoreAwsInfraStack.template.json',
    _versionReportingEnabled: true,
    synthesizer: DefaultStackSynthesizer {
      _boundStack: [Circular *2],
      qualifier: 'hnb659fds',
      bucketName: 'xxxxx',
      repositoryName: 'xxxxxx',
      _deployRoleArn: 'arn:${AWS::Partition}:iam::xxx:role/cdk-hnb659fds-deploy-role-xxx-ap-souxxx',
      _cloudFormationExecutionRoleArn: 'arn:${AWS::Partition}:iam::xxxx:role/cdk-hnb659fds-cfn-exec-role-xxx-ap-southeast-2',
      fileAssetPublishingRoleArn: 'arn:${AWS::Partition}:iam::xxx:role/cdk-hnb659fds-file-publishing-role-xxxx-ap-xxx',
      imageAssetPublishingRoleArn: 'arn:${AWS::Partition}:iam::xxxx:role/cdk-hnb659fds-image-publishing-role-xxxxx-ap-southeast-2',
      lookupRoleArn: 'arn:${AWS::Partition}:iam::xxxx:role/cdk-hnb659fds-lookup-role-xxx-ap-soutxxx',
      bucketPrefix: '',
      dockerTagPrefix: '',
      bootstrapStackVersionSsmParameter: '/cdk-bootstrap/hnb659fds/version'
    },
    [Symbol(@aws-cdk/core.DependableTrait)]: { dependencyRoots: [Array] }
  },
  env: { account: 'xxxx', region: 'ap-sxxx' },
  _physicalName: undefined,
  _allowCrossEnvironment: false,
  physicalName: '${Token[TOKEN.9]}',
  aliases: [],
  keyArn: 'arn:aws:kms:ap-soxxx:xxx:key/a00xxxxxxx',
  policy: undefined,
  trustAccountIdentities: true,
  keyId: 'a00d1xxxx',
  [Symbol(@aws-cdk/core.DependableTrait)]: { dependencyRoots: [ [Circular *1] ] }
}


Solution

  • You can't use fromKeyArn for this.

    You use functions like fromKeyArn when you want to specify an existing key as a property for another resource in your stack, like a bucket that you'll encrypt with the key. fromKeyArn doesn't cause the key you reference to be managed by your CDK stack.

    When you say that deploying each resource using the steps in this post will take a long time, I assume you mean that figuring out the right CDK for all the resources you want to import will take a long time, not that you will run the cdk import command for one resource at a time.

    Based on the docs, you should be able to import multiple resources with one cdk import command.

    But you have to write the CDK for the existing resources first.

    For shortening the time to hand-write the CDK code for the resources you want to import, you may be able to use the IaC Generator, which is supposed to generate CloudFormation from deployed resources, and CDK Migrate.

    I'm not sure if CDK Migrate will bring resources into an existing CDK stack. If not, you could use it to generate code for a new CDK app, and then copy the resources from there into your existing CDK app.