1

我们的问题似乎很基本,我希望很常见。

我们有必须始终应用的标签(用于计费)。但是,标签值仅在部署堆栈时才知道......我们不知道在开发堆栈时或在服务目录中创建产品时标签值是什么......

我们不想等到资源部署后才发现标签丢失,所以尽管 AWS 配置可能很酷,但如果我们不需要,我们也不想依赖它的规则。

所以标签选项之类的东西不起作用,因为他们似乎希望我们在某些部署之前几个月就知道标签值(事实并非如此。)

有没有办法在部署 cloudformation 模板时强制使用标签?更好的是,我们可以在部署时对标签值进行服务目录查询吗?例如,诸如“系统”或“项目”之类的标签会随着时间的推移而出现和消失,并且对于我们开发的许多类型的 cloudformation 模板而言,它们并不预先知道。

这不是一个常见的场景吗?

我担心我错过了一些非常非常简单和基本的东西,这些东西要求预先使用标签,但我似乎无法弄清楚是什么。先感谢您。在问之前我确实做了很多谷歌,但没有找到令人满意的答案。

4

1 回答 1

0

我对服务目录一无所知,但您可以创建条件,然后使用它有条件地创建(甚至失败)您的资源创建。有条件的资源创建,例如

Parameters:
  ResourceTag:
    Type: String
    Default: ''
Conditions:
  isTagEmpty:
    !Equals [!Ref ResourceTag, '']
Resources:
  DBInstance:
    Type: AWS::RDS::DBInstance
    Condition: isTagEmpty
    Properties:
      DBInstanceClass: <DB Instance Type>

此处仅当标签非空时才会创建 RDS 数据库实例。但是cloudformation仍然会返回成功。

或者,您可以尝试资源创建失败。

Resources:
  DBInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceClass: !If [isTagEmpty, !Ref "AWS::NoValue", <DB instance type>]

我没有尝试过,但它应该会失败,因为如果标签为空,数据库实例类型将无效。

编辑:您还可以使用createStackCFN API 创建堆栈。编写一些代码来读取和验证输入(例如从服务目录中读取)并调用createStackAPI。我正在从Lambda(nodejs)读取一些输入Parameter Store。示例代码 -

module.exports.create = async (event, context, callback) => {

 let request = JSON.parse(event.body);

 let subnetids = await ssm.getParameter({
     Name: '/vpc/public-subnets'
 }).promise();

 let securitygroups = await ssm.getParameter({
     Name: '/vpc/lambda-security-group'
 }).promise();

 let params = {
    StackName: request.customerName, /* required */
    Capabilities: [
        'CAPABILITY_IAM',
        'CAPABILITY_NAMED_IAM',
        'CAPABILITY_AUTO_EXPAND',
        /* more items */
    ],
    ClientRequestToken: 'qwdfghjk3912',
    EnableTerminationProtection: false,
    OnFailure: request.onfailure,
    Parameters: [
        {
            ParameterKey: "SubnetIds",
            ParameterValue: subnetids.Parameter.Value,
        },
        {
            ParameterKey: 'SecurityGroupIds',
            ParameterValue: securitygroups.Parameter.Value,
        },
        {
            ParameterKey: 'OpsPoolArnList',
            ParameterValue: request.userPoolList,
        },
        /* more items */
    ],
    TemplateURL: request.templateUrl,
 };

 cfn.config.region = request.region;

 let result = await cfn.createStack(params).promise();

 console.log(result);
}

另一种选择:添加由 Lambda 支持的AWS 自定义资源。检查本节中的标签,如果不满足约束则返回失败。使所有其他资源创建依赖于该资源(以便在您的检查通过时它们都创建)。链接还包含示例。您还必须为堆栈更新和删除添加处理(如默认成功)。我认为这是你目前最好的选择。

于 2019-03-06T17:28:32.567 回答