首页 > 解决方案 > 在启动模板用户数据脚本中使用 CDK 部署时间令牌值

问题描述

我最近开始将部分基础设施移植到 AWS CDK。之前,我直接用 Cloudformation 模板做了一些实验。

我目前面临的问题是,我想在 EC2 启动模板的用户数据脚本中编码一些值(即产品版本),并且这些值只能在部署时加载。使用 Cloudformation,这非常简单,我只是从 和 之类的函数构建我的 JSONFn::Base64文件Fn::Join。例如,它看起来像这样(简化)

"MyLaunchTemplate": {
    "Type": "AWS::EC2::LaunchTemplate",
        "Properties": {
            "LaunchTemplateData": {
                "ImageId": "ami-xxx",
                "UserData": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "#!/bin/bash -xe",
                            {"Fn::Sub": "echo \"${SomeParameter}\""},
                        ]
                    }
                }
            }
        }
    }
}

这样我就可以SomeParameter在启动 cloudformation 模板时定义参数。

使用 CDK,我们可以在部署时或综合时从 AWS Parameter Store 访问值。如果我们在部署时使用它们,我们只会得到一个令牌,否则我们会得到实际值。

到目前为止,我已经实现了读取合成时间的值并将用户数据脚本直接编码为 base64,如下所示:

product_version = ssm.StringParameter.value_from_lookup(
    self, f'/Prod/MyProduct/Deploy/Version')

launch_template = ec2.CfnLaunchTemplate(self, 'My-LT', launch_template_data={
    'imageId': my_ami,
    'userData': base64.b64encode(
        f'echo {product_version}'.encode('utf-8')).decode('utf-8'),
})

但是,使用此代码,版本会在综合期间被读取,并将被硬编码到用户数据脚本中。

为了能够使用仅在部署时解析的动态值 ( value_for_string_parameter),我需要以某种方式告诉 CDK 编写类似于我之前手动完成的 Cloudformation 模板(Fn::Base64仅在 Cloudformation 中使用,而不在 Python 中使用)。但是,我没有找到方法来做到这一点。

如果我读取一个仅在部署时解析的值,如下所示,我如何在UserData启动模板字段中使用它?

latest_string_token = ssm.StringParameter.value_for_string_parameter(
    self, "my-plain-parameter-name", 1)

标签: amazon-web-servicesamazon-cloudformationaws-cdk

解决方案


可以使用Pythonaws_cdk.core.Fn中可用的 Cloudformation 内部函数。

这些可以在 EC2 中创建启动模板以组合字符串和令牌时使用,例如

import aws_cdk.core as cdk

# loads a value to be resolved at deployment time
product_version = ssm.StringParameter.value_for_string_parameter(
    self, '/Prod/MyProduct/Deploy/Version')

launch_template = ec2.CfnLaunchTemplate(self, 'My-LT', launch_template_data={
    'imageId': my_ami,
    'userData': cdk.Fn.base64(cdk.Fn.join('\n', [
        '#!/usr/bin/env bash',
        cdk.Fn.join('=', ['MY_PRODUCT_VERSION', product_version]),
        'git checkout $MY_PRODUCT_VERSION',
    ])),
})

如果参数存储包含 version ,则此示例可能会在启动模板中生成以下用户数据脚本1.2.3

#!/usr/bin/env bash
MY_PRODUCT_VERSION=1.2.3
git checkout $MY_PRODUCT_VERSION

推荐阅读