avatarTeri Radichel

Summary

This context provides a step-by-step guide on how to deploy an AWS Elastic Container Registry (ECR) repository using CloudFormation, focusing on the configuration options and addressing issues related to KMS permissions.

Abstract

The provided context is a detailed guide on deploying an AWS Elastic Container Registry (ECR) repository using CloudFormation. The author begins by discussing the need to upload a container image to an Amazon ECR repository before deploying it within a Lambda function. The author then proceeds to explain the CloudFormation configuration options for an ECR repository, including encryption configuration, image scanning configuration, image tag mutability, lifecycle policy, repository name, and repository policy text.

The author also addresses an issue with KMS permissions when creating an ECR repository, which was resolved by adding a one-off condition for ECR to support the encrypt user. The context also includes the deployment of a KMS key in the Sandbox environment for use with ECR and other services.

Bullet points

  • The author explains the need to upload a container image to an Amazon ECR repository before deploying it within a Lambda function.
  • The author discusses the CloudFormation configuration options for an ECR repository, including encryption configuration, image scanning configuration, image tag mutability, lifecycle policy, repository name, and repository policy text.
  • The author addresses an issue with KMS permissions when creating an ECR repository and resolves it by adding a one-off condition for ECR to support the encrypt user.
  • The author deploys a KMS key in the Sandbox environment for use with ECR and other services.
  • The author provides code snippets and screenshots to illustrate the deployment process.

Deploy an AWS Elastic Container Registry Repository with CloudFormation

ACM.282 Creating an ECR Repository to deploy containers in Lambda functions

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

⚙️ Check out my series on Automating Cybersecurity Metrics | Code.

🔒 Related Stories: Container Security | AWS Security | Application Security

💻 Free Content on Jobs in Cybersecurity | ✉️ Sign up for the Email List

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In the last post I wrote about Container runtimes.

Then I attempted to create a custom Lambda Container Base using the Lambda Python Container Runtime and test it with the AWS Lambda Runtime Interface Emulator (RIE).

If you use a base image from AWS, the RIE is embedded into that image. I was trying to initially run the a container based on an image without the RIE embedded into it. I deployed the RIE with the appropriate architecture for my system. That didn’t work.

Then I tried to embed the image into it. I pretty much followed the instructions exactly and was using an arm architecture. I go the image to build but couldn’t get it to run. I wrote about that here:

Since I’m going to be at AWS in Seattle next week, I decided to move on. I spent way too much time on that already. I can instead create the image, which seemed to build correctly, and try to deploy it within Lambda. Maybe it will work or I’ll get some more helpful error messages so I can figure out what I’m doing wrong.

Before I can do that, I need to upload the image to an AWS Elastic Container Registry repository.

To create a Lambda function from a container image, build your image locally and upload it to an Amazon Elastic Container Registry (Amazon ECR) repository. Then, specify the repository URI when you create the function.

And before I can do that, I need to deploy an ECR repository. So that’s what I’m going to do in this post. As always, I’m going to deploy it with CloudFormation.

The image I’m going to upload is based on this AWS blog post.

Recall that I’m using an AWS EC2 instance with an arm architecture as my development environment. I covered the basics of building containers in the prior posts:

So I already have a container built and Now for the repository.

CloudFormation for an ECR Repository

Here’s the CloudFormation to deploy an Elastic Container Registry (ECR) Repository:

Let’s take a look at our configuration options:

EncryptionConfiguration: Not required.

  • Allowed values for EncryptionType are AES256 or KMS.
  • If you choose KMS for encryption type you can pass in alias, key ID, or full ARN for the KmsKey property.

I’m going to add a parameter to pass in a KMS key. We can use our standard KMS template to deploy a key as always.

This evolved over time so check all the posts on KMS and the GitHub repository for the latest.

ImageScanningConfiguration: Not Required.

  • ScanOnPush can be set to true or false.

Image scanning has some additional configuration not yet controlled by CloudFormation but hopefully coming soon. #awswishlist

I’ll allow this to be passed in but not turn on scanning for now.

ImageTagMutability: Not Required.

  • Allowed values: IMMUTABLE or MUTABLE

This setting is important in order to validate images through the whole Software Development Lifecycle (SDLC). I started to write about this in my as of yet unfinished post on testing with the Lambda RIE and will revisit it more later. For now, until we work out the process for building images, I will leave it as the default — MUTABLE. But I recommend making this setting IMMUTABLE in workflows from dev to production. To make it easier to change in the future I’ll add a parameter for this and default it to MUTABLE.

LifecyclePolicy: Not Required.

I just had an in-depth discussion on versions for containers in a security consulting call with an IANS Research client. This probably deserves a separate post. For now I will leave it off. One of the reasons I’m leaving this off is because you can deploy this policy separately from the repository.

This is another case where the policy rules should be a separate entity so you could create a list of rules for a policy, similar to my wish to be able to deploy separate policy statements for an IAM policy document. Unfortunately it also appears that you can only deploy these policies in JSON. A couple of changes for the #awswishlist.

More on Lifecycle Policies.

RepositoryName: Not Required

