Automatically redeploys a Yandex Cloud Serverless Container whenever a new image tag is pushed to Container Registry.
Container Registry push
│
▼
YC Function Trigger
(one per image repo)
│
▼
Cloud Function (Go)
│
1. Resolve container ID from IMAGE_CONTAINER_MAP
2. Fetch active revision config
3. Deploy new revision with updated imageUrl
│
▼
Serverless Container
running the new image
.
├── function/ # Go source for the Cloud Function
│ ├── main.go # Handler entrypoint + helper functions
│ ├── go.mod
│ └── go.sum
└── terraform/ # Infrastructure as code
├── main.tf # Providers, archive data source
├── function.tf # yandex_function resource
├── trigger.tf # yandex_function_trigger (one per image)
├── iam.tf # Service accounts and IAM bindings
├── variables.tf # Input variable definitions
├── outputs.tf # Output values
└── terraform.tfvars.example
- Yandex Cloud CLI (
yc) - Terraform >= 1.3
- Go 1.23+ (for local builds / tests only)
- A Yandex Cloud folder with billing enabled
- An existing Container Registry
cd terraform
cp terraform.tfvars.example terraform.tfvarsEdit terraform.tfvars:
| Variable | Description |
|---|---|
folder_id |
Yandex Cloud folder ID (yc resource-manager folder list) |
registry_id |
Container Registry ID (yc container registry list) |
image_container_map |
Map of short image name → container-id (no registry_id/ prefix) |
function_name |
Cloud Function name (default: registry-deploy) |
function_memory |
Memory in MB (default: 128) |
function_timeout |
Timeout in seconds (default: 30) |
Example image_container_map:
image_container_map = {
"urlshortener" = "bba..."
"otherapp" = "bbb..."
}Keys are the bare image names (e.g.
urlshortener). Terraform prefixes them withregistry_id/when building theIMAGE_CONTAINER_MAPenv var so they match therepository_namefield in trigger events (crp.../urlshortener).
export YC_SERVICE_ACCOUNT_KEY_FILE=$(cat key.json)
terraform init
terraform plan
terraform applyTerraform will create:
- One Cloud Function (
registry-deploy) with the Go handler zipped and uploaded - One trigger per entry in
image_container_map, each scoped to its repository name - Two service accounts with minimal IAM roles:
- function-sa —
serverless-containers.editor,iam.serviceAccounts.user,vpc.user - trigger-sa —
serverless.functions.invoker(invokes the function)
- function-sa —
Add an entry to image_container_map in terraform.tfvars and re-run terraform apply. A new trigger is created automatically; no code changes needed.
| Variable | Format | Description |
|---|---|---|
IMAGE_CONTAINER_MAP |
JSON {"registry_id/repo": "container-id"} |
Auto-set by Terraform from image_container_map variable |
The service account used to run terraform apply (e.g. registry-deploy-sa) needs:
| Role | Purpose |
|---|---|
container-registry.images.puller |
Pull images from Container Registry |
functions.editor |
Create and manage Cloud Functions |
iam.serviceAccounts.admin |
Create and bind runtime service accounts |
resource-manager.admin |
Manage folder-level resources |
serverless-containers.editor |
Create and manage Serverless Containers |
serverless.functions.invoker |
Invoke Cloud Functions |
| Role | Assigned to | Purpose |
|---|---|---|
serverless-containers.editor |
<function_name>-sa |
Deploy new container revisions at runtime |
iam.serviceAccounts.user |
<function_name>-sa |
Assign the container's service account when deploying a revision |
vpc.user |
<function_name>-sa |
Attach a VPC network when the revision config carries connectivity settings |
serverless.functions.invoker |
<function_name>-trigger-sa |
Invoke the Cloud Function from the registry trigger |
cd function
go build ./...
go vet ./...The package has no
main()— Yandex Cloud Functions useHandleras the entrypoint (main.Handler).
Uncomment the backend "s3" block in terraform/main.tf and set your Object Storage bucket name to store state remotely.