出现错误:资源之间的循环依赖

Posted

技术标签:

【中文标题】出现错误:资源之间的循环依赖【英文标题】:Getting Error : Circular dependency between resources 【发布时间】:2019-12-04 12:03:40 【问题描述】:

我的 CloudFormation 代码出现循环依赖错误:

资源之间的循环依赖:[WebServerScaleDownPolicy, WebServerScaleUpPolicy、LaunchConfig、ElasticLoadBalancer、 CPUAlarmHigh、MySecurityGroup、CPUAlarmLow、WebServerGroup]

代码文件:https://drive.google.com/open?id=1SxDqc4oPRW0SgjtDg3eoVN_YE01iRLD1

我尝试添加“DependsOn”,但这无济于事。我是 CloudFormation 新手,正在寻求帮助。

AWSTemplateFormatVersion: '2010-09-09'
# this is the CloudFormation template deploys a Vpc
Resources:
  VPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: '10.0.0.0/16'
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: myWebsite-VPC
  InternetGateway:
    Type: 'AWS::EC2::InternetGateway'
    Properties:
      Tags:
      - Key: Name
        Value: myWebsite-IGW
  VPCGatewayAttachment:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  SubnetAPublic:
    Type: 'AWS::EC2::Subnet'
    Properties:
      AvailabilityZone: us-east-1a
      CidrBlock: '10.0.1.0/24'
      MapPublicIpOnLaunch: Yes
      VpcId: !Ref VPC
      Tags:
      - Key: name
        Value: 'A public'
      - Key: Reach
        Value: Public
  SubnetBPublic:
    Type: 'AWS::EC2::Subnet'
    Properties:
      AvailabilityZone: us-east-1b
      CidrBlock: '10.0.2.0/24'
      MapPublicIpOnLaunch: Yes
      VpcId: !Ref VPC
      Tags:
      - Key: Name
        Value: 'B public'
      - Key: Reach
        Value: Public
  RouteTablePublic:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref VPC
      Tags:
      - Key: Name
        Value: Public-routeTable
  RouteTableAssociationAPublic:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref SubnetAPublic
      RouteTableId: !Ref RouteTablePublic
  RouteTableAssociationBPublic:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref SubnetBPublic
      RouteTableId: !Ref RouteTablePublic
  RouteTablePublicInternetRoute:
    Type: 'AWS::EC2::Route'
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref RouteTablePublic
      DestinationCidrBlock: '0.0.0.0/0'
      GatewayId: !Ref InternetGateway
  WebServerGroup:
    Type: 'AWS::AutoScaling::AutoScalingGroup'
    Properties:
      AutoScalingGroupName: myASG
      Cooldown: 200
      DesiredCapacity: 2
      LaunchConfigurationName: !Ref LaunchConfig
      MaxSize: 6
      MinSize: 2
      LoadBalancerNames: [!Ref 'ElasticLoadBalancer']
      HealthCheckGracePeriod: 300
      Subnets:
          - us-east-1a
          - us-east-1b
  LaunchConfig:
    Type: AWS::AutoScaling::LaunchConfiguration
    Metadata:
      Comment: Install Apache
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
          files:
            /var/www/html/index.html:
              content: "<html><h1>this is my webpage</h1></html>"
              mode: '000644'
              owner: root
              group: root
          services:
            sysvinit:
              httpd:
                enabled: "true"
                ensureRunning: "true"
    Properties:
      KeyName: MYEC2Keypair
      SecurityGroup: !Ref MySecurityGroup
      InstanceType: t2.micro
      ImageId: ami-0b898040803850657
  WebServerScaleUpPolicy:
    Type: AWS::AutoScaling::ScalingPolicy
    Properties:
      AdjustmentType: ChangeInCapacity
      AutoScalingGroupName: !Ref WebServerGroup
      Cooldown: '60'
      ScalingAdjustment: 1
  WebServerScaleDownPolicy:
    Type: AWS::AutoScaling::ScalingPolicy
    Properties:
      AdjustmentType: ChangeInCapacity
      AutoScalingGroupName: !Ref WebServerGroup
      Cooldown: '60'
      ScalingAdjustment: -1
  CPUAlarmHigh:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: Scale-up if CPU > 90% for 10 minutes
      MetricName: CPUUtilization
      Namespace: AWS/EC2
      Statistic: Average
      Period: 300
      EvaluationPerioods: 2
      Threshold: 90
      AlarmActions: [!Ref 'WebServerScaleUpPolicy']
      Dimensions:
        - Name: AutoScalingGroupName
          Value: !Ref WebServerGroup
      ComparisonOperator: GreaterThanThreshold
  CPUAlarmLow:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: Scale-down if CPU < 70% for 10 minutes
      MetricName: CPUUtilization
      Namespace: AWS/EC2
      Statistic: Average
      Period: 300
      EvaluationPeriods: 2
      Threshold: 70
      AlarmActions: [!Ref 'WebServerScaleDownPolicy']
      Dimensions:
        - Name: AutoScalingGroupName
          Value: !Ref WebServerGroup
      ComparisonOperator: LessThanThreshold
  ElasticLoadBalancer:
    Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
    DependsOn: MySecurityGroup
    Properties:
      VpcId: !Ref VPC
      CrossZone: 'true'
      Listeners:
        - LoadBalancerPort: '80'
          InstancePort: '80'
          Protocol: HTTP
      SecurityGroup: !Ref MySecurityGroup
      AvailabilityZones:
        - us-east-1a
        - us-east-1b
      HealthCheck:
        Target: HTTP:80/
        HealthyThreshold: '3'
        UnhealthyThreshold: '5'
        Interval: '30'
        Timeout: '5'
        Tags:
          - Key: Name
            Value: MyELB
  MySecurityGroup:
    Type: AWS::EC2::SecruityGroup
    Properties:
      GroupDescription: Allow http and ssh only from LoadBalancer
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: '0.0.0.0/0'
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: '0.0.0.0/0'
          SourceSecurityGroupOwnerId: !GetAtt [ElasticLoadBalancer, SourceSecurityGroup.OwnerAlias]
          SourceSecurityGroupName: !GetAtt [ElasticLoadBalancer, SourceSecurityGroup.GroupName]
      Tags:
        - Key: Name
          Value: MySecurityGroup

