AWS CodeArtifact enables you to store your custom packages or fetch packages from public package registries and use them in your software development process. If you use AWS CodeBuild to build your code, you can make CodeBuild retrieve the packages required for your build or test commands from your CodeArtifact repository on AWS instead of public Internet registries.
In this post, I will introduce you to AWS CodeArtifact and provide an example of using it with AWS CodeBuild to build an Angular application.
What is AWS CodeArtifact?
AWS CodeArtifact is a serverless package management service provided by AWS. It helps you store, publish, and share software packages using popular package management tools like npm, pip, Maven, RubyGems, etc. You can store your custom packages or packages from language-native public registries in your CodeArtifact repositories.
Why use AWS CodeArtifact?
If you need a central package management solution, maintaining and scaling your own system is costly, time-consuming, and challenging. Instead, you can use AWS CodeArtifact to let AWS manage it for you.
AWS CodeArtifact is serverless. It is hosted on Amazon S3 and DynamoDB tables. Not only does CodeArtifact free you from the server management burden, but it also redundantly stores your repository data in multiple AZs and automatically scales your repositories based on demand theoretically without limits. Hence, AWS CodeArtifact provides durability and high availability out of the box.
It is cost-effective. You only pay for the storage used, the number of requests made, and data transferred out of an AWS region. Besides, the AWS free tier provides 2GB of storage and 100,000 requests per month for free.
It is secure. The data is encrypted at rest with KMS keys, which can be customer-managed or AWS-managed. The data in transit is encrypted with TLS encryption. You use IAM roles and resource policies on your CodeArtifact repositories to control who can access them.
It is integrated with CloudTrail, so you can log who accessed and when for each action taken on your CodeArtifact repositories.
You can create a single CodeArtifact domain within your AWS organization and share it with multiple AWS accounts as a central location for your packages.
Then, what are CodeArtifact domains and repositories? So, let’s continue with AWS CodeArtifact’s primary concepts.
AWS CodeArtifact – Primary concepts
Asset
The individual files representing packages are called assets
in CodeArtifact. It is what you download and store when you fetch a package from a package management service. For example, ‘package.tgz’ files in npm packages are CodeArtifact assets.
Package
A package represents a bundle of software with its dependencies. When you install a package, you actually install a package version, which consists of a version number, such as ‘1.5.2’, a metadata and a set of assets.
Repository
A CodeArtifact repository is the primary place to store and fetch packages on CodeArtifact. It is a set of package versions from the same or different package registries. For example, you can install packages from npm or PyPi in the same CodeArtifact repository.
If a repository has packages accessed from a second repository, it becomes an upstream repository. For example, if your CodeArtifact repository has package versions from npm, CodeArtifact creates a special repository to download packages from npm
. This npm repository becomes an upstream repository, and your repository becomes a downstream.
Domain
Finally, domains are top-level CodeArtifact constructs that group and manage multiple repositories. You define external and internal repositories in CodeArtifact domains and access them through your domains.
Domains also allow you to use organization policies to share your repositories between your AWS accounts. For example, you can create a CodeArtifact domain for your production environment in an AWS account in your AWS organization and use it as the central domain for your software packages in other AWS accounts. So your teams can access them easily.
All package versions are stored in CodeArtifact domains. For example, if two repositories in your domain reference the same package version, only one copy of the package asset is stored in the domain. It doesn’t matter how many repositories reference it. This avoids unnecessary duplicates in your domain.
What is AWS CodeBuild?
AWS CodeBuild is a fully managed and serverless continuous integration service. With CodeBuild, you can build and test your code from your source Git repository hosted on GitHub, GitHub Enterprise, Bitbucket, GitLab, or GitLab self-managed. It also supports AWS CodeCommit, but AWS deprecated it in July 2024.
I won’t dive into the details of AWS CodeBuild in this post. If you want to learn AWS CodeBuild, you’re welcome to join my AWS CodePipeline Step by Step course. Now, let’s continue with using AWS CodeArtifact with AWS CodeBuild.
How do you use AWS CodeArtifact repositories in a CodeBuild project?
There are a few common steps for using AWS CodeArtifact:
1) You create a CodeAritfact domain and a repository.
2) You assign necessary IAM permissions to the IAM identity, which will store packages to or download packages from your CodeArtifact repository.
3) You log in to your CodeArtifact repository using AWS CLI. The documentation refers to it as CodeArtifact CLI, but you install it with AWS CLI, and its usage is similar to that of other commands. So, I will refer to it as AWS CLI.
4) You publish your package or install a package using language-native tools such as npm publish
or npm install
, respectively.
Step 1 - Preparing your CodeArifact domain and repository
To begin with, you create a CodeArtifact domain that will host all your CodeArtifact repositories and package versions.
In the example below, I create a CodeArtifact domain named my-demo-domain
.
Then, you create a new repository in your CodeArtifact domain
and choose its upstream repositories from the popular central package registries.
Your repository must be created in a CodeArtifact domain. If you don’t yet have a domain, you can create it while creating your repository on the CodeArtifact Console. However, you can create a repository in an existing domain by clicking the ‘Create repository’ button, as shown below.
In the example below, I create a repository named my-demo-repository
in the my-demo-domain
created before. Although our sample project only needs npm-store (JavaScript)
to install the required Node packages, I also added PyPi (Python)
, RubyGems (Ruby)
, and Maven Central Repository (Java)
registries as upstream repositories to my repository as an example.
These are repositories with external connections, and CodeArtifact uses them to store package versions from the Internet. Because they are defined as upstream
for your repository, it can also access their packages. However, you can store your own packages in your repository directly.
On the review page, CodeArtifact shows the upstream and downstream repositories with a nice diagram.
In this diagram, the maven-central-store
, rubygems-store
, npm-store
, and pypi-store
repositories were added as upstream
repositories. my-demo-repository
is a downstream
repository that automatically has access to the package versions in them.
After the creation, your CodeArtifact domain will have five repositories as below.
At the beginning, your CodeArtifact repository doesn’t have any packages.
Angular applications use Node packages. So, during the build, we expect CodeBuild to fetch some Node packages from npm
and store them in the npm-store
repository. However, the npm-store
repository on CodeArtifact is empty beforehand.
So, let’s see what happens after integrating it with AWS CodeBuild running a build.
Step 2 – Creating your CodeBuild project
This part is almost the same as using AWS CodeBuild without CodeArtifact. Your CodeBuild project’s source can be any of the source repositories supported. It can also be a part of a CodePipeline build action, which you can learn in my AWS CodePipeline Step by Step course on Udemy.
In the example for this blog post, I use a buildspec file to build an Angular application. I won’t embed the CodeArtifact domain and repository names or AWS account ID in the buildspec file. Instead, I recommend using environment variables. So, in the example below, I create these environment variables in my CodeBuild project:
CODEARTIFACT_DOMAIN: The name of your CodeArtifact domain. In my example, it is ‘my-demo-domain’.
CODEARTIFACT_REPO: The name of your CodeArtifact repository, which is ‘my-demo-repository’ in my example.
CODEARTIFACT_OWNER: The AWS account ID of the owner of the repository. It will be my account ID, but it can also be from a different AWS account whose repository is configured for cross-account access.
The environment variables on CodeBuild look like the image below. You can learn to use environment variables in CodeBuild from my previous post about the subject.
Step 3 – Granting your CodeBuild project necessary permissions
Your CodeBuild project won’t have permission to access CodeArtifact after the creation. So, you should provide permission to log in to CodeArtifact and access your CodeArtifact domain and repositories in its IAM service role.
You can create a customer-managed IAM policy with the permissions below.
Then, you should assign it to your CodeBuild project’s IAM role.
Step 4 – Adding CodeArtifact login command to your buildspec file
In CodeBuild, you provide the commands to build or test your code in your buildspecs. A buildspec consists of these optional phases in the order they are executed: install, pre_build, build, and post_build.
Usually, the pre_build phase is where you log in to central repositories, such as DockerHub or Amazon ECR. However, in the install phase before pre_build, you may also install global packages in your CodeBuild environment, such as Angular CLI. So, the place of your CodeArtifact login command depends on your buildspec file’s structure.
In my sample buildspec below, I install Angular CLI in the install phase and the project dependencies in the pre_build phase. Then, I build the Angular project in the build phase.
If I place the CodeArtifact in the pre_build phase, the npm install command for Angular CLI in the install phase will still fetch the package from the central npm registry. But I also want CodeBuild to fetch it from CodeArtifact. So, either I would move the Angular CLI installation to the pre_build phase or place the CodeArtifact login before it.
I chose the second option. You can see the final buildspec file below.
Because the build execution logs in to CodeArtifact before all npm install commands, all required Node packages will be stored in the CodeArtifact domain first. Then, they will be installed from CodeArtifact into the CodeBuild environment.
If you joined my AWS CodePipeline Step by Step course, you are already familiar with the ‘aws ecr get-login’ command. The ‘codeartifact login’ command works similarly. It returns an authentication token to be used by the Node package manager (npm) in the HTTP Authorization header while logging in to CodeArtifact.
The Result of the Build
After executing the build project, you will have these in your logs and CodeArtifact repositories.
The CodeBuild logs
After running the build, you will see a build log for the successful login similar to the one below. Please note the build log after the CodeArtifact login command.
The authorization token returned by the ‘codeartifact login’ command provided 12 hours of access, which was much more than needed for my CodeBuild project execution.
The CodeArtifact repositories after the build
After the build, you will see your CodeArtifact repository with new package versions.
Actually, these are from the upstream npm-store repository in your CodeArtifact domain.
CodeArtifact automatically fetches all dependencies from your package.json file in your Node or Angular project. But if your project continues to use the same package versions, CodeArtifact will not fetch those unless you delete them. If your project references a new version, CodeArtifact will fetch it in the subsequent build execution.
Would you like to learn to use AWS CodeBuild with AWS CodePipeline?
If you want to learn to use AWS CodeBuild in your CI/CD pipelines, my AWS CodePipeline Step by Step course on Udemy may be helpful.
In this course, you will learn to use AWS CodePipeline to build CI/CD pipelines on AWS step by step to build your applications with CodeBuild and deploy them to S3 or EC2. You will also learn to create Docker images with CodeBuild and deploy Docker containers from them to Amazon ECS with CodePipeline. We cover many CodeBuild features in detail in my Udemy bestseller
course.
The links in this post also provides a special discount for you. You can view all my courses on our Courses page.
Conclusion
AWS CodeArtifact provides a feasible and efficient central package management solution for your software development processes. In this post, I provided an example of using AWS CodeArtifact with your CodeBuild projects.
If you found it helpful, please also share it on your LinkedIn profile or X (Twitter) account to help me reach others like you.
Follow me on LinkedIn and X (Twitter) to hear about my future online courses or blog posts.
Thanks for reading!
References
- AWS CodeArtifact Concepts - AWS CodeArtifact Docs
- Using npm packages in CodeBuild - AWS CodeArtifact Docs
- Phases - AWS CodeBuild Buildspec Reference
- AWS CodeArtifact Pricing