{"id":50825545,"url":"https://github.com/sshaplygin/redeploy-container-yc","last_synced_at":"2026-06-13T18:39:43.057Z","repository":{"id":341306221,"uuid":"1169621390","full_name":"sshaplygin/redeploy-container-yc","owner":"sshaplygin","description":"Automatically redeploys a Yandex Cloud Serverless Container whenever a new image tag is pushed to Container Registry","archived":false,"fork":false,"pushed_at":"2026-03-01T01:36:44.000Z","size":11,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-01T05:41:37.083Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sshaplygin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-01T00:28:14.000Z","updated_at":"2026-03-01T01:36:48.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sshaplygin/redeploy-container-yc","commit_stats":null,"previous_names":["sshaplygin/redeploy-container-yc"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/sshaplygin/redeploy-container-yc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaplygin%2Fredeploy-container-yc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaplygin%2Fredeploy-container-yc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaplygin%2Fredeploy-container-yc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaplygin%2Fredeploy-container-yc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sshaplygin","download_url":"https://codeload.github.com/sshaplygin/redeploy-container-yc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaplygin%2Fredeploy-container-yc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34296382,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-13T18:39:42.404Z","updated_at":"2026-06-13T18:39:43.052Z","avatar_url":"https://github.com/sshaplygin.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# redeploy-container-yc\n\nAutomatically redeploys a Yandex Cloud Serverless Container whenever a new image tag is pushed to Container Registry.\n\n## How it works\n\n```\nContainer Registry push\n        │\n        ▼\n  YC Function Trigger\n  (one per image repo)\n        │\n        ▼\n  Cloud Function (Go)\n        │\n   1. Resolve container ID from IMAGE_CONTAINER_MAP\n   2. Fetch active revision config\n   3. Deploy new revision with updated imageUrl\n        │\n        ▼\n  Serverless Container\n  running the new image\n```\n\n## Repository layout\n\n```\n.\n├── function/          # Go source for the Cloud Function\n│   ├── main.go        # Handler entrypoint + helper functions\n│   ├── go.mod\n│   └── go.sum\n└── terraform/         # Infrastructure as code\n    ├── main.tf        # Providers, archive data source\n    ├── function.tf    # yandex_function resource\n    ├── trigger.tf     # yandex_function_trigger (one per image)\n    ├── iam.tf         # Service accounts and IAM bindings\n    ├── variables.tf   # Input variable definitions\n    ├── outputs.tf     # Output values\n    └── terraform.tfvars.example\n```\n\n## Prerequisites\n\n- [Yandex Cloud CLI (`yc`)](https://yandex.cloud/docs/cli/)\n- [Terraform \u003e= 1.3](https://developer.hashicorp.com/terraform/install)\n- [Go 1.23+](https://go.dev/dl/) (for local builds / tests only)\n- A Yandex Cloud folder with billing enabled\n- An existing Container Registry\n\n## Deployment\n\n### 1. Configure variables\n\n```bash\ncd terraform\ncp terraform.tfvars.example terraform.tfvars\n```\n\nEdit `terraform.tfvars`:\n\n| Variable | Description |\n|---|---|\n| `folder_id` | Yandex Cloud folder ID (`yc resource-manager folder list`) |\n| `registry_id` | Container Registry ID (`yc container registry list`) |\n| `image_container_map` | Map of short image name → container-id (**no** `registry_id/` prefix) |\n| `function_name` | Cloud Function name (default: `registry-deploy`) |\n| `function_memory` | Memory in MB (default: `128`) |\n| `function_timeout` | Timeout in seconds (default: `30`) |\n\nExample `image_container_map`:\n\n```hcl\nimage_container_map = {\n  \"urlshortener\" = \"bba...\"\n  \"otherapp\"     = \"bbb...\"\n}\n```\n\n\u003e Keys are the bare image names (e.g. `urlshortener`). Terraform prefixes them\n\u003e with `registry_id/` when building the `IMAGE_CONTAINER_MAP` env var so they\n\u003e match the `repository_name` field in trigger events (`crp.../urlshortener`).\n\n### 2. Apply\n\n```bash\nexport YC_SERVICE_ACCOUNT_KEY_FILE=$(cat key.json)\n\nterraform init\nterraform plan\nterraform apply\n```\n\nTerraform will create:\n\n- One Cloud Function (`registry-deploy`) with the Go handler zipped and uploaded\n- One trigger per entry in `image_container_map`, each scoped to its repository name\n- Two service accounts with minimal IAM roles:\n  - **function-sa** — `serverless-containers.editor`, `iam.serviceAccounts.user`, `vpc.user`\n  - **trigger-sa** — `serverless.functions.invoker` (invokes the function)\n\n### 3. Adding a new container\n\nAdd an entry to `image_container_map` in `terraform.tfvars` and re-run `terraform apply`. A new trigger is created automatically; no code changes needed.\n\n## Function environment variable\n\n| Variable              | Format                                        | Description                                              |\n|-----------------------|-----------------------------------------------|----------------------------------------------------------|\n| `IMAGE_CONTAINER_MAP` | JSON `{\"registry_id/repo\": \"container-id\"}`   | Auto-set by Terraform from `image_container_map` variable|\n\n## IAM roles required\n\n### Terraform deployer service account\n\nThe service account used to run `terraform apply` (e.g. `registry-deploy-sa`) needs:\n\n| Role | Purpose |\n|---|---|\n| `container-registry.images.puller` | Pull images from Container Registry |\n| `functions.editor` | Create and manage Cloud Functions |\n| `iam.serviceAccounts.admin` | Create and bind runtime service accounts |\n| `resource-manager.admin` | Manage folder-level resources |\n| `serverless-containers.editor` | Create and manage Serverless Containers |\n| `serverless.functions.invoker` | Invoke Cloud Functions |\n\n### Runtime service accounts (created by Terraform)\n\n| Role | Assigned to | Purpose |\n|---|---|---|\n| `serverless-containers.editor` | `\u003cfunction_name\u003e-sa` | Deploy new container revisions at runtime |\n| `iam.serviceAccounts.user` | `\u003cfunction_name\u003e-sa` | Assign the container's service account when deploying a revision |\n| `vpc.user` | `\u003cfunction_name\u003e-sa` | Attach a VPC network when the revision config carries connectivity settings |\n| `serverless.functions.invoker` | `\u003cfunction_name\u003e-trigger-sa` | Invoke the Cloud Function from the registry trigger |\n\n## Local development\n\n```bash\ncd function\ngo build ./...\ngo vet ./...\n```\n\n\u003e The package has no `main()` — Yandex Cloud Functions use `Handler` as the entrypoint (`main.Handler`).\n\n## Optional: remote Terraform state\n\nUncomment the `backend \"s3\"` block in [terraform/main.tf](terraform/main.tf) and set your Object Storage bucket name to store state remotely.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshaplygin%2Fredeploy-container-yc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsshaplygin%2Fredeploy-container-yc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshaplygin%2Fredeploy-container-yc/lists"}