CloudFormation,根据 DependsOn 应用条件 [英] CloudFormation, apply Condition on DependsOn

查看:30
本文介绍了CloudFormation,根据 DependsOn 应用条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要做的任务是让 CDN 依赖于 S3 存储桶.但我们想让它使用现有的存储桶,而不是创建一个新的存储桶.

The task that I need to do is make CDN depend on a S3 bucket. But we want to make it use the existing bucket rather than creating a new one.

这是我正在尝试的示例代码:

Here is the sample code that I am trying:

"Parameters" : {
  "UseExistingBucket" : {
    "Description" : "Yes/No",
    "Default" : "yes",
    "Type" : "String",
    "AllowedValues" : [ "yes", "no" ]
  }
},
"Conditions" : {
  "CreateS3Resources" : {"Fn::Equals" : [{"Ref" : "UseExistingBucket"}, "no"]}
},
"Resources" : {
  "StaticBucket" : {
    "Type" : "AWS::S3::Bucket",
    "Condition" : "CreateS3Resources",
    "Properties" : {
      "BucketName" : { "Fn::Join": [ "-", [ "app",  { "Ref": "EnvType" }, "static" ] ] }
    },
    "DeletionPolicy": "Retain"
  },
  "MyStaticDistribution": {
    "Type": "AWS::CloudFront::Distribution",
    "Properties": {
      "DistributionConfig": {
        "Origins": [
          {
            "DomainName": {
              "Fn::If" : [
                "CreateS3Resources",
                { "Fn::Join": [ "-", [ "app",  { "Ref": "EnvType" }, "static" ] ] },
                {"Fn::GetAtt": [ "StaticBucket", "DomainName" ] }
              ]
            },
            "Id": "S3Origin",
          }
        ]
      }
    },
    "DependsOn": [{
      "Fn::If" : [
        "CreateS3Resources",
        { "Fn::Join": [ "-", [ "app",  { "Ref": "EnvType" }, "static" ] ] },
        ""
      ]
    }]
  }
}

如果需要,请向我建议更多细节(至少 stackoverflow 确实需要更多细节,但我没有指定任何细节:-P)

Please suggest to me any more details, if they are required (atleast stackoverflow does wants more details, but I have not specified any :-P)

推荐答案

您可以使用包裹在条件 Fn:If 中的 Fn:GetAtt 来实现.使用 Fn:GetAtt 意味着依赖,因此 CloudFormation 会在到达该函数后自动等待,就像您使用 DependsOn 一样.

You can do this by using Fn:GetAtt wrapped in a conditional Fn:If. Using Fn:GetAtt implies a dependency, so CloudFormation will automatically wait once it reaches that function, the same as if you were using a DependsOn.

示例

下面的代码片段通过有条件地检索尚未创建的嵌套堆栈的名称来显示这一点,但只有在条件 UseNestedStack 设置为 true 时才会这样做.如果 UseNestedStack 为 false,它将不会等待而是检索局部变量名称.

The code snippet below shows this by conditionally retrieving the name of a nested stack that has not yet been created but only does so if the condition UseNestedStack is set to true. If UseNestedStack is false it will not wait and instead retrieve a local variable name.

{
"Fn::If": ["UseNestedStack", {
    "Fn::GetAtt": ["NestedStack", "Outputs.Name"]
}, {
    "Ref": "LocalName"
}]

我怎么知道这个?(另一个例子)

不幸的是,没有官方文档对此进行正式说明,但 AWS 告诉我要这样做,在他们的代码示例中,您可以看到当订单很重要时,他们使用 Fn:GetAtt.我已经尝试了很多次,每次都有效.自己在一个简单的堆栈上尝试一下.这是我自己调整并使用过的 AWS lambda 示例中的一些伪证明.如果 AMI 函数是在资源 AMI 信息之后创建的,则下面的堆栈可能无法工作,AMI 信息需要 AMI 函数的输出,因此 AWS 使用 Fn:GetAtt 将它们链接在一起.要查看此滚动到底部并查看资源 AMIInfo,您将看到它通过 fn:Gett 引用了 AMIFunction.CloudFormation 看到这一点并返回到 AMIFunction 以首先创建它.

Unfortunately there is no official documentation officially stating this but it was AWS that told me to do it this way and in their code examples you can see that when order matters they use Fn:GetAtt. I've tried this numerous times and it works every time. Try it yourself on a simple stack. Here is some more pseudo proof from an AWS lambda example that I tweaked and have used myself. The stack below could not possibly work if the AMI function is created after the resource AMI info, AMI Info needs output of the AMI function, so AWS has chained them together using Fn: GetAtt. To see this scroll to the bottom and look at the resource AMIInfo and you will see it references AMIFunction via fn: Gett. CloudFormation sees this and goes back to AMIFunction to create it first.

"AMIInfoFunction": {
  "DependsOn":"SourceStack",
  "Type": "AWS::Lambda::Function",
  "Properties": {
    "Code": {
      "S3Bucket": { "Ref": "DeploymentBucket" },
      "S3Key": {"Fn::Join": [
        "",
        [
          {
            "Ref": "ApplicationName"
          },
          "/amilookup.zip"
        ]
      ]}
    },
    "Handler": "amilookup.handler",
    "Runtime": "nodejs",
    "Timeout": "30",
    "Role": { "Fn::GetAtt" : ["LambdaExecutionRole", "Arn"] },
    "VpcConfig": {
      "SecurityGroupIds": [ {"Ref": "InstanceSecurityGroup"}],
      "SubnetIds": [ {"Ref":"PrivateSubnetA"},{"Ref":"PrivateSubnetB"} ]
    }
  }
},
"AMIInfo": {
  "Type": "Custom::AMIInfo",
  "Properties": {
    "ServiceToken": { "Fn::GetAtt" : ["AMIInfoFunction", "Arn"] },
    "StackName": { "Ref":"SourceStack" }
  }
}

更新: 现在在相关堆栈的文档中对此进行了记录 (Fn::GetAtt).感谢 idoimaging 在评论中指出这一点.https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html

Update: This is now documented (Fn::GetAtt) in the documentation for dependent stacks. Thank you to idoimaging in the comments for pointing that out. https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html

这篇关于CloudFormation,根据 DependsOn 应用条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