|
Starting today, Rust developers can store and access libraries (known as crates in the Rust world) in AWS CodeArtifact.
Modern software development relies heavily on pre-written code packages to speed up development. These packages, which can number in the hundreds for a single application, handle common programming tasks and can be created in-house or obtained from external sources. Although these packages can greatly help speed development, their use poses two major challenges for organizations: legal and security issues.
From a legal perspective, organizations must ensure that they have compatible licenses for these third-party packages and that they do not infringe any intellectual property rights. Security is another risk, as vulnerabilities in these packages can be exploited to compromise applications. A known tactic, supply chain attacks, is to inject vulnerabilities into popular open source projects.
To solve these problems, organizations can set up private package repositories. These repositories limit your risk of legal or security exposure by storing pre-approved packages that have been vetted by your security and legal teams. This is where CodeArtifact comes in.
AWS CodeArtifact is a fully managed artifact storage service designed to securely store, publish, and share software packages used in application development. Support for popular package managers and formats such as npm, PyPI, Maven, NuGet, SwiftPM, and Rubygem makes it easy to integrate into your existing development workflow. Enhance security and promote cross-team collaboration with access control. CodeArtifact integrates with AWS Identity and Access Management (IAM) and continuous integration and continuous deployment (CI/CD) tools to help you maintain a consistent, secure, and efficient software development lifecycle.
For the eighth year in a row, Rust has topped the charts as the “most desired programming language” in Stack Overflow’s annual developer survey, with more than 80% of developers saying they want to use the language again next year. Rust’s growing popularity stems from its ability to combine the performance and memory safety of systems languages like C++ with features that make it easier to write reliable, concurrent code. This, along with its rich ecosystem and strong focus on community collaboration, makes Rust an attractive option for developers working on high-performance systems and applications.
Rust developers use Cargo, the official package manager, to manage package dependencies. Cargo simplifies the process of finding, downloading, and integrating pre-built boxes (libraries) into your project. This not only saves time by eliminating manual dependency management, but also ensures compatibility and security. Cargo’s powerful dependency resolution system resolves potential conflicts between different crate versions, and since many crates come from a curated registry, developers can have more confidence in the quality and safety of their code. Cargo’s focus on efficiency and reliability has made it an essential tool for building Rust applications.
Let’s create a CodeArtifact repository for my box.
In this demo, we create two repositories using the AWS Command Line Interface (AWS CLI) and the AWS Management Console. Configure your first repository to download public packages from the official crates.io repository. Configure the second repository to download packages only from the first repository. This dual repository configuration is the recommended way to manage your repositories and external connections. See the CodeArtifact documentation on managing external connections. To cite a document:
“It is recommended to have one repository per domain with an external connection to a given public repository. To connect other repositories to a public repository, add the repository with the external connection as upstream.”
I sketched this diagram to illustrate the setup.
Domains and repositories can be created from the command line or console. I choose Command Line. In your shell terminal, type:
CODEARTIFACT_DOMAIN=stormacq-test
# Create an internal-facing repository: crates-io-store
aws codeartifact create-repository \
--domain $CODEARTIFACT_DOMAIN \
--repository crates-io-store
# Associate the internal-facing repository crates-io-store to the public crates-io
aws codeartifact associate-external-connection \
--domain $CODEARTIFACT_DOMAIN \
--repository crates-io-store \
--external-connection public:crates-io
# Create a second internal-facing repository: cargo-repo
# and connect it to upstream crates-io-store just created
aws codeartifact create-repository \
--domain $CODEARTIFACT_DOMAIN \
--repository cargo-repo \
--upstreams '{"repositoryName":"crates-io-store"}'
Next, as a developer, my local computer has internal storage (cargo-repo
) I just made it.
i make up cargo
Fetch libraries from internal repository instead of public crates.io. For that, I config.toml
Point the file to the CodeArtifact internal repository.
# First, I retrieve the URI of the repo
REPO_ENDPOINT=$(aws codeartifact get-repository-endpoint \
--domain $CODEARTIFACT_DOMAIN \
--repository cargo-repo \
--format cargo \
--output text)
# at this stage, REPO_ENDPOINT is https://stormacq-test-012345678912.d.codeartifact.us-west-2.amazonaws.com/cargo/cargo-repo/
# Next, I create the cargo config file
cat << EOF > ~/.cargo/config.toml
(registries.cargo-repo)
index = "sparse+$REPO_ENDPOINT"
credential-provider = "cargo:token-from-stdout aws codeartifact get-authorization-token --domain $CODEARTIFACT_DOMAIN --query authorizationToken --output text"
(registry)
default = "cargo-repo"
(source.crates-io)
replace-with = "cargo-repo"
EOF
Creating a configuration file replaces two environment variables: cargo
Your configuration does not support environment variables.
From now on, every time I call from this machine cargo
To add a box cargo
Obtain an authentication token from CodeArtifact to communicate internally. cargo-repo
Storage. You must have IAM permission to make the call. get-authorization-token
Depending on the commands I use, in addition to package read/publish permissions, I also have the CodeArtifact API. If you are running this setup on a build machine for a continuous integration (CI) pipeline, the build machine must have the appropriate permissions to do so.
You can now test this setup and add the crate to your local project.
$ cargo add regex
Updating `codeartifact` index
Adding regex v1.10.4 to dependencies
Features:
+ perf
+ perf-backtrack
+ perf-cache
+ perf-dfa
+ perf-inline
+ perf-literal
+ perf-onepass
+ std
+ unicode
+ unicode-age
+ unicode-bool
+ unicode-case
+ unicode-gencat
+ unicode-perl
+ unicode-script
+ unicode-segment
- logging
- pattern
- perf-dfa-full
- unstable
- use_std
Updating `cargo-repo` index
# Build the project to trigger the download of the crate
$ cargo build
Downloaded memchr v2.7.2 (registry `cargo-repo`)
Downloaded regex-syntax v0.8.3 (registry `cargo-repo`)
Downloaded regex v1.10.4 (registry `cargo-repo`)
Downloaded aho-corasick v1.1.3 (registry `cargo-repo`)
Downloaded regex-automata v0.4.6 (registry `cargo-repo`)
Downloaded 5 crates (1.5 MB) in 1.99s
Compiling memchr v2.7.2 (registry `cargo-repo`)
Compiling regex-syntax v0.8.3 (registry `cargo-repo`)
Compiling aho-corasick v1.1.3 (registry `cargo-repo`)
Compiling regex-automata v0.4.6 (registry `cargo-repo`)
Compiling regex v1.10.4 (registry `cargo-repo`)
Compiling hello_world v0.1.0 (/home/ec2-user/hello_world)
Finished `dev` profile (unoptimized + debuginfo) target(s) in 16.60s
You can verify that CodeArtifact has downloaded the crate and its dependencies from the upstream public repository. Connect to the CodeArtifact console and see a list of available packages in the two repositories I created. At this stage, the package list should be identical in both repositories.
Publish a private package to a repository
Now that you know that the upstream link works as intended, you can export your private package. cargo-repo
A repository that I make available to other teams in my organization.
For this we use standard Rust tools. cargo
, as usual. Before doing so, open the project file git
Storage.
$ git add . && git commit -m "initial commit"
5 files changed, 1855 insertions(+)
create mode 100644 .gitignore
create mode 100644 Cargo.lock
create mode 100644 Cargo.toml
create mode 100644 commands.sh
create mode 100644 src/main.rs
$ cargo publish
Updating `codeartifact` index
Packaging hello_world v0.1.0 (/home/ec2-user/hello_world)
Updating crates.io index
Updating `codeartifact` index
Verifying hello_world v0.1.0 (/home/ec2-user/hello_world)
Compiling libc v0.2.155
... (redacted for brevity) ....
Compiling hello_world v0.1.0 (/home/ec2-user/hello_world/target/package/hello_world-0.1.0)
Finished `dev` profile (unoptimized + debuginfo) target(s) in 1m 03s
Packaged 5 files, 44.1KiB (11.5KiB compressed)
Uploading hello_world v0.1.0 (/home/ec2-user/hello_world)
Uploaded hello_world v0.1.0 to registry `cargo-repo`
note: waiting for `hello_world v0.1.0` to be available at registry `cargo-repo`.
You may press ctrl-c to skip waiting; the crate should be available shortly.
Published hello_world v0.1.0 at registry `cargo-repo`
Finally, using the console hello_world
The box is now available in: cargo-repo
.
Pricing and Availability
You can now store Rust libraries in any of the 13 AWS Regions where CodeArtifact is available. There is no additional cost for the Rust package. The three billing dimensions are storage (measured in GB per month), number of requests, and data transfer to the Internet or another AWS Region. There is no charge for data transfer to AWS services in the same region. This means you can run continuous integration and delivery (CI/CD) jobs, for example, on Amazon Elastic Compute Cloud (Amazon EC2) or AWS CodeBuild. CodeArtifact data transfer. As usual, there are details on the pricing page.
Now build your Rust application and upload your personal box to CodeArtifact!