Mirror new Images to Google Artifact Registry with Chainguard CloudEvents
Certain interactions with Chainguard resources will emit CloudEvents that you or an application can subscribe to. This allows you to do things like receive alerts when a user downloads one or more of your organization’s private Images or when a new Image gets added to your organization’s registry.
This tutorial is meant to serve as a companion to the Image Copy GCP example application. It will guide you through setting up infrastructure to listen for push
events on an organization’s private registry and mirror any new Chainguard Images in the registry to a repository in a GCP Artifact Registry repository.
Prerequisites
To follow along with this guide, it is assumed that you have the following set up and ready to use.
- A verified Chainguard organization with a private Registry and access to Production Images.
chainctl
, the Chainguard command-line interface. You can install this by following our guide on How to Installchainctl
.terraform
to configure a Google Cloud service account, IAM permissions, and deploy the Cloud Run service.- A Google Cloud account with a project running. The example application assumes that your project has the following APIs enabled:
- The
gcloud
CLI installed on your local machine. You’ll need this to authenticate to Google Cloud over the command line.
Setting up the Terraform configuration
You can find all the code associated with this sample application in our Platform Examples repository on GitHub.
To set up the sample application, you can create a Terraform configuration file and apply it to set up the necessary resources. To begin, create a new directory to hold the configuration and navigate into it.
mkdir ~/gcp-example && cd $_
After navigating into the new directory you can begin creating a Terraform configuration named main.tf
.
This configuration will consist of a single module. For the purposes of this example, we will call it image-copy
. This module’s source
value will be the iac
folder from the application code in the examples repository.
module "image-copy" {
source = "github.com/chainguard-dev/platform-examples/image-copy-gcp/iac"
The next five lines configure a few variables that you will need to update to reflect your own setup.
- First, the configuration defines a
name
value. This will be used to prefix resources created by this sample application where possible. - Next, it specifies the GCP project ID where certain resources will reside, including the container image for this application (along with mirrored images), the Cloud Run service hosting the application, and the Service Account that authorizes pushes to the Google Artifact Registry.
- Following that, the configuration specifies the Chainguard IAM organization from which we expect to receive events. This is used to authenticate that the Chainguard events are intended for you, and not another user. Images pushed to repositories under this organization will be mirrored to Artifact Registry.
- If you don’t know your organization’s UIDP, you can retrieve it by running
chainctl iam organizations list -o table
.
- If you don’t know your organization’s UIDP, you can retrieve it by running
- The next line specifies the location of the Artifact Registry repository and the Cloud Run subscriber.
- The final line defines
dst_repo
value, which is used to create a name for the repository in the Artifact Registry where images will be mirrored.
As an example, if the name
value you specify is chainguard-dev
and the dst_repo
value is mirrored
(as shown in the following example) any pushes to cgr.dev/<organization>/foo
will be mirrored to <location>-docker.pkg.dev/<project_id>/chainguard-dev-mirrored
Be sure to include to include a closing curly bracket after the final line.
name = "chainguard-dev"
project_id = "<project-id>"
group = "<organization-id>"
location = "us-central1"
dst_repo = "mirrored"
}
You can create this file with a command like the following.
cat > main.tf <<EOF
module "image-copy" {
source = "github.com/chainguard-dev/platform-examples/image-copy-gcp/iac"
name = "chainguard-dev"
project_id = "<project-id>"
group = "<organization-id>"
location = "us-central1"
dst_repo = "mirrored"
}
EOF
Make sure to replace the placeholders with your own settings for project_id
and group
. In the next section, we’ll see how to apply the configuration to get the application up and running.
Applying the configuration
The Terraform configuration you created in the previous section will do all the work of setting up an events subscription for you.
Specifically, it will build the mirroring application into an image using ko_build
and deploy the app to a Cloud Run service with permission to push to the Google Artifact Registry. It also sets up a Chainguard Identity with permissions to pull from the private cgr.dev
repository, allows the Cloud Run service’s service account to assume the puller identity, and sets up a subscription to notify the Cloud Run service when pushes happen to cgr.dev
.
Before applying the configuration, you’ll need to log in to both the Chainguard platform with chainctl
and GCP with gcloud
.
chainctl auth login
gcloud auth login
If you haven’t already done so, you will also need to acquire new access credentials to use as Application Default Credentials. You can do so with this command.
gcloud auth application-default login
Following that, run terraform init
to initialize Terraform’s working directory.
terraform init
Then run terraform plan
. This will produce a speculative execution plan that outlines what steps Terraform will take to create the resources defined in the file you set up in the last section.
terraform plan
If the plan worked successfully and you’re satisfied that it will produce the resources you expect, you can apply it.
terraform apply
Before going through with applying the Terraform configuration, this command will prompt you to confirm that you want it to do so. Enter yes
to apply the configuration.
. . .
Plan: 8 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
. . .
Apply complete! Resources: 8 added, 0 changed, 0 destroyed.
Assuming all the resources were created as expected, you can observe the application in action.
Testing the application
If the terraform apply
command you ran in the previous section was successful, the Terraform configuration will have set up a Cloud Run service to host the example application.
As mentioned previously, this application listens for registry.push
events that occur on your organization’s repository; any time a new Image gets added to your organization’s Registry the application will mirror it to your GCP project’s Artifact Registry and into a repository named with the name
and dst_repo
values you set in your main.tf
file. For example, if these values were chainguard-dev
and mirrored
, respectively, (as shown in the previous example) the mirror repository would be found at <location>-docker.pkg.dev/<project_id>/chainguard-dev-mirrored
.
You can find the results of the application in your GCP Project’s dashboard. Navigate to your GCP Project’s Artifact Registry, then click on the mirror repository you set up with Terraform. There, you will find any Images that have been added to your organization’s Registry since you deployed the application. This example shows a repository named chainguard-dev-mirrored
with two Images (node
and python
) mirrored into it.
Be aware that just because the application is listening for registry.push
events doesn’t mean any will occur automatically. Chainguard Images are generally updated at least once every twenty four hours, so Images may not immediately appear in your mirror repository.
Removing sample resources
If you’d like to remove the resources you created with Terraform, you can run the terraform destroy
command.
terraform destroy
This will destroy everything created in your Terraform configuration, including the Artifact Registry repository, the Service Account, and the Cloud Run service.
You can then remove the working directory to clean up your system.
rm -r ~/gcp-example/
Following that, all of the example resources created in this guide will be removed from your system.
Learn more
Chainguard emits more CloudEvents than just the registry:push
events highlighted in this guide. We encourage you to check out our overview of Chainguard Events to learn the full breadth of event types that Chainguard generates. In addition, you may find it useful to explore the rest of our Administration resources to better understand how you can work with Chainguard’s products.
Last updated: 2024-05-24 15:22