首页 > 解决方案 > 当模板相互导出值时,如何上传/部署和组织 AWS CloudFormation 模板

问题描述

我正在使用 CloudFormation 模板部署我的 AWS 资源。但是我有两个模板可以相互导出和导入值并使用这些值。

我有一个模板,它使用现有资源和以下模板,称为 storage-resources.yml

AWSTemplateFormatVersion: "2010-09-09"
Description: "Permanent resources to be imported"
Parameters:
  DBInstanceIdentifier:
    Type: String
    Default: 'patheindbidentifier'
  DBName:
    Type: String
    Default: 'patheindb'
  DBUsername:
    Type: String
    Default: 'patheindbadmin'
  DBClass:
    Type: String
    Default: 'db.t2.micro'
  DBAllocatedStorage:
    Type: String
    Default: '5'
  DBPassword:
    Type: String

Resources:
  StorageBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      BucketName: pathein-directory-storage
      AccessControl: PublicRead

  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Database security group
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '3306'
          ToPort: '3306'
          SourceSecurityGroupId: !ImportValue PatheinWebServerSecurityGroup.GroupId

  WebDatabase:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      DBInstanceIdentifier: !Ref DBInstanceIdentifier
      DBName: !Ref DBName
      DBInstanceClass: !Ref DBClass
      AllocatedStorage: !Ref DBAllocatedStorage
      Engine: MySQL
      MasterUsername: !Ref DBUsername
      MasterUserPassword: !Ref DBPassword
      VPCSecurityGroups:
        - !GetAtt DBSecurityGroup.GroupId

Outputs:
  StorageBucket:
    Description: "S3 storage bucket"
    Value: !Ref StorageBucket
    Export:
      Name: PatheinStorageBucket

正如您在上面的模板中看到的,我正在导出 S3 存储桶。另一件事是我正在导入资源并按如下方式使用它。

!ImportValue PatheinWebServerSecurityGroup.GroupId

PatheinWebServerSecurityGroup 基本上位于另一个名为 core.yml 的模板中。我还将 S3 存储桶从 resources.yml 模板导入到 core.yml 模板中。

现在,我要做的是尝试使用使用现有资源的选项来部署 resources.yml。但问题是我无法上传它并且在我上传时它会抛出错误,因为 core.yml 模板还不存在并且它正在使用 core.yml 模板中的 PatheinWebServerSecurityGroup。

在这种情况下上传或部署模板的最佳方式是什么?我什至在做正确的事?我怎样才能做得更好?

标签: amazon-web-servicesamazon-cloudformation

解决方案


根据评论。

由于您的模板之间存在循环依赖关系,因此最简单的解决方案是将StorageBucketfromresources.yml移至core.yml,然后从那里导出。这样,resources.yml您将同时导入PatheinWebServerSecurityGroupStorageBucket

另一种方法是移动StorageBucketPatheinWebServerSecurityGroup进入第三个模板,从而打破循环依赖。

另请注意,您不能这样做:

!ImportValue PatheinWebServerSecurityGroup.GroupId

例如,您可以拥有以下两个具有循环依赖关系的模板(必须创建我自己的示例 core.yml):

核心.yml

Resources:


  MyELB:
    Type: AWS::ElasticLoadBalancing::LoadBalancer
    Properties: 
      AccessLoggingPolicy: 
        #EmitInterval: Integer
        Enabled: true
        S3BucketName: !ImportValue PatheinStorageBucket
        #S3BucketPrefix: String
      Listeners:
        - InstancePort: 80
          LoadBalancerPort: 80
          Protocol: HTTP
 
  PatheinWebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Database security group
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '3306'
          ToPort: '3306'
          CidrIp: 10.0.0.0/16


Outputs:

  WebServerSecurityGroup:
    Description: "Security Group"
    Value: !Ref PatheinWebServerSecurityGroup
    Export:
      Name: PatheinWebServerSecurityGroup

资源.yml

Resources:

  StorageBucket:
    Type: AWS::S3::Bucket
    #DeletionPolicy: Retain
    #UpdateReplacePolicy: Retain
    Properties:
      BucketName: pathein-directory-storage-332112
      AccessControl: PublicRead

  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Database security group
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '3306'
          ToPort: '3306'
          SourceSecurityGroupId: !ImportValue PatheinWebServerSecurityGroup.GroupId


Outputs:
  StorageBucket:
    Description: "S3 storage bucket"
    Value: !Ref StorageBucket
    Export:
      Name: PatheinStorageBucket

要解决上述问题,您可以创建第三个模板,该模板定义StorageBucketand PatheinWebServerSecurityGroup

基础.yml

Resources:

  StorageBucket:
    Type: AWS::S3::Bucket
    #DeletionPolicy: Retain
    #UpdateReplacePolicy: Retain
    Properties:
      BucketName: pathein-directory-storage-332112
      AccessControl: PublicRead

  PatheinWebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Database security group
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '3306'
          ToPort: '3306'
          CidrIp: 10.0.0.0/16

Outputs:

  StorageBucket:
    Description: "S3 storage bucket"
    Value: !Ref StorageBucket
    Export:
      Name: PatheinStorageBucket


  WebServerSecurityGroup:
    Description: "Security Group"
    Value: !GetAtt PatheinWebServerSecurityGroup.GroupId
    Export:
      Name: PatheinWebServerSecurityGroupId

那么 core.yml 和 resource.yml 将是:

核心.yml

Resources:

  MyELB:
    Type: AWS::ElasticLoadBalancing::LoadBalancer
    Properties: 
      AccessLoggingPolicy: 
        #EmitInterval: Integer
        Enabled: true
        S3BucketName: !ImportValue PatheinStorageBucket
        #S3BucketPrefix: String
      Listeners:
        - InstancePort: 80
          LoadBalancerPort: 80
          Protocol: HTTP
      AvailabilityZones: !GetAZs ""

资源.yml

Resources:

  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Database security group
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '3306'
          ToPort: '3306'
          SourceSecurityGroupId: !ImportValue PatheinWebServerSecurityGroupId

推荐阅读