多AWS账号下CodePipeline ECS蓝绿部署的appspec.yml动态配置问题
问题解答
核心结论
原生appspec.yml不支持类似buildspec.yml的内置自定义环境变量注入能力,无法直接通过参数替换修改固定写死的任务定义ARN等配置。跨账号多环境场景下的最佳实践是在CodeBuild阶段根据当前环境上下文动态生成appspec文件,作为构建产物传递给后续的CodeDeploy阶段使用。
具体实现方案
该方案通过Python脚本接收环境变量参数,自动生成对应环境的appspec.json文件,无需提前写死各个环境的配置值:
1. 前置准备
将create_appspec_json.py脚本放在应用根目录,和buildspec.yml、Dockerfile同级存放。
create_appspec_json.py 代码
#!/usr/bin/python import json from sys import argv def print_obj_to_disk(obj, file_type): if file_type == 'app_spec': file_name = 'appspec.json' if file_type == 'task_def': file_name = 'taskdef.json' print('正在写入 {}:'.format(file_name)) print(obj) print(json.dumps(obj, indent=2)) with open(file_name, 'w') as outfile: json.dump(obj, outfile, indent=2) def return_appspec(container_name, container_port, task_definition_arn): appsec_obj = { "version": 0.0, "Resources": [ { "TargetService": { "Type": "AWS::ECS::Service", "Properties": { "TaskDefinition": task_definition_arn, "LoadBalancerInfo": { "ContainerName": container_name, "ContainerPort": container_port }, } } } ] } return appsec_obj appspec_obj = return_appspec(argv[1], argv[2], argv[3]) print_obj_to_disk(appspec_obj, 'app_spec')
2. buildspec.yml配置
在CodeBuild的构建配置中,提前为不同环境的流水线配置对应的环境变量:CONTAINER_NAME、CONTAINER_PORT、TASK_DEFINITION_ARN,然后修改buildspec.yml调用脚本生成appspec文件,并将其设为构建产物:
artifacts: files: - appspec.json phases: install: commands: - pip install boto3 build: commands: - python create_appspec_json.py $CONTAINER_NAME $CONTAINER_PORT $TASK_DEFINITION_ARN # 其余构建逻辑保留 post_build: commands: # 其余后置构建逻辑保留 pre_build: commands: # 其余前置构建逻辑保留 version: 0.2
3. 流水线配置
后续CodeDeploy阶段直接读取CodeBuild输出的构建产物中的appspec.json即可,无需再使用代码库中固定的appspec.yml文件。不同账号对应不同流水线/不同环境参数的场景下,会自动生成匹配当前环境的appspec配置,实现跨账号部署。
内容的提问来源于stack exchange,提问作者GGG
相关产品推荐
相关产品推荐

