Skip to content

Importing existing resources into a cloudformation stack: ECR

Published: at 05:00 PM

While researching how to import existing resources into a CloudFormation stack, I noticed that most examples focused on S3 buckets. But there were rarely any about ECR (Elastic Container Registry). So, I decided write an example using ECR and share my experience.

Context

Like many developers, I started by creating AWS resources like ECR repositories and Lambda functions through the AWS Console (often called “clickops”). While this approach works initially, it quickly becomes unsustainable as your infrastructure grows. That’s why I decided to transition these manually created resources to Infrastructure as Code (IaC). While I can’t share the exact code due to company privacy policies, I’ll walk you through a simplified example that demonstrates the process.

Resource Identifiers

One important concept to understand is how CDK handles resource identifiers. CDK appends a unique identifier to the end of the logical ID of each resource. Let’s look at a simple example:

import { Stack, StackProps, aws_s3 as s3 } from 'aws-cdk-lib';
import { Construct } from 'constructs';

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

    const bucket = new s3.Bucket(this, 'MyNewBucket', {
      bucketName: 'my-existing-bucket'
    });
  }
}

This CDK code will generate a CloudFormation template that looks like this:

{
  "Resources": {
    "MyNewBucketC8B64525": {
      ...
    }
  }
}

CDK uses this resource identifier for any operations it performs on the resource. Understanding this is crucial for the import process.

Now, let’s break down the import process into manageable steps:

Create CDK Block

First, we’ll create a CDK block for our ECR repository. Note that we won’t actually deploy this - we’re just using it to generate a CloudFormation template for the import process.

import { Stack, StackProps, aws_ecr as ecr } from 'aws-cdk-lib';
import { Construct } from 'constructs';

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

    // Add the ECR repository as if creating a new one
    const repo = new ecr.Repository(this, 'ExistingRepo', {
      // replace with repo name that is to be imported
      repositoryName: 'my-existing-repo'
    });
  }
}

Generate CloudFormation Template

Running cdk synth will generate a CloudFormation template in the cdk.out directory. We’ll create a simplified version with only the necessary components:

{
  "Resources": {
    "ExistingRepoFEDAB8B5": {
      "Type": "AWS::ECR::Repository",
      "Properties": {
        "RepositoryName": "my-existing-repo"
      },
      "UpdateReplacePolicy": "Retain",
      "DeletionPolicy": "Retain",
      "Metadata": {
        "aws:cdk:path": "EcrImportStack/ExistingRepo/Resource"
      }
    }
  }
}

Import Using AWS Console

The import process in the AWS CloudFormation console is straightforward:

  1. Select “Create stack” with existing resources (import resources)
  2. Upload your simplified template file (SimplifiedEcr.template.json)
  3. Set RepositoryName to “my-existing-repo”
  4. Name your stack (e.g., “my-imported-ecr-stack”)
  5. Start the import process

Verify Import

After the import completes successfully, you should see the stack status change to IMPORT_COMPLETE. At this point, your existing ECR repository is now managed through CloudFormation!

References