我在 CodePipeline 中使用 ECS 容器和 CodeBuild 和 CodeDeploy(用于蓝/绿部署)阶段。我在应用程序代码的根目录中有一个 appspec.yml 文件,其中包含任务定义 arn 和容器名称。所有这些在单一环境场景中运行良好。在我的情况下,当我有一个单独的用于开发、测试和生产的 AWS 账户时,我需要 CodeDeploy 来根据环境上下文交换任务定义 arn。有没有办法像我们为 buildspec.yml 文件和自定义环境变量一样传递参数和修改 appspec.yml 文件?如果不是,那么使用 appspec.yml 文件进行跨账户部署的最佳解决方案是什么?
更新
感谢 Ronan Cunningham 的 Python 脚本——请参见下面的代码示例——它允许生成 appspec.json 文件作为 CodeBuild 阶段的工件并将其作为输入传递给 CodeDeploy 阶段。您可以从 buildspec.yml 文件调用脚本并将自定义环境变量作为脚本参数传递,这将根据 AWS 环境上下文定义您的 appspec.json。该脚本应与 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('Writing {}:'.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')
从 buildspec.yml 调用脚本并将环境变量作为参数传递。
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