【问题讨论】:

【参考方案1】:

这是因为您的“ElasticLoadBalancer”资源依赖于您的安全组“MySecurityGroup”,而 MySecurityGroup 在其入口规则中引用了负载均衡器,这就是存在循环依赖的原因。 您应该为负载均衡器定义一个单独的安全组,然后在“MySecurityGroup”中允许来自该安全组的 ssh 和 http。

【讨论】:

【参考方案2】:

CloudFormation Linter 将警告循环依赖等:

E3012 Property Resources/WebServerGroup/Properties/Cooldown should be of type String
~/Downloads/template.yml:76:7

E3012 Property Resources/WebServerGroup/Properties/DesiredCapacity should be of type String
~/Downloads/template.yml:77:7

E3012 Property Resources/WebServerGroup/Properties/MaxSize should be of type String
~/Downloads/template.yml:79:7

E3012 Property Resources/WebServerGroup/Properties/MinSize should be of type String
~/Downloads/template.yml:80:7

E3002 Invalid Property Resources/WebServerGroup/Properties/Subnets
~/Downloads/template.yml:83:7

E3002 Invalid Property Resources/LaunchConfig/Properties/SecurityGroup
~/Downloads/template.yml:108:7

E3003 Property EvaluationPeriods missing at Resources/CPUAlarmHigh/Properties
~/Downloads/template.yml:127:5

E3002 Invalid Property Resources/CPUAlarmHigh/Properties/EvaluationPerioods
~/Downloads/template.yml:133:7

E3004 Circular Dependencies for resource ElasticLoadBalancer.  Circular dependency with [MySecurityGroup, ElasticLoadBalancer]
~/Downloads/template.yml:155:3

E3002 Invalid Property Resources/ElasticLoadBalancer/Properties/VpcId
~/Downloads/template.yml:159:7

E3012 Property Resources/ElasticLoadBalancer/Properties/CrossZone should be of type Boolean
~/Downloads/template.yml:160:7

E3002 Invalid Property Resources/ElasticLoadBalancer/Properties/SecurityGroup
~/Downloads/template.yml:165:7

E3002 Invalid Property Resources/ElasticLoadBalancer/Properties/HealthCheck/Tags
~/Downloads/template.yml:175:9

E3004 Circular Dependencies for resource MySecurityGroup.  Circular dependency with [MySecurityGroup, ElasticLoadBalancer]
~/Downloads/template.yml:178:3

E3001 Invalid or unsupported Type AWS::EC2::SecruityGroup for resource MySecurityGroup in us-east-1
~/Downloads/template.yml:179:5

DependsOn 不会解决循环依赖。

是否可以从ElasticLoadBalancer 中删除DependsOn: MySecurityGroup 并在MySecurityGroup 中选择属性SourceSecurityGroupOwnerIdSourceSecurityGroupName 的值而不依赖于ElasticLoadBalancer? Those two properties may not be required 如果您根本不想为这些属性之一指定它。

这些选项将解决循环依赖项之一。

【讨论】:

以上是关于出现错误:资源之间的循环依赖的主要内容,如果未能解决你的问题,请参考以下文章

解决由于类之间的循环依赖而导致的构建错误

解决由于类之间的循环依赖而导致的构建错误

解决由于类之间的循环依赖而导致的构建错误

解决由于类之间的循环依赖而导致的构建错误

解决由于类之间的循环依赖而导致的构建错误

如何解决资源之间的循环依赖:[s3bucketvideo, S3InvokeLambdaPermission]