【问题标题】:Cloudformation stack with nested resources fails to create具有嵌套资源的 Cloudformation 堆栈无法创建
【发布时间】:2021-07-06 21:41:54
【问题描述】:

我正在尝试定义一些公共资源(特别是几个 IAM 角色),这些资源将通过嵌套堆栈在两个环境之间共享。使用嵌套堆栈资源的第一个环境创建正常,但第二个环境在尝试运行嵌套堆栈时失败。我是不了解嵌套堆栈的工作原理,还是我做错了什么?

我的嵌套堆栈定义为:

AWSTemplateFormatVersion: '2010-09-09'
Description: Defines common resources shared between environments.

Parameters:
    ParentStage:
    Type: String
    Description: The Stage or environment name.
    Default: ""
    ParentVpcId:
    Type: "AWS::EC2::VPC::Id"
    Description: VpcId of your existing Virtual Private Cloud (VPC)
    Default: ""

Resources:

    LambdaFunctionSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
        GroupDescription: Identifies Lamdba functions to VPC resources
        GroupName: BBA-KTDO-SG-LambdaFunction
        VpcId: !Ref ParentVpcId

    RdsAccessSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
        GroupDescription: Allows Lambda functions access to RDS instances
        GroupName: BBA-KTDO-SG-RDS
        SecurityGroupIngress:
        - IpProtocol: tcp
            FromPort: 3306
            ToPort: 3306
            SourceSecurityGroupId: !Ref LambdaFunctionSG
        VpcId: !Ref ParentVpcId

我已将该 YAML 文件上传到 S3 存储桶,然后尝试在两个单独的堆栈文件(即 app_dev.yamlapp_prod.yaml)中使用它:

Resources:

    CommonResources:
    Type: 'AWS::CloudFormation::Stack'
    Properties:
        TemplateURL: "https://my-buildbucket.s3-eu-west-1.amazonaws.com/common/common.yaml"
        Parameters:
        ParentStage: !Ref Stage
        ParentVpcId: !Ref VpcId

并将其输出称为(例如):

VpcConfig:
    SecurityGroupIds:
        - !GetAtt [ CommonResources, Outputs.LambdaFunctionSGId ]

第一个环境创建良好,包括嵌套资源。当我尝试运行第二个环境时,它失败并出现错误:

嵌入式堆栈 arn:aws:cloudformation:eu-west-1:238165151424:stack/my-prod-stack-CommonResources-L94ZCIP0UD9W/f9d06dd0-994d-11eb-9802-02554f144c21 未成功创建:以下资源未能成功创建 创建:[LambdaExecuteRole, LambdaFunctionSG]。

不可能像这样在两个独立的堆栈之间共享一个资源定义,还是我只是在实现中遗漏了一些东西?

【问题讨论】:

  • 这可能是命名事物的结果。例如,如果您有一个命名的 IAM 角色,第一个角色会成功,而第二个角色会失败。如果您删除名称,它将以基于堆栈名称和资源名称(添加随机字符)生成的名称结尾。

标签: amazon-web-services amazon-cloudformation


【解决方案1】:

正如@jasonwadsworth 提到的,堆栈的正确名称总是在末尾用随机字符串修改AWS::CloudFormation::Stack 检查返回值。使用GetAtt 获取堆栈的名称并构造输出。 How do I pass values between nested stacks within the same parent stack in AWS CloudFormation?

加上使用aws cloudformation package命令打包嵌套堆栈,无需手动上传到s3桶。

有点像

aws cloudformation package \
--template-file /path_to_template/template.json \
--s3-bucket bucket-name \
--output-template-file packaged-template.json

如果你对Difference between an Output & an Export感到好奇,也可以看看cloudformation output exports

【讨论】:

  • 非常感谢 - 我删除了组名,现在两个堆栈都建立了。我也已经在使用aws cloudformation package 来打包 lambda 函数,但没有意识到我也可以将它应用到堆栈模板文件,因此从部署脚本中又采取了另一个不必要的步骤 :)
猜你喜欢
  • 2020-08-30
  • 2020-11-09
  • 2019-04-07
  • 2018-10-27
  • 2019-02-27
  • 2017-01-16
  • 2021-04-22
  • 1970-01-01
  • 2019-12-13
相关资源
最近更新 更多