【问题标题】:Sequentially initialise ec2 via cft通过 cft 顺序初始化 ec2
【发布时间】:2019-04-23 13:46:04
【问题描述】:

我正在尝试创建一个 cft,由于某种原因,我希望通过 cft 顺序初始化 ec2 实例。 有没有可能?

【问题讨论】:

  • 在此上下文中定义顺序初始化。如果您希望一个 EC2 实例一个接一个地启动,您可以使用 CloudFormation 中的 DependsOn 属性链接它们。如果您希望它们同时启动,但要按特定顺序执行初始化脚本/步骤,则需要 cfn-init 之类的东西并使用 WaitConditions 和 WaitHandlers。
  • 我正在编写 cft 来安装 rabbitmq,然后添加退出集群。我的 EC2 是 ASG 的一部分,因此 DependsOn 具有 LaunchConfiguration 依赖项。我希望在每个 EC2 节点上并行安装 Rabbitmq,但在每个 EC2 实例上按顺序执行集群连接脚本。

标签: amazon-ec2 ansible amazon-cloudformation aws-cli


【解决方案1】:

您将需要结合使用 cfn-init 和 cfn-signal 来协调此操作。 请按照下面的示例进行操作,该示例应该可以为您提供有关如何执行此操作的好主意。

Resources:    
  Server1:    
    Type: AWS::EC2::Instance
    Properties: 
      [...]
      UserData:
        Fn::Base64:  
            !Sub |  
              #!/bin/bash  
              yum update -y aws-cfn-bootstrap # good practice - always do this.  
              /opt/aws/bin/cfn-init -v -c primary -s ${AWS::StackId} -r Server1 --region ${AWS::Region}  
              yum -y update
    Metadata:
      AWS::CloudFormation::Init:
        configSets:
          primary:
            - InstallPreRequisites
            - CreateCluster # will be run only in master node
          secondary:
            - InstallPreRequisites
            - JoinCluster # will be run in each secondary node
        InstallPreRequisites:
          commands:
            a-install-app:
              command: 
                "install apps on each server"
            b-signal-node-ready-join-cluster:
              command: !Join
                - ''
                - - '/opt/aws/bin/cfn-signal -e 0 '
                  - Fn::Base64: !Ref AllNodesReadyToJoinClusterWaitHandle
        CreateCluster:
          commands:
            a-create-cluster:
              command: 
                "your commands to create the cluster"
            b-signal-cluster-created:
              command: !Join
                - ''
                - - '/opt/aws/bin/cfn-signal -e 0 '
                  - Fn::Base64: !Ref ClusterCreatedWaitHandle
        JoinCluster:
            a-wait-cluster-created:
              command: !Sub >-
                output=$(aws cloudformation describe-stack-resource 
                --region=${AWS::Region} 
                --stack-name=${AWS::StackName} 
                --logical-resource-id=ClusterCreatedWaitCondition 
                --output=text
                --query=StackResourceDetail.ResourceStatus)

                while [ "$output" != "CREATE_COMPLETE" ] && [ "$output" != "UPDATE_COMPLETE" ];
                do
                  sleep 10
                  output=$(aws cloudformation describe-stack-resource 
                  --region=${AWS::Region} 
                  --stack-name=${AWS::StackName} 
                  --logical-resource-id=ClusterCreatedWaitCondition 
                  --output=text
                  --query=StackResourceDetail.ResourceStatus)                  
                done
              waitAfterCompletion: '0'
            b-join-cluster:
              command: 
                "your commands to join the cluster"
              waitAfterCompletion: '0'

  Server2:
    Type: AWS::EC2::Instance
    Properties: 
      [...]
      UserData:
        Fn::Base64:  
            !Sub |  
              #!/bin/bash  
              yum update -y aws-cfn-bootstrap # good practice - always do this.  
              /opt/aws/bin/cfn-init -v -c secondary -s ${AWS::StackId} -r Server2 --region ${AWS::Region}  # Resource was updated here
              yum -y update
    Metadata:
      AWS::CloudFormation::Init:
        [...] # exactly same as above... one will be primary, the other secondary, due to UserData cfn-init parameter

  Server3:    
    Type: AWS::EC2::Instance
    Properties: 
      [...]
      UserData:
        Fn::Base64:  
            !Sub |  
              #!/bin/bash  
              yum update -y aws-cfn-bootstrap # good practice - always do this.  
              /opt/aws/bin/cfn-init -v -c secondary -s ${AWS::StackId} -r Server3 --region ${AWS::Region}  # Resource was updated here
              yum -y update
    Metadata:
      AWS::CloudFormation::Init:
        [...]


  AllNodesReadyToJoinClusterWaitCondition:
    Type: 'AWS::CloudFormation::WaitCondition'
    Properties:
      Handle: !Ref AllNodesReadyToJoinClusterWaitHandle
      Count: 3 # this should match the number of nodes on your cluster
      Timeout: '7200'
  AllNodesReadyToJoinClusterWaitHandle:
    Type: 'AWS::CloudFormation::WaitConditionHandle'

  ClusterCreatedWaitCondition:
    Type: 'AWS::CloudFormation::WaitCondition'
    Properties:
      Handle: !Ref ClusterCreatedWaitHandle
      Count: 1 # only one node (master) will signal this
      Timeout: '7200'
  ClusterCreatedWaitHandle:
    Type: 'AWS::CloudFormation::WaitConditionHandle'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 2012-02-16
    • 2021-07-12
    相关资源
    最近更新 更多