AWS Cloudformation으로 AWS EC2 인스턴스를 프로비저닝하는 방법.

10425 단어 iacawstutorialdevops
안녕하세요. EC2 인스턴스를 프로비저닝하고 구성하는 데 사용되는 샘플 AWS Cloudformation 템플릿과 공유하고 싶습니다. 운영자가 런타임에 특정 값을 수정할 수 있도록 매개변수화된 템플릿임을 알 수 있습니다. 매니페스트 외에도 보안 그룹 구성 및 거의 생성된 인스턴스에 대한 연결과 같은 다양한 작업을 수행하고 있습니다(수신 규칙은 미세 조정이 필요함). 물론 우리는 프로비저닝이 완료된 후 새 인스턴스를 수정하는 데 필요한 구성 단계를 실행하기 위해 Cloud-Init을 활용하고 있으며 최종적으로 템플릿은 내부 Dns 영역을 업데이트하기 위해 SSM 및 Route53에 대한 값도 검색/생성합니다.

사용된 도구에 대한 참조:
AWS Cloudformation 문서: https://docs.aws.amazon.com/cloudformation/?icmpid=docs_homepage_mgmtgov
AWS Cloudformation 템플릿: https://aws.amazon.com/cloudformation/resources/templates/
AWS::CloudFormation::초기화( cfn-init ).
AWS SSM: https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html
AWS ROUTE53: https://docs.aws.amazon.com/route53/?icmpid=docs_homepage_networking

AWSTemplateFormatVersion: 2010-09-09
Description:  This template creates a new ec2 EC2

Parameters:
  Environment:
    Type: String
    Description: 'staging, preproduction, or production'
    Default: staging
    AllowedValues:
      - staging
      - preproduction
      - production

  PrivateSubnet:
    Description: Specify the Subnet Id e.g. id-a for SubnetA
    Type: String
    Default: id-a
    AllowedValues:
      - id-a
      - id-b
      - id-c

  InstanceType:
    Description: EC2 instance type
    Type: String
    Default: t3.medium

  NodeName:
    Description: "Specify the Node's Name keep in mind that the resulting name will follow this convention: staging-infrastructure-ec2-1"
    Type: String
    Default: ec2

  NodeId:
    Description: Specify the Node Number Id e.g. 1 for Node1
    Type: String
    Default: 1

  DiskSize:
    Description: EC2 Selected Disk Size
    Type: String
    Default: 40


  DNSZoneId:
    Description: Specify the DNSZone  Id e.g. Z0177864RGEW5HYK40Z5
    Type: String

  DNSDomainName: 
    Description: Specify the DNSZone  Name e.g. 
    Type: String
    Default: staging.internal.services.com



Mappings:

    RegionToAmazonAMI:
      eu-central-1:
        HVM64: ami-image-id

