有没有办法在 AWS CloudFormation 模板中进行继承或代码重用?

Is there a way to do inheritance or code reuse in an AWS CloudFormation template?

我正在构建一个 CloudFormation 模板,其中包含一个 AWS::AutoScaling::LaunchConfiguration 和一个使用该 LaunchConfiguration 的 AWS::AutoScaling::AutoScalingGroup。对于我的堆栈,我将需要多个 AutoScalingGroup,但我希望它们位于单独的安全组中。

我还将使用 CodeDeploy,因此我的 LaunchConfiguration 包括要安装的 Metadata 和 UserData 属性以及 运行 CodeDeploy 代理(如 http://s3.amazonaws.com/aws-codedeploy-us-east-1/templates/latest/CodeDeploy_SampleCF_Template.json 的第 262 行所示)。因为我必须在 LaunchConfiguration 而不是 AutoScalingGroup 中指定安全组,所以我的模板中必须有多个 LaunchConfiguration 副本,只有一行差异。

有没有办法减少冗长的元数据和用户数据部分出现在我的模板中的次数?我尝试创建映射,但它们只允许字母数字字符。

编写代码来创建您的模板 JSON 而不是手动编写 - 然后您可以使用您选择的语言中可用的任何抽象来创建不同的 LaunchConfiguration 资源。

允许您将地图和矢量表示为文字的语言比那些不这样做的语言更适合于此。

例如,Clojure 文字

{"Type" "AWS::AutoScaling::LaunchConfiguration"
 "Properties" {"KeyName" {"Ref" "KeyName"}
               "ImageId" {"Ref" "AMI"}}}

可以自动翻译成JSON字符串

{"Type":"AWS::AutoScaling::LaunchConfiguration",
 "Properties":{"ImageId":{"Ref":"AMI"},
               "KeyName":{"Ref":"KeyName"}}}

(尽管在实践中您只会为完整模板而不是单个资源创建 JSON。)

然后您可以执行以下操作

(defn launch-configuration
  [ami]
  {"Type" "AWS::AutoScaling::LaunchConfiguration"
   "Properties" {"KeyName" {"Ref" "KeyName"}
                 "ImageId" ami}})

(map launch-configuration ["ami1" "ami2" "ami3"])

创建多个相似的资源。

手工制作模板JSON真的只对非常小的模板方便。

我最近发现了 CDK。还没有使用过它,但它似乎是比直接写出所有模板代码更好的方法。可以使用 TypeScript、JavaScript、Java 和 C# 定义资源,并编译生成 CloudFormation 模板。在 Java:

中创建堆栈的示例
public class MyStack extends Stack {
    public MyStack(final App scopy, final String id) {
        this(scope, id, null);
    }

    public MyStack(final App scope, final String id, final StackProps props) {
        super(scope, id, props);

        new Bucket(this, "MyFirstBucket", BucketProps.builder()
            .withVersioned(true)
            .build());
    }
}

关于 CDK 的更多信息:https://docs.aws.amazon.com/CDK/latest/userguide/what-is.html