新手求助:用Terraform和GitHub Action创建ACR并实现旧镜像清理
以下是用Terraform创建Azure Container Registry(ACR)并通过GitHub Action实现旧镜像清理的完整方案,适合新手上手:
使用Terraform创建Azure Container Registry(ACR)
先通过Terraform定义ACR的基础配置,包含可选的内置保留策略(仅Standard/Premium SKU支持):
# 指定Azure Provider版本 terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "~> 3.0" } } } # 初始化Azure Provider provider "azurerm" { features {} } # 创建ACR所属的资源组 resource "azurerm_resource_group" "acr_rg" { name = "acr-resource-group" location = "eastus" # 替换为你需要的区域 } # 创建Azure Container Registry resource "azurerm_container_registry" "acr" { name = "myuniqueacr001" # 必须全局唯一,建议加个人前缀 resource_group_name = azurerm_resource_group.acr_rg.name location = azurerm_resource_group.acr_rg.location sku = "Standard" # 标准版支持内置保留策略,满足新手需求 admin_enabled = false # 禁用管理员账户,用服务主体授权更安全 # 可选:启用内置保留策略,自动删除指定天数前的未标记镜像 retention_policy { enabled = true days = 7 # 保留7天内的未标记镜像,自动删除更早的 } } # 输出ACR登录服务器地址,后续GitHub Action会用到 output "acr_login_server" { value = azurerm_container_registry.acr.login_server }
部署步骤
- 安装Terraform并通过
az login完成Azure CLI登录 - 在Terraform文件目录执行:
terraform init terraform plan terraform apply
使用GitHub Action实现ACR旧镜像清理
如果内置保留策略不够灵活(比如需要清理标记镜像、按数量保留),可以用GitHub Action自定义清理逻辑。
前置准备
- 创建Azure服务主体,赋予ACR的
AcrDelete和AcrPull权限:az ad sp create-for-rbac --name "acr-cleanup-sp" --role "AcrDelete" --scopes /subscriptions/<你的订阅ID>/resourceGroups/acr-resource-group/providers/Microsoft.ContainerRegistry/registries/myuniqueacr001 - 将服务主体的
appId、password、tenant以及订阅ID存入GitHub仓库的Secrets,命名为:AZURE_CLIENT_ID(对应appId)AZURE_CLIENT_SECRET(对应password)AZURE_TENANT_ID(对应tenant)AZURE_SUBSCRIPTION_ID
GitHub Action 工作流示例
创建.github/workflows/acr-cleanup.yml文件:
name: ACR Old Image Cleanup on: schedule: - cron: '0 0 * * 0' # 每周日凌晨0点执行(UTC时间) workflow_dispatch: # 允许手动触发清理 jobs: cleanup-images: runs-on: ubuntu-latest steps: - name: Login to Azure uses: azure/login@v1 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} client-secret: ${{ secrets.AZURE_CLIENT_SECRET }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - name: Cleanup untagged images older than 7 days run: | # 获取所有未标记镜像的清单摘要,筛选7天前的 az acr repository show-manifests --name myuniqueacr001 --repository my-app-image --filter "untagged" --orderby time_desc --output json | \ jq -r 'select(.timestamp | fromdateiso8601 < (now - 7*86400)) | .digest' | \ while read digest; do echo "Deleting untagged image: myuniqueacr001.azurecr.io/my-app-image@$digest" az acr repository delete --name myuniqueacr001 --image my-app-image@$digest --yes done - name: Cleanup tagged images (keep latest 5 versions) run: | # 假设镜像标签为v1.0.0、v2.1.0这类语义化版本,保留最新5个 az acr repository show-tags --name myuniqueacr001 --repository my-app-image --orderby time_desc --output json | \ jq -r '.[5:] | .[]' | \ while read tag; do echo "Deleting tagged image: myuniqueacr001.azurecr.io/my-app-image:$tag" az acr repository delete --name myuniqueacr001 --image my-app-image:$tag --yes done
优化建议
- 先做Dry Run:在正式删除前,将
az acr repository delete命令替换为echo,确认要删除的镜像列表无误后再执行实际删除。 - 使用变量:将ACR名称、保留天数、保留数量定义为GitHub仓库变量(比如
ACR_NAME、RETENTION_DAYS),避免硬编码。 - 权限最小化:服务主体仅赋予
AcrDelete和AcrPull权限,不要使用过高权限的角色。 - 结合内置策略:如果只需要清理未标记镜像,直接用Terraform配置的ACR内置保留策略即可,无需编写自定义脚本,更省心。
内容的提问来源于stack exchange,提问作者pawan kumar
相关产品推荐
相关产品推荐

