如何编写我的云形成更可重用而不是重命名资源

Ham*_*aee 1 amazon-web-services aws-cloudformation aws-opsworks

我是 cloudformation 的新手,我正在为我的项目的基础架构编写一些 cfn 代码。但是有一个问题在我编写代码时一直困扰着我。假设我有以下资源要创建:

Resources: 
MyEC2Instance: 
  Type: "AWS::EC2::Instance"
  Properties: 
    ImageId: "ami-79fd7eee"
    KeyName: "testkey"
    BlockDeviceMappings: 
      - DeviceName: "/dev/sdm"
        Ebs: 
          VolumeType: "io1"
          Iops: "200"
          DeleteOnTermination: "false"
          VolumeSize: "20"
      - DeviceName: "/dev/sdk"
        NoDevice: {}
Run Code Online (Sandbox Code Playgroud)

如您所见,我正在创建一个名为 MyEC2Instance 的资源。现在假设我有另一个名为 stg 的环境,它与上面的完全相同,所以一个简单的方法是使用上面的代码和不同的堆栈名称,但我被告知我需要按如下方式重命名我的资源名称:

Resources: 
MyEC2InstanceStg1: 
  Type: "AWS::EC2::Instance"
  Properties: 
    ImageId: "ami-79fd7eee"
    KeyName: "testkey"
    BlockDeviceMappings: 
      - DeviceName: "/dev/sdm"
        Ebs: 
          VolumeType: "io1"
          Iops: "200"
          DeleteOnTermination: "false"
          VolumeSize: "20"
      - DeviceName: "/dev/sdk"
        NoDevice: {}
Run Code Online (Sandbox Code Playgroud)

但对我来说,这看起来并不专业,因为如果我有 10 个环境,这是否意味着我需要复制我的代码 10 次并重命名资源。有什么更好的方法吗?

Jam*_*rke 5

我们在我的团队中处理这个问题的方式是我们有一个共享模板,用于为我们的每个环境生成堆栈:devstagingproduction。每个环境之间的逻辑 ID 将相同,但生成的物理 ID 将不同。

对此的一个警告是,如果您在同一帐户中拥有不同的环境堆栈,则必须确保任何Name属性都是唯一的。如果不需要它们,请不要设置它们,CloudFormation 会为您生成它们。在需要它们的情况下,我发现{"Fn::Sub": "${AWS::StackName}-SomeName"}这会有所帮助,因为它使每个物理资源名称都与它们的环境堆栈相关。例如,对于 CodeBuild,需要一个项目名称,因此我们执行以下操作:

Resources:
  Project:
    Type: AWS::CodeBuild::Project
    Properties:
      Name: !Sub "${AWS::StackName}-SlackBotLambda"
      ...
Run Code Online (Sandbox Code Playgroud)

因此,如果我在我的dev堆栈中,这会使 CodeBuild 项目名为dev-SlackBotLambda.

我们采用的另一种策略是传入EnvironmentName参数,以便我们可以拥有在一个环境而不是另一个环境中创建的资源。例如,我通常希望构建在 Dev 中创建的工件,然后与 Staging 和 Production 共享,因此我有如下创建的存储桶:

Parameters:
  EnvironmentName:
    Type: String
    AllowedValues:
      - dev
      - staging
      - production

  Conditions:
    ShouldGenerateArtifactBucket: !Equals [!Ref EnvironemntName, dev]

  Resources:
    ArtifactBucket:
      Type: AWS::S3::Bucket
      Condition: ShouldGenerateArtifactBucket
Run Code Online (Sandbox Code Playgroud)

只要您的堆栈名称足够独特,您甚至可以将第一种策略与第二种策略结合使用,以创建一个具有足够可预测名称的存储桶,以便一个堆栈可以从第一个中引用存储桶工件。