It’s a good idea to give your repository a name, even though not required. I really wish AWS would describe the naming convention in plain English as well as regex, which can vary by regex engine.

(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*

RepositoryPolicyText: Not Required.

This is a resource policy that allows you to define at the repository level who has access to the repository. I explained what resource policies are here:

I’m going to add a policy and allow passing in the principals as I just did in another post.

Here’s some additional information on repository policies.

Here’s the sample policy. We can replace the users with a parameter of type CommaDelimintedList.

For outputs we want to grab the ARN and RepositoryUri so we can use those later.

Deploy a KMS Key in Sandbox for use with ECR and other services

I’m going to deploy the KMS key using my existing code in this repository:

/SecurityMetricsAutomation/KMS/stacks/Key
/SecurityMetricsAutomation/KMS/stacks/KeyAlias

Because I’m just testing in my Sandbox Account I’ll add the key deployment to the SandboxKey deployment script:

/SecurityMetricsAutomation/Org/stacks/Sandbox/deploy.sh

Because I’m just testing in my Sandbox Account I’ll add the key deployment to the SandboxKey deployment script. I’m creating a generic key name because I don’t want to pay for multiple keys in the Sandbox account just for testing for anything that uses the KMS service.

For testing purposes I had to add the Sandbox environment to my KMS key template parameter:

And the associated mapping for the KMS key administrator role I created in the Sandbox Account earlier:

Really I just want all my keys in the KMSAdmin account for the most part but for now this works.

I test that key deployment and it works.

Issue with KMS permissions when creating an ECR Repository

Now as it turns out I had an issue trying to deploy the ECR repository. I used my SandboxAdmin that has full permission to the Sandbox account to create the repository. I got this error saying the SandboxAdmin does not have kms:CreateGrant permissions:

SandboxAdmin is not authorized to perform: kms:CreateGrant on resource: [key ARN]

*sigh* ~ nothing can just be simple.

The problem is that I made the SandboxAdmin an administrator of the key by way of a role:

arn:aws:iam::xxxxxxxxxxxx:role/KMSAdminsGroup

However, that role does not also have permission to deploy an ECR repository.

But I am not sure I like this implementation. The deployment and assignment of the Key and Granting KMS Key permissions should be independent of deploying an ECR Repository. The principal deploying the repository should not need permission to administer the key, only use the key. Hmm.

Anyway I have to do a one-off condition for ECR to support this via the encrypt user, I guess. Turns out I had to do the same for EC2 so I just copied that and changed 2 to R:

I wasn’t sure if this was going to work but it let me deploy the repository. Whether it actually works when we try to upload a container image is another matter we’ll have to address later if it doesn’t work.

I adde the service as an allowed service:

Deploy the ECR repository

Next I created a new directory for ECR deployment code.

/SecurityMetricsAutomation/AppSec/stacks/ECR

Within that directory I create the usual files:

deploy.sh
ecr_functions.sh
cfn/ECR.yaml

The CloudFormation Template:

The function to deploy the template in ecr_functions.sh:

Next I have to add a new directory to my change_dir function to support ECR.

Recall this function is in this file for now.

/SecurityMetricsAutomation/Functions/assume_role.sh

I add these lines:

As a reminder this function allows me to switch to a directory containing some code and source the files in it.

Back over in my sandbox deploy.sh file I can:

  • Change to the ECR directory and source the functions file.
  • Define the repo name
  • Obtain the KMS key id from the alias
  • Reuse the principals list I created for the encryption key
  • Pass in the parameters to deploy the ECR repository using the new function.

Here’s the deploy script code.

As per usual, the majority of my time was spent resolving KMS key issues even though we have a standard KMS key template. I’m thinking there should be a way to streamline the somewhat duplicated code for ECR and EC2 but going to move on for now.

Update: I realized at some point that I was missing something in regards to services that use KMS keys versus keys that users use with AWS services. Two different things. I fixed that in another post. I’m not sure if ECR actually requires the permission or the user requires the permission so I’ll retest with the new key policy as I continue with the series.

Follow for updates.

Teri Radichel | © 2nd Sight Lab 2023

About Teri Radichel:
~~~~~~~~~~~~~~~~~~~~
⭐️ Author: Cybersecurity Books
⭐️ Presentations: Presentations by Teri Radichel
⭐️ Recognition: SANS Award, AWS Security Hero, IANS Faculty
⭐️ Certifications: SANS ~ GSE 240
⭐️ Education: BA Business, Master of Software Engineering, Master of Infosec
⭐️ Company: Penetration Tests, Assessments, Phone Consulting ~ 2nd Sight Lab
Need Help With Cybersecurity, Cloud, or Application Security?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
🔒 Request a penetration test or security assessment
🔒 Schedule a consulting call
🔒 Cybersecurity Speaker for Presentation
Follow for more stories like this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
❤️ Sign Up my Medium Email List
❤️ Twitter: @teriradichel
❤️ LinkedIn: https://www.linkedin.com/in/teriradichel
❤️ Mastodon: @teriradichel@infosec.exchange
❤️ Facebook: 2nd Sight Lab
❤️ YouTube: @2ndsightlab
Ecr
Cloudformation
Container
Lambda
Kms
Recommended from ReadMedium