1
0
Fork 0
mirror of https://github.com/imjasonh/terraform-playground synced 2026-07-08 07:44:57 +00:00

also set up Chainguard puller identity

Signed-off-by: Jason Hall <jason@chainguard.dev>
This commit is contained in:
Jason Hall 2023-06-23 09:19:09 -04:00
parent 2015ec0edf
commit 201548b75a
Failed to extract signature
4 changed files with 70 additions and 3 deletions

View file

@ -9,5 +9,8 @@ jobs:
test-image:
runs-on: ubuntu-latest
steps:
- uses: chainguard-dev/actions/setup-chainctl@main
with:
identity: 7bf08061e47a927f78ffa39cd6393f4a83ec6eb7/aa8f8890af6747f9
- run: |
echo ding ding testing ${{ github.event.inputs.image }}
docker pull ${{ github.event.inputs.image }}

View file

@ -2,6 +2,10 @@
This sets up a Cloud Run app to listen for `registry.push` events to a private Chainguard Registry group, and triggers a GitHub Actions workflow with that image ref as an input.
This lets you define GitHub Actions workflows to pull and test images in response to pushes.
# Usage
To start, create a GitHub workflow at `.github/workflows/workflow.yaml`, with an input named `image`:
```
@ -16,12 +20,17 @@ jobs:
test-image:
runs-on: ubuntu-latest
steps:
# This sets up auth with the registry to be able to pull the image.
- uses: chainguard-dev/actions/setup-chainctl@main
with:
identity: TODO # We'll fill this in later.
- run: |
# Your tests go here.
echo ding ding testing ${{ github.event.inputs.image }}
docker pull ${{ github.event.inputs.image }}
```
Then Terraform apply the module (e.g., from the root of this repo):
Then `terraform apply` the module (e.g., from the root of this repo):
```
module "image-workflow" {
@ -52,6 +61,8 @@ module "image-workflow" {
}
```
## Setting your GitHub Personal Access Token
Once things have been provisioned, this module outputs a `secret-command`
containing the command to run to upload your Github "personal access token" to
the Google Secret Manager secret the application will use, looking something
@ -63,3 +74,9 @@ echo -n YOUR GITHUB PAT | \
```
The personal access token needs `actions:write` to trigger workflows.
## Setting your puller identity
The module also outputs the identity that was created, which can be assumed by the
GitHub Actions workflow. This is the value that goes in the `setup-chainctl` step
of your workflow above.

View file

@ -7,14 +7,20 @@ terraform {
}
}
provider "ko" {
repo = "gcr.io/${var.project_id}/${var.name}-image-workflow"
}
provider "google" {
project = var.project_id
}
# Create a service account to run the service, with access to the GitHub PAT secret.
resource "google_service_account" "image-workflow" {
account_id = "${var.name}-image-workflow"
}
# Create a secret to hold the GitHub personal access token.
resource "google_secret_manager_secret" "gh-pat" {
project = var.project_id
secret_id = "${var.name}-github-pat"
@ -23,6 +29,9 @@ resource "google_secret_manager_secret" "gh-pat" {
}
}
# Create the initial secret version, which will let the service start up.
# After the infrastructure is provisioned, the secret-command output will
# show you how to populate the secret.
resource "google_secret_manager_secret_version" "initial-secret-version" {
secret = google_secret_manager_secret.gh-pat.id
@ -36,12 +45,14 @@ resource "google_secret_manager_secret_version" "initial-secret-version" {
}
}
# Grant the service account access to read the secret.
resource "google_secret_manager_secret_iam_member" "grant-secret-access" {
secret_id = google_secret_manager_secret.gh-pat.id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.image-workflow.email}"
}
# Verify the base image is signed by the expected identity.
data "cosign_verify" "base-image" {
image = "cgr.dev/chainguard/static:latest-glibc"
@ -71,11 +82,13 @@ data "cosign_verify" "base-image" {
})
}
# Build the app into a container image.
resource "ko_build" "image" {
importpath = "github.com/imjasonh/terraform-playground/image-workflow/cmd/app"
working_dir = path.module
}
# Deploy the service, running as the Service Account, with the GitHub PAT as a secret env var.
resource "google_cloud_run_service" "image-workflow" {
name = "${var.name}-image-workflow"
location = var.location
@ -119,6 +132,7 @@ resource "google_cloud_run_service" "image-workflow" {
}
}
# Look up the IAM policy for "allUsers" to allow anyone to invoke the service.
data "google_iam_policy" "noauth" {
binding {
role = "roles/run.invoker"
@ -128,6 +142,7 @@ data "google_iam_policy" "noauth" {
}
}
# Allow anyone to invoke the service.
resource "google_cloud_run_service_iam_policy" "noauth" {
location = google_cloud_run_service.image-workflow.location
service = google_cloud_run_service.image-workflow.name
@ -140,3 +155,30 @@ resource "chainguard_subscription" "subscription" {
parent_id = var.group
sink = google_cloud_run_service.image-workflow.status[0].url
}
# Create an identity that can be assumed by the GitHub workflow.
resource "chainguard_identity" "puller" {
parent_id = var.group
name = "${var.name}-image-workflow image puller"
description = <<EOF
This is an identity that authorizes the workflow in the
GitHub repo to pull from the Chainguard Registry, to test it.
EOF
claim_match {
issuer = "https://token.actions.githubusercontent.com"
subject = "repo:${var.github_org}/${var.github_repo}:ref:refs/heads/main"
}
}
# Look up the registry.push role to grant the actions identity below.
data "chainguard_roles" "registry-pull" {
name = "registry.pull"
}
# Grant the actions identity the "registry.pull" role on the group.
resource "chainguard_rolebinding" "private-pusher-is-public-puller" {
identity = chainguard_identity.puller.id
group = var.group
role = data.chainguard_roles.registry-pull.items[0].id
}

View file

@ -6,3 +6,8 @@ output "secret-command" {
description = "gcloud secrets command to upload the github personal access token."
value = format("echo -n YOUR GITHUB PAT | gcloud --project %s secrets versions add %s --data-file=-", var.project_id, google_secret_manager_secret.gh-pat.secret_id)
}
output "identity" {
description = "The identity that can be assumed by the GitHub workflow."
value = chainguard_identity.puller.id
}