AWS CloudFormation - 교차 스택으로 네트워크 및 서버 스택을 별도로 관리

🗒️ 내용


  • AWS CloudFormation 101
  • 하나의 키 쌍 f
  • Hands-on Lab: 교차 스택으로 네트워크 및 서버 스택을 별도로 관리



  • 1. AWS 클라우드포메이션 101



    1.1. IaC(코드형 인프라)



    개발자가 코드를 처리하는 것과 동일한 방식으로 인프라를 처리하는 것은 DevOps의 가장 기본적인 원칙 중 하나입니다.

    Infrastructure as code (IaC) means provisioning, configuring and managing your infrastructure resources using code and templates.



    1.2. AWS 클라우드포메이션



    AWS CloudFormation is a service speeding up cloud provisioning with infrastructure as code



    AWS 리소스 및 인프라 아키텍처는 JSON 또는 YAML(권장) 형식의 텍스트 파일로 작성된 CloudFormation 템플릿에서 모델링되고 설명됩니다. 그런 다음 CloudFormation이 해당 리소스의 프로비저닝 및 구성을 처리합니다.

    아래 다이어그램과 같이 스택을 생성하기 위한 CloudFormation 워크플로우

    CloudFormation 워크플로(출처: https://aws.amazon.com/cloudformation/ )

    2. CloudFormation 템플릿 구조


  • 리소스(필수): AWS 리소스 선언
  • 매개변수(선택 사항): with!Ref <parameter>를 사용하여 스택을 생성/업데이트할 때마다 템플릿에 사용자 정의 값을 입력합니다.
  • 매핑(선택 사항): with를 사용하여 키를 특정 값에 매핑합니다!FindInMap [ <map_name>, <top_key>, <second_key> ].
  • 조건(선택 사항): 조건에 따라 리소스 또는 출력 생성을 제어합니다
  • .
  • 출력(선택 사항): 스택의 출력 값 반환
  • 교차 스택: 템플릿을 분리하고 한 스택의 Export와 다른 스택의 !ImportValue <export_name>를 사용하여 다른 스택의 값을 참조합니다
  • .

    3. Hands-on Lab: 크로스 스택으로 네트워크 및 서버 스택을 별도로 관리



    다음 아키텍처를 사용하여 간단한 웹 애플리케이션을 개발한다고 가정합니다.
  • VPC 1개, 퍼블릭 서브넷 1개, EC2 인스턴스 1개
  • 포트 80에서 열리는 하나의 보안 그룹(어디서나 HTTP용)


  • 인프라를 2개의 템플릿으로 분리하면 인프라를 더 쉽게 관리하는 데 도움이 될 수 있습니다.

    3.1. LabNetworkStack


    lab_network_cfn.yml의 내용:

    Description: This template manages network components
    
    Parameters:
      ApplicationName:
        Description: An application name that is prefixed to resource names
        Type: String
        Default: lab
      VpcCidr:
        Description: The IP range (CIDR notation) for VPC in form x.x.x.x/16-28
        Type: String
        AllowedPattern: "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(1[6-9]|2[0-8]))$"
        Default: 10.192.0.0/16
      PublicSubnetCidr:
        Description: The IP range (CIDR notation) for public subnet in form x.x.x.x/16-28
        Type: String
        AllowedPattern: "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(1[6-9]|2[0-8]))$"
        Default: 10.192.10.0/24
    
    Resources:
      Vpc:
        Type: AWS::EC2::VPC
        Properties:
          CidrBlock: !Ref VpcCidr
          EnableDnsSupport: true
          EnableDnsHostnames: true
          Tags:
            - Key: Name
              Value: !Sub '${ApplicationName}-vpc'
      PublicSubnet:
        Type: AWS::EC2::Subnet
        Properties:
          VpcId: !Ref Vpc
          CidrBlock: !Ref PublicSubnetCidr
          MapPublicIpOnLaunch: true
          Tags:
            - Key: Name
              Value: !Sub '${ApplicationName}-public-subnet'
      InternetGateway:
        Type: AWS::EC2::InternetGateway
        Properties:
          Tags:
            - Key: Name
              Value: !Sub '${ApplicationName}-igw'
      InternetGatewayAttachment:
        Type: AWS::EC2::VPCGatewayAttachment
        Properties:
          InternetGatewayId: !Ref InternetGateway
          VpcId: !Ref Vpc
      PublicRouteTable:
        Type: AWS::EC2::RouteTable
        Properties:
          VpcId: !Ref Vpc
          Tags:
            - Key: Name
              Value: !Sub '${ApplicationName}-rtb'
      DefaultPublicRoute:
        Type: AWS::EC2::Route
        DependsOn: InternetGatewayAttachment
        Properties:
          RouteTableId: !Ref PublicRouteTable
          DestinationCidrBlock: 0.0.0.0/0
          GatewayId: !Ref InternetGateway
      PublicSubnetRouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
          RouteTableId: !Ref PublicRouteTable
          SubnetId: !Ref PublicSubnet
    
    Outputs:
      VpcId:
        Description: The VPC ID of lab application
        Value: !Ref Vpc
        Export:
          Name: !Sub '${AWS::StackName}-VpcId'
      SubnetId:
        Description: The Subnet ID of lab application
        Value: !Ref PublicSubnet
        Export:
          Name: !Sub '${AWS::StackName}-PublicSubnetId'
    


    템플릿은 AWS CLI로 배포할 수 있습니다.

    aws s3 cp lab_network_cfn.yml s3://<your_bucket>
    aws cloudformation create-stack --stack-name LabNetworkStack --template-url https://<your_bucket>.s3.<your_region>.amazonaws.com/lab_network_cfn.yml
    


    3.2. LabServerStack


    lab_server_cfn.yml의 내용:

    Description: This template manages servers components
    
    Parameters:
      ApplicationName:
        Description: An application name that is prefixed to resource names
        Type: String
        Default: lab
      Landscape:
        Type: String
        Default: develop
        AllowedValues:
        - develop
        - production
      NetworkStackName:
        Description: The name of Network CloudFormation stack
        Type: String
        Default: LabNetworkStack
    
    Mappings:
      RegionMap:
        ap-southeast-1:
          AMI: ami-02ee763250491e04a
        ap-southeast-2:
          AMI: ami-0e040c48614ad1327
    
    Conditions:
      IsProduction: !Equals [ !Ref Landscape, production]
    
    Resources:
      SecurityGroup:
        Type: AWS::EC2::SecurityGroup
        Properties:
          GroupDescription: !Sub 'Security group for ${ApplicationName} instances'
          SecurityGroupIngress:
            - IpProtocol: tcp
              FromPort: 80
              ToPort: 80
              CidrIp: 0.0.0.0/0
          VpcId: !ImportValue
            'Fn::Sub': '${NetworkStackName}-VpcId'
          Tags:
            - Key: Name
              Value: !Sub '${ApplicationName}-srg'
      Ec2Instance: 
        Type: AWS::EC2::Instance
        Properties: 
          ImageId: !FindInMap [ RegionMap, !Ref 'AWS::Region', AMI ]
          InstanceType: !If [ IsProduction, t2.small, t2.micro ] 
          KeyName: your_key_name
          SubnetId: !ImportValue
            'Fn::Sub': '${NetworkStackName}-PublicSubnetId'
          SecurityGroupIds:
          - !Ref SecurityGroup
          BlockDeviceMappings: 
          - DeviceName: "/dev/sda1"
            Ebs:
              VolumeSize: 12
              VolumeType: gp2
              Encrypted: true
          UserData:
            "Fn::Base64":
              !Sub |
                #!/bin/bash
                apt update
                apt install apache2 -y
          Tags:
            - Key: Name
              Value: !Sub '${ApplicationName}-ec2'
    
    Outputs:
      InstanceIp:
        Description: The IP address of instance
        Value: !GetAtt Ec2Instance.PublicIp
    


    템플릿은 AWS CLI로 배포할 수 있습니다.

    aws s3 cp lab_server_cfn.yml s3://<your_bucket>
    aws cloudformation create-stack --stack-name LabServerStack --template-url https://<your_bucket>.s3.<your_region>.amazonaws.com/lab_server_cfn.yml
    


    확인
  • 스택 상태가 모두인지 확인합니다CREATE_COMPLETE.
  • 기본 Ubuntu Apache 웹 페이지를 확인합니다http://your_server_ip.


  • 3.3. 깨끗한 자원



    콘솔 또는 AWS CLI에서 다음 순서로 스택을 삭제할 수 있습니다.

    aws cloudformation delete-stack --stack-name LabServerStack
    aws cloudformation delete-stack --stack-name LabNetworkStack
    

    좋은 웹페이지 즐겨찾기