
GCP Artifact Registry Для GitHub Организации (Часть 1)
Сегодня я хотел бы описать как использовать GCP “Workload Identity Federation” чтобы безопасно пушить докер образы из GitHub Actions CI в GCP Artifact Registry
Этот пост что-то типа туториала для тех у кого есть организация в github.com, но по какой-то причине желающих хранить докер-образы в GCP Artifact Registry (например чтобы ускорить пул внутри GCP)
Итак, что у нас есть и чего мы хотим достичь?
Дано:
- организация в github.com, скажем
mnacharov-eu
- GCP проект, скажем
mnacharov-eu-docker
Цель:
- Иметь закрытый GCP Artifact Registry репозиторий для каждого GitHub.com репозитория в нашей организации
- Иметь возможность пушить докер образы из GitHub Actions CI в закрытый GCP Artifact Registry репозиторий без необходимости добавлять секреты в github репозиторий
- Простота управления доступами пользователей к GCP Artifact Registry репозиториям
Авторизуем GitHubCI джобы в GCP с короткоживущими токенами
Начнём с простых вещей: авторизации с помощью Workload Identity Federation. Эта возможность должна быть использована в ваших GitHub CI пайплайнах!
Если вы когда нибудь использовали достаточно популярный способ авторизации github actions CI в google cloud - экшен
google google-github-actions/auth, вы должны были заметить что рекомендуемый способ использования это
“Direct Workload Identity Federation”. Инструкции по его настройки там достаточно хорошие, но
на случай если вам хочется иметь terraform
описание, вот мой конфиг:
variable "github_organization" {
description = "The GitHub organization for the attribute condition."
default = "mnacharov-eu"
}
resource "google_iam_workload_identity_pool" "github_pool" {
project = var.project_id
workload_identity_pool_id = "github-com"
display_name = "GitHub identity pool"
}
resource "google_iam_workload_identity_pool_provider" "github_mnacharov-eu_repos" {
project = var.project_id
display_name = "GitHub for mnacharov-eu repos"
workload_identity_pool_id = google_iam_workload_identity_pool.github_pool.workload_identity_pool_id
workload_identity_pool_provider_id = "mnacharov-eu"
attribute_mapping = {
"google.subject" = "assertion.sub"
"attribute.repository" = "assertion.repository"
"attribute.repository_owner" = "assertion.repository_owner"
}
# Condition: specific github organization
attribute_condition = <<EOT
assertion.repository_owner == '${var.github_organization}'
EOT
oidc {
issuer_uri = "https://token.actions.githubusercontent.com"
}
}
после этого я могу авторизовать любой github actions пайплайн из моей гитхаб организации в google. Но как назначить пермишены на пуш образов в Artifact Registry? Это может выглядеть как-то так:
locals {
github_repos = [
"push-to-gcp",
]
}
resource "google_artifact_registry_repository" "registries" {
for_each = toset(local.github_repos)
repository_id = each.value
description = "github.com/mnacharov-eu/${each.value} images"
format = "DOCKER"
location = var.region
project = var.project_id
docker_config {
immutable_tags = true
}
cleanup_policies {
id = "keep-release-images"
action = "KEEP"
condition {
tag_state = "TAGGED"
tag_prefixes = ["v"]
}
}
cleanup_policies {
id = "delete-untagged"
action = "DELETE"
condition {
tag_state = "UNTAGGED"
older_than = "86400s" # 1 day
}
}
cleanup_policies {
id = "delete after 30d"
action = "DELETE"
condition {
older_than = "2592000s" # 30 days
}
}
}
resource "google_artifact_registry_repository_iam_member" "allow_to_push_from_github" {
for_each = toset(local.github_repos)
project = var.project_id
location = google_artifact_registry_repository.registries[each.value].location
repository = google_artifact_registry_repository.registries[each.value].name
role = "roles/artifactregistry.writer"
member = "principalSet://iam.googleapis.com/projects/${var.project_number}/locations/global/workloadIdentityPools/github-com/attribute.repository/mnacharov-eu/${each.value}"
}
таким образом, для github actions пайплайна из репозитория mnacharov-eu/push-to-gcp
будет доступен пуш докер образа
в закрытый Artifact Registry europe-docker.pkg.dev/mnacharov-eu-docker/push-to-gcp
.
Давайте попробуем провеить его в простом пайплайне:
on:
schedule:
- cron: '26 4 * * 4'
push:
branches:
- main
tags:
- 'v*'
env:
REGISTRY: europe-docker.pkg.dev
jobs:
docker-build:
runs-on: ubuntu-latest
permissions:
contents: 'read'
id-token: 'write'
steps:
- uses: 'actions/checkout@v4'
- uses: 'google-github-actions/auth@v2'
with:
project_id: 'mnacharov-eu-docker'
workload_identity_provider: 'projects/152460024713/locations/global/workloadIdentityPools/github-com/providers/mnacharov-eu'
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: europe-docker.pkg.dev/mnacharov-eu-docker/push-to-gcp/main
flavor: |
latest=false
tags: |
type=semver,pattern={{version}}
type=sha,enable=${{ github.ref == format('refs/heads/{0}', 'main') && github.event.schedule == null }}
type=raw,enable=${{ github.event.schedule != null }},value={{date 'cron-YY-MM-DD'}}
- name: Configure GC docker
run: |
gcloud auth configure-docker europe-docker.pkg.dev
- name: Build & Push Airflow
uses: docker/build-push-action@v6
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
и это работает, вот тут можно найти как выглядит лог билда https://github.com/mnacharov-eu/push-to-gcp/actions
Вот и всё на сегодня
Итак, у нас уже есть безопасный способ авторизоваться и запушить образы в Artifact Registry из GitHub Actions CI, но всего для одного репозитория
В следующий раз я расширю этот подход чтобы иметь Artifact Registry репозиторий со всеми необходимыми доступами сразу после создания нового GitHub.com репозитория! До скорого…