微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

<AWS CloudFormation> 如何从外部脚本获取和使用返回值?

如何解决<AWS CloudFormation> 如何从外部脚本获取和使用返回值?

我正在试验 CloudFormation 来自动创建资源。在以下设置中,我试图将负载平衡目标组的创建从主脚本分解为一个单独的脚本。我知道我们可以使用“转换”部分引用外部脚本,但主脚本流需要创建的目标组的 ARN 才能继续。我可以知道是否有办法从外部脚本传回值?谢谢

(Create_Cluster.yaml) 主脚本

    AWstemplateFormatVersion: 2010-09-09
    Description: Create ECS cluster,task deFinition and service

    Transform:
      Name: 'AWS::Include'
      Parameters:
        Location: s3://MyAmazonS3BucketName/Create_Target_Group.yaml

    Resources:
      TestECSCluster:
        Type: 'AWS::ECS::Cluster'
        Properties: {}

      ECSTaskExecutionRole:
        Type: 'AWS::IAM::Role'
        Properties:
          AssumeRolePolicyDocument:
            Version: 2012-10-17
            Statement:
              - Sid: ''
                Effect: Allow
                Principal:
                  Service: ecs-tasks.amazonaws.com
                Action: 'sts:AssumeRole'
          ManagedPolicyArns:
            - 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'

      PostCodeECSTaskDeFinition:
        Type: 'AWS::ECS::TaskDeFinition'
        Properties:
          ExecutionRoleArn: !GetAtt 
            - ECSTaskExecutionRole
            - Arn
          ContainerDeFinitions:
            - Name: PostCode
              Image: 'Nginxdemos/hello:latest'
              Essential: true
              PortMappings:
                - HostPort: 80
                  Protocol: tcp
                  ContainerPort: 80
          RequiresCompatibilities:
            - FARGATE
          NetworkMode: awsvpc
          cpu: '256'
          Memory: '512'
          Family: ecs-demo

      PostCodeECSService:
        Type: 'AWS::ECS::Service'
        Properties:
          Cluster: TestCluster
          DeploymentController: 
            Type: CODE_DEPLOY
          DesiredCount: 1
          HealthCheckGracePeriodSeconds: 300
          LaunchType: FARGATE
          LoadBalancers: 
            - ContainerName: PostCode
              ContainerPort: 80
              TargetGroupArn: <HOW TO GET THE ARN OF THE TARGET GROUP CREATED IN EXTERNAL SCRIPT?>
          SchedulingStrategy: REPLICA
          ServiceName: TestService
          TaskDeFinition: PostCodeECSTaskDeFinition

(Create_Target.yaml) 用于创建目标组的脚本

    AWstemplateFormatVersion: 2010-09-09
    Description: Create target group
    Resources:
      TestTargetGroup01:
        Type: AWS::ElasticLoadBalancingV2::TargetGroup
        Properties:
          Name: TestTargetGroup01
          Protocol: HTTP
          Port: 80
          targettype: instance
          VpcId: vpc-b830c6c5

================================
更新(2021 年 4 月 6 日)
==============================

经过一些研究,我让它工作了。您需要将要外部化的部分放在单独的堆栈(嵌套堆栈)中,并在主堆栈中调用它。在嵌套堆栈中,添加输出”部分以返回任何值;在主栈中,使用“GetAtt”函数从嵌套栈中获取返回值。

      ...
      TargetGroupArn: !GetAtt
        - TargetGroup01Stack
        - Outputs.TargetGroupARN
      ...

这里我使用了嵌套堆栈而不是 Transform 部分,因为它可以有自己的“输出”部分。
参考:
https://aws.amazon.com/premiumsupport/knowledge-center/cloudformation-nested-stacks-values/

这里讨论了嵌套堆栈和转换之间的区别:
https://acloud.guru/forums/aws-cda-2018/discussion/-LYOIsyqQdHckIbop4XP/difference_between_nested_stac#:~:text=2%20Answers&text=Nested%20stacks%20create%20a%20distinctly,master%20template's%20parameters%2C%20conditions%20etc