Resources:

    SecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties:
        GroupDescription: !Join [ "-", [ !Ref Environment, !Ref "AWS::Region", infrastructure-security-group-ec2-all] ]
        GroupName: !Join [ "-", [ !Ref Environment, !Ref "AWS::Region", infrastructure-security-group-ec2-all] ]
        SecurityGroupEgress:
          - CidrIp: 0.0.0.0/0
            IpProtocol: "-1"
        SecurityGroupIngress:
          - CidrIp: 0.0.0.0/0
            IpProtocol: icmp
            FromPort: -1
            ToPort: -1
          - CidrIp: 0.0.0.0/0
            IpProtocol: tcp
            FromPort: 22
            ToPort: 22
          - CidrIp: 0.0.0.0/0
            IpProtocol: tcp
            FromPort: 80
            ToPort: 80
          - CidrIp: 0.0.0.0/0
            IpProtocol: tcp
            FromPort: 443
            ToPort: 443
          - CidrIp: 0.0.0.0/0
            IpProtocol: tcp
            FromPort: 1936
            ToPort: 1936  
        Tags:
          - Key: "Environment"
            Value: !Ref Environment 
        VpcId: !ImportValue ExportedVpcId

    # One Node ec2 Linux Instance 
    InfraHAProxyNode:
      Type: AWS::EC2::Instance
      DependsOn: SecurityGroup
      CreationPolicy:
        ResourceSignal:
          Count: 1
          Timeout: PT30M
      Metadata:
        'AWS::CloudFormation::Init':
          configSets:
                Provisioning:
                  - PrepHaproxySteps
          PrepHaproxySteps:
            files:
              /root/prep-ec2-script.sh:
                content: !Sub |
                    #!/bin/bash
                    ip=$(hostname -I)
                    echo "$ip  $HOSTNAME " >>/etc/hosts

                    chmod 0700 /root/.ssh/
                    echo "$SSHKEY" > /root/.ssh/HAProxy_ssh_key
                    echo "$PUBSSHKEY" >> /root/.ssh/authorized_keys
                    chmod 0600 /root/.ssh/HAProxy_ssh_key
                    chmod 0600 /root/.ssh/authorized_keys
                env: 
                  SSHKEY: !Sub "{{resolve:ssm:/${Environment}/infrastructure/aws/ec2/rabbitmq_ssh_key}}"
                  PUBSSHKEY: !Sub "{{resolve:ssm:/${Environment}/infrastructure/aws/ec2/rabbitmq_ssh_key-pub}}"
                  HOSTNAME: !Sub  "${Environment}-${AWS::Region}-infrastructure-${NodeName}-node-${NodeId}"
                mode: '000755'
                owner: root
                group: root
            commands: 
              runPrepScript: 
                command: 'sh  /root/prep-ec2-script.sh'
                env: 
                  SSHKEY: !Sub "{{resolve:ssm:/${Environment}/infrastructure/aws/ec2/rabbitmq_ssh_key}}"
                  PUBSSHKEY: !Sub "{{resolve:ssm:/${Environment}/infrastructure/aws/ec2/rabbitmq_ssh_key-pub}}"
                  HOSTNAME: !Sub  "${Environment}-${AWS::Region}-infrastructure-${NodeName}-node-${NodeId}"
                cwd: "~"
                ignoreErrors: "false"
      Properties:
        ImageId:
          Fn::FindInMap:
            - RegionToAmazonAMI
            - Ref: 'AWS::Region'
            - HVM64
        InstanceInitiatedShutdownBehavior: stop
        InstanceType: !Ref InstanceType 
        Tags: 
          - Key: "Name"
            Value: !Sub "${Environment}-${AWS::Region}-infrastructure-${NodeName}-node-${NodeId}"
        BlockDeviceMappings:
          - DeviceName: "/dev/sda1"
            Ebs:
              DeleteOnTermination: 'true'
              VolumeSize: !Ref DiskSize
              VolumeType: gp2
        Monitoring: 'true'
        NetworkInterfaces:
          - AssociatePublicIpAddress: 'false'
            DeviceIndex: '0'
            GroupSet:
              - !Ref SecurityGroup
              - !Sub "{{resolve:ssm:/${Environment}/infrastructure/aws/vpc/security-group/ec2/all}}"
            SubnetId: !Join [ '', [ !Sub '{{resolve:ssm:/', !Sub '${Environment}', '/infrastructure/aws/vpc/subnet/private/', !Sub '${PrivateSubnet}', '}}'] ]
        Tenancy: default
        UserData:
            Fn::Base64: !Sub |
                #cloud-config
                repo_update: true
                repo_upgrade: all
                hostname:  "${Environment}-${AWS::Region}-infrastructure-${NodeName}-node-${NodeId}"
                write_files:
                    - content: |
                        #!/bin/bash
                        /opt/aws/bin/cfn-init -v  --stack ${AWS::StackName} --resource InfraHAProxyNode --configsets  HAProxyProvisioning  --region ${AWS::Region}
                        /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource InfraHAProxyNode  --region ${AWS::Region}
                      owner: root:root
                      path: /root/call-cfn-init.sh
                      permissions: '0700'     
                runcmd:
                  - [ sh, -c , "/root/call-cfn-init.sh" ]

    InfraHAProxyNodePrivIpOnSSM:
      Type: AWS::SSM::Parameter
      DependsOn: InfraHAProxyNode
      Properties:
        Name: !Sub /${Environment}/infrastructure/aws/ec2/node-${NodeId}/ip
        Type: String
        Value: !Sub ${InfraHAProxyNode.PrivateIp}

    InfraHAProxyNodeHostnameOnSSM:
      Type: AWS::SSM::Parameter
      DependsOn: InfraHAProxyNode
      Properties:
        Name: !Sub /${Environment}/infrastructure/aws/ec2/node-${NodeId}/hostname
        Type: String
        Value: !Sub  "${Environment}-${AWS::Region}-infrastructure-${NodeName}-node-${NodeId}"

    InfraHAProxyNodeEC2IDOnSSM:
      Type: AWS::SSM::Parameter
      DependsOn: InfraHAProxyNode
      Properties:
        Name: !Sub /${Environment}/infrastructure/aws/ec2/node-${NodeId}/instance-id
        Type: String
        Value: !Ref InfraHAProxyNode

    InfraHAProxyNodeEC2IDOnSSM:
      Type: 'AWS::SSM::Parameter'
      DependsOn: InfraHAProxyNode
      Properties:
        Name: !Sub /${Environment}/infrastructure/aws/ec2/node-${NodeId}/instance-id
        Type: String
        Value: !Ref InfraHAProxyNode

    InfraSecurityGroupOnSSM:
      Type: AWS::SSM::Parameter
      DependsOn: InfraHAProxyNode
      Properties:
        Name: !Sub /${Environment}/infrastructure/aws/ec2/security/group/1
        Type: String
        Value: !Ref SecurityGroup

    InfraHAProxyNodeDNSRecord:
      Type: AWS::Route53::RecordSet
      Properties:
        HostedZoneId: !Ref DNSZoneId
        Name: !Sub "${Environment}-${AWS::Region}-infrastructure-${NodeName}-node-${NodeId}"
        ResourceRecords:
          - !Sub ${InfraHAProxyNode.PrivateIp}
        TTL: 360
        Type: A


Outputs:
    InfraHAProxyNodeId: 
        Description: 'The ID of EC2 Instance' 
        Value:  !Ref InfraHAProxyNode
        Export:
          Name: !Sub "ExportedHAProxyID-${NodeId}"

    InfraHAProxyNodeHostname: 
        Description: 'The Hostname of ec2 EC2 Instance' 
        Value: !Sub "${Environment}-${AWS::Region}-infrastructure-${NodeName}-node-${NodeId}"
        Export:
          Name: !Sub "ExportedHAProxyHostname-${NodeId}"




엄지 척을 포기한다면 튜토리얼이 마음에 드시기 바랍니다! 그리고 에서 저를 팔로우하세요. 다가오는 튜토리얼을 놓치지 않기 위해 제 Newletter를 구독할 수도 있습니다.

미디어 속성



내 게시물에서 사용하고 있는 멋진Clark Tibbs을 디자인해 준 것에 대해photo 감사합니다.

좋은 웹페이지 즐겨찾기