如何通过Terraform安全更新管理自身的AWS CodePipeline?
我们用Terraform在AWS CodeCommit仓库管理所有AWS资源,其中包含负责部署Terraform变更的CodePipeline。现在想通过修改Terraform代码,在不依赖自动化流程外的手动terraform apply操作的前提下,安全更新这条流水线本身?
根据AWS官方文档说明:
若修改流水线时有版本正在运行,该运行将无法完成。
当前流水线的流程是:Source步骤(拉取仓库内容)后,部署阶段为:
plan(CodeBuild)->人工审核->apply(CodeBuild)
以下是最简buildspec配置:
Plan阶段
version: 0.2 phases: install: on-failure: ABORT commands: - . scripts/aws_utils.sh && install_terraform build: on-failure: ABORT commands: - terraform init -input=false - terraform plan -out tfplan -input=false -var-file=terraform.tfvars artifacts: files: - '**/*'
Apply阶段
version: 0.2 phases: install: on-failure: ABORT commands: # Fetched during the plan step - cp terraform /usr/bin/terraform && terraform -version build: on-failure: ABORT commands: - terraform apply -auto-approve -input=false tfplan
(注:install_terraform仅用于拉取并解压Terraform二进制文件)
现在需要找到修改流水线自身的计划与应用方法,避免使用开发者本地执行Terraform这类带外操作(目前暂时用的是这个方案)。
要实现流水线自我更新且完全依赖内部自动化流程,核心是避免更新操作打断正在运行的流水线任务,同时确保变更能安全执行,可按以下方案调整:
1. 在Plan阶段前置流水线运行状态检查
修改Plan阶段的buildspec,在生成Terraform计划前,检查当前流水线是否有正在运行的执行实例。如果存在,直接终止本次Plan任务,防止后续apply操作打断活跃任务:
version: 0.2 phases: install: on-failure: ABORT commands: - . scripts/aws_utils.sh && install_terraform build: on-failure: ABORT commands: # 新增:检查是否有正在运行的流水线实例 - | RUNNING_EXECUTIONS=$(aws codepipeline list-pipeline-executions --pipeline-name YOUR_PIPELINE_NAME --query 'pipelineExecutionSummaries[?status==`InProgress`].pipelineExecutionId' --output text) if [ -n "$RUNNING_EXECUTIONS" ]; then echo "检测到正在运行的流水线实例:$RUNNING_EXECUTIONS,为避免中断任务,终止本次计划生成。" exit 1 fi - terraform init -input=false - terraform plan -out tfplan -input=false -var-file=terraform.tfvars artifacts: files: - '**/*'
注意:需确保CodeBuild的服务角色拥有codepipeline:ListPipelineExecutions权限。
2. 在Apply阶段追加二次检查
为避免Plan到Apply期间有新的流水线实例启动,在Apply阶段执行变更前再次检查运行状态,双重保障:
version: 0.2 phases: install: on-failure: ABORT commands: - cp terraform /usr/bin/terraform && terraform -version build: on-failure: ABORT commands: # 新增:二次检查运行中的流水线实例 - | RUNNING_EXECUTIONS=$(aws codepipeline list-pipeline-executions --pipeline-name YOUR_PIPELINE_NAME --query 'pipelineExecutionSummaries[?status==`InProgress`].pipelineExecutionId' --output text) if [ -n "$RUNNING_EXECUTIONS" ]; then echo "检测到正在运行的流水线实例,终止本次变更执行。" exit 1 fi - terraform apply -auto-approve -input=false tfplan
3. 配置CodeBuild角色权限
确保执行Terraform的CodeBuild服务角色拥有修改CodePipeline的权限,需添加以下IAM权限(按需调整资源范围):
{ "Effect": "Allow", "Action": [ "codepipeline:UpdatePipeline", "codepipeline:ListPipelineExecutions", "codepipeline:GetPipeline" ], "Resource": "arn:aws:codepipeline:REGION:ACCOUNT_ID:pipeline/YOUR_PIPELINE_NAME" }
4. 验证流程
- 修改流水线的Terraform配置(比如调整阶段超时时间、修改BuildSpec引用),提交到CodeCommit。
- 流水线自动触发后,Plan阶段会先检查运行状态,无活跃实例则生成变更计划。
- 人工审核环节重点确认变更内容为流水线自身修改,确认无误后放行。
- Apply阶段再次检查状态,确认无冲突后执行变更,完成流水线自我更新。
- 后续流水线运行将直接使用更新后的配置,全程无需本地手动执行
terraform apply。
内容的提问来源于stack exchange,提问作者STerliakov