(Create_ECS_Cluster.yaml) 创建主栈,一步调用里面的嵌套栈

    AWstemplateFormatVersion: '2010-09-09'
    Description: Create ECS cluster,task deFinition and service
    Resources:
      TargetGroup01Stack:
        Type: 'AWS::CloudFormation::Stack'
        Properties:
          TemplateURL: 'https://mys3bucket.s3.amazonaws.com/Create_Target_Group.yaml'

      TestSecurityGroup:
        Type: 'AWS::EC2::SecurityGroup'
        Properties:
          GroupDescription: Security group for ec2 access
          VpcId: vpc-b830c6c5
          SecurityGroupIngress:
            - IpProtocol: tcp
              FromPort: 80
              ToPort: 80
              CidrIp: 0.0.0.0/0
            - IpProtocol: tcp
              FromPort: 8080
              ToPort: 8080
              CidrIp: 0.0.0.0/0
            - IpProtocol: tcp
              FromPort: 22
              ToPort: 22
              CidrIp: 0.0.0.0/0

      TestALB:
        Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
        Properties:
          Scheme: internet-facing
          SecurityGroups:
            - !Ref TestSecurityGroup
          subnets:
            - subnet-e80ed48e
            - subnet-7c3ba772
          Tags:
            - Key: Group
              Value: Example
          Type: application
          IpAddresstype: ipv4

      TestALBListener:
        Type: 'AWS::ElasticLoadBalancingV2::Listener'
        Properties:
          DefaultActions:
            - Type: forward
              ForwardConfig:
                TargetGroups:
                  - TargetGroupArn: !GetAtt
                    - TargetGroup01Stack
                    - Outputs.TargetGroupARN
          LoadBalancerArn: !Ref TestALB
          Port: 80
          Protocol: HTTP

      TestECSCluster:
        Type: 'AWS::ECS::Cluster'
        Properties: {}

      ECSTaskExecutionRole:
        Type: 'AWS::IAM::Role'
        Properties:
          AssumeRolePolicyDocument:
            Version: 2012-10-17
            Statement:
              - Sid: ''
                Effect: Allow
                Principal:
                  Service: ecs-tasks.amazonaws.com
                Action: 'sts:AssumeRole'
          ManagedPolicyArns:
            - 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'

      PostCodeECSTaskDeFinition:
        Type: 'AWS::ECS::TaskDeFinition'
        Properties:
          ExecutionRoleArn: !GetAtt 
            - ECSTaskExecutionRole
            - Arn
          ContainerDeFinitions:
            - Name: PostCode
              Image: patrick888/postcode:latest
              Essential: true
              PortMappings:
                - HostPort: 80
                  Protocol: tcp
                  ContainerPort: 80
              LogConfiguration:
                LogDriver: awslogs
                Options:
                  awslogs-group: awslogs-ecs
                  awslogs-region: us-east-1
                  awslogs-stream-prefix: PostCodeECSService
          RequiresCompatibilities:
            - FARGATE
          NetworkMode: awsvpc
          cpu: '256'
          Memory: '512'
          Family: ecs-demo

      PostCodeECSService:
        Type: 'AWS::ECS::Service'
        Properties:
          Cluster: !Ref TestECSCluster
          DeploymentController: 
            Type: CODE_DEPLOY
          DesiredCount: 1
          HealthCheckGracePeriodSeconds: 300
          LaunchType: FARGATE
          LoadBalancers: 
            - ContainerName: PostCode
              ContainerPort: 80
              TargetGroupArn: !GetAtt
                - TargetGroup01Stack
                - Outputs.TargetGroupARN
          NetworkConfiguration:
            AwsVpcConfiguration:
              AssignPublicIp: ENABLED
              SecurityGroups:
                - !Ref TestSecurityGroup
              subnets:
                - subnet-e80ed48e
                - subnet-7c3ba772
          SchedulingStrategy: REPLICA
          ServiceName: TestService
          TaskDeFinition: !Ref PostCodeECSTaskDeFinition
        DependsOn: TestALBListener

(Create_Target_Group.yaml) 创建用于创建目标组的嵌套堆栈

    AWstemplateFormatVersion: 2010-09-09
    Description: Create target group
    Resources:
      TestTargetGroup01:
        Type: AWS::ElasticLoadBalancingV2::TargetGroup
        Properties:
          Name: TestTargetGroup01
          Protocol: HTTP
          Port: 80
          targettype: ip
          VpcId: vpc-b830c6c5
          HealthCheckPath: /healthcheck.html
    Outputs:
      TargetGroupARN:
        Value: !Ref TestTargetGroup01       
        Description: The target group ARN

解决方法

使用嵌套堆栈使设置正常工作,并在嵌套堆栈的“输出”部分中返回值。详情请参考以上内容,谢谢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。