[SK shieldus Rookies 16기][AWS] AWS CloudFormation

Jina·2023년 12월 4일
0

SK shieldus Rookies 16기

목록 보기
31/59
post-thumbnail
post-custom-banner

참조
https://docs.aws.amazon.com/ko_kr/AWSCloudFormation/latest/UserGuide/Welcome.html

AWS CloudFormation

정의

AWS 리소스를 모델링, 프로비저닝 해주는 서비스

클라우드 환경 내 모든 인프라 리소스를 설명하고 프로비저닝할 수 있도록 공통 언어(JSON, YAML)를 통해 코드 기반 인프라를 구성하고 프로비저닝할 수 있음

AWS Cloudformation에는 추가 요금이 없으며 애플리케이션 실행에 필요한 AWS 리소스에 대해서만 요금을 지불하면 됨

코드형 인프라(Infrastructure as Code, iaC)란?
수동 프로세스 및 설정 대신 코드를 사용하여 컴퓨팅 인프라를 프로비저닝하고 지원하는 기능

테라폼이란?
하시코프(Hashicorp)에서 오픈소스로 개발중인 클라우드 인프라스트럭처 자동화를 지향하는 코드로서의 인프라스트럭처(IaC)도구

특징

  1. 인프라 관리 간소화
  2. 신속한 인프라 복제
  3. 인프라 변경사항 쉽게 제어 및 추적 가능

작동 방식

  1. AWS Cloudformation에서 인프라의 생성, 수정, 삭제는 모두 템플릿을 통해 수행됨
  2. YAML 또는 JSON 포맷으로 Cloudformation 템플릿을 작성하거나, 샘플 템플릿을 사용하여 인프라를 코드로 작성
  3. 로컬의 템플릿 코드를 체크아웃 하거나, S3 버킷에 템플릿 업로드
  4. AWS 콘솔, 명령줄 도구(CLI) 또는 API를 통해 AWS Cloudformation을 사용하여 템플릿 코드를 기반으로 스택(stack)을 생성
  5. 템플릿에 지정된 스택(stack)을 통해 AWS 리소스에 대한 프로비저닝 및 구성 작업 (스택 생성에 실패하면 AWS Cloudformation에서는 생성한 리소스를 삭제하여 변경 사항을 롤백함)

구성요소

  1. 템플릿
    • JSON 또는 YAML 형식의 텍스트 파일
    • 스택에서 프로비저닝할 리소스를 설명
    • Cloudformation Designer 또는 텍스트 편집기를 사용해 생성 가능
  2. Stack
    • 하나의 단위로 관리할 수 있는 AWS 리소스 모음
    • 스택의 생성, 수정, 삭제를 통해 리소스 모음의 생성, 수정, 삭제 가능
    • 스택의 모든 리소스는 Cloudformation 템플릿을 통해 정의됨
    • 스택을 삭제하면 관련 리소스가 모두 삭제됨
  3. 변경세트
    • 리소스를 변경하기 전에 제안된 변경 사항의 요약
    • 변경 사항을 구현하기 이전에 해당 변경이 실행 중인 리소스 특히, 중요 리소스에 미치는 영향을 확인 가능

템플릿 구조

CreateVPC_01.yaml

# 문서 형식의 버전 정보를 정의
AWSTemplateFormatVersion: 2010-09-09
# 템플릿 설명문
Description: Make a VPC 1

# 템플릿을 통해 만들 리소스 정의
Resources:
  # ToturialVPC 리소스 정의
  ToturialVPC:
    Type: AWS::EC2::VPC # VPC종류
    Properties:
      CidrBlock: 172.0.0.0/16 # VPC가 가질 수 있는 CidrBlock 정의
      EnableDnsHostnames: true # `ToturialVPC` 라는 이름으로 하겠다.

  # InternetGateway 리소스 정의
  InternetGateway:
    Type: AWS::EC2::InternetGateway # 필수항목이 Type ONLY

  # AttachGateway 리소스 정의
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment # VPC-GW를 연결해주는 것
    Properties:
      VpcId: !Ref ToturialVPC # 내장함수 Ref 정의. 위에서 정의한 ToturialVPC 참조.
      InternetGatewayId: !Ref InternetGateway # 위에서 정의한 IGW를 말한다.

  # PublicSubnet01 리소스 정의
  PublicSubnet01:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref ToturialVPC  
      CidrBlock: 172.0.0.0/24 # VPC의 CidrBlock 보다는 작은 걸 써야한다.
      AvailabilityZone: !Select # 가용영역, 내장함수 Select는 인덱스별 객체 목록에서 객체 하나 반환 
                                # 짧은 형식 ⇒ !Select [ index, listOfObjects ]
        - '0' # ap-northeast-2a을 반환 ⇒ 가용 영역 목록의 첫번째 값을 반환받는다.
        - !GetAZs '' # 내장함수 GetAZs는 지정된 리전의 가용 영역을 알파벳순으로 나열하는 Array를 반환
                    # 짧은 형식 ⇒  !GetAZs 리전 ⇒ 빈 문자열을 지정하면 AWS::Region을 지정하는 것과 같다.
                    # 만약 서울 리전이라면 ap-northeast-2a, ap-northeast-2b, ap-northeast-2c, ap-northeast-2d를 반환

  # PrivateSubnet01 리소스 정의
  PrivateSubnet01:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref ToturialVPC
      CidrBlock: 172.0.1.0/24
      AvailabilityZone: !Select 
        - '0'
        - !GetAZs ''

  # PublicRouteTable 리소스 정의
  PublicRouteTable: 
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref ToturialVPC

  # PublicRoute 리소스 정의
  PublicRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0 # 모든 IP로의 요청을
      GatewayId: !Ref InternetGateway # 인터넷게이트로 가게 해라 ⇒ 인터넷게이트웨이로 라우팅 정의

  # PublicSubnetRouteTableAssociation1 리소스 정의
  PublicSubnetRouteTableAssociation1: 
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet01
      RouteTableId: !Ref PublicRouteTable
  # 인터넷게이트웨이로의 라우팅을 별도로 정의, 연결 X
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref ToturialVPC

  # PrivateSubnetRouteTableAssociation1 리소스 정의
  PrivateSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet01
      RouteTableId: !Ref PrivateRouteTable

# 템플릿 실행 후 결과물 
Outputs:
  VPC:
    Description: Toturial VPC ID
    Value: !Ref ToturialVPC # ToturialVPC
  AZ1:
    Description: Availability Zone 1
    Value: !GetAtt # 내장 함수 !GetAtt은 템플릿의 리소스를 반환
      - PublicSubnet01
      - AvailabilityZone

실습1

1) 스택 생성

  1. 스택 생성
    CloudFormation > 스택 > 스택 생성 클릭

  2. 스택 템플릿 지정

  3. 스택 이름 작성

  4. 나머지 설정 변경하지 않고 전송

  5. 스택 상태 확인
    스택 상태가 CREATE_IN_PROGRESS → CREATE_COMPLETE 로 변경되는 거 확인

  6. 출력 확인

  7. VPC확인
    VPC > VPC

  8. 서브넷 확인
    VPC > 서브넷

2) 스택 업데이트

  1. 디렉토리에 CreateVPC_01.yaml 을 복사 붙여넣기 해서CreateVPC_02.yaml 파일 생성
AWSTemplateFormatVersion: 2010-09-09
Description: Make a VPC 2

Resources:
  ToturialVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 172.0.0.0/16
      EnableDnsHostnames: true

  InternetGateway:
    Type: AWS::EC2::InternetGateway

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref ToturialVPC
      InternetGatewayId: !Ref InternetGateway

  PublicSubnet01:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref ToturialVPC
      CidrBlock: 172.0.0.0/24
      AvailabilityZone: !Select 
        - '0'
        - !GetAZs ''
  #추가1----------------------------
  PublicSubnet02:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref ToturialVPC
      CidrBlock: 172.0.2.0/24
      AvailabilityZone: !Select 
        - '2'
        - !GetAZs ''
  #---------------------------------
  PrivateSubnet01:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref ToturialVPC
      CidrBlock: 172.0.1.0/24
      AvailabilityZone: !Select 
        - '0'
        - !GetAZs ''
  #추가2----------------------------
  PrivateSubnet02:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref ToturialVPC
      CidrBlock: 172.0.3.0/24
      AvailabilityZone: !Select 
        - '2'
        - !GetAZs ''
  #---------------------------------
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref ToturialVPC

  PublicRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet01
      RouteTableId: !Ref PublicRouteTable
  #추가3----------------------------
  PublicSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet02
      RouteTableId: !Ref PublicRouteTable
  #---------------------------------
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref ToturialVPC

  PrivateSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet01
      RouteTableId: !Ref PrivateRouteTable
  #추가4----------------------------
  PrivateSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet02
      RouteTableId: !Ref PrivateRouteTable
  #---------------------------------
Outputs:
  VPC:
    Description: Tutorial VPC ID
    Value: !Ref ToturialVPC
  AZ1:
    Description: Availability Zone 1
    Value: !GetAtt 
      - PublicSubnet01
      - AvailabilityZone
  #추가5----------------------------
  AZ3:
    Description: Availability Zone 3
    Value: !GetAtt 
      - PublicSubnet02
      - AvailabilityZone
  #---------------------------------
  1. 스택 업데이트

    변경 세트 미리보기

  2. VPC 서브넷에서 추가된 서브넷 확인

    태그 탭에서 확인 시 PublicSubnet02 이 보인다.

  3. 스택 실행 결과 확인

3) 스택 삭제

스택 삭제 완료 되었다면 Refresh

4) 삭제 확인

  1. 스택 삭제 확인

  2. VPC 확인

  3. 서브넷 확인

  4. 인터넷 게이트웨이 확인

S3 = 파일 저장소 서비스
파일? 객체(Object), 파일 저장소? 버킷(Bucket)

  1. 버킷 삭제
    S3 > 버킷

실습2

CloudFormation을 이용한 웹 애플리케이션 배포

  1. 템플릿 생성 - WebApplication.json
{
  	// CloudFormation 템플릿 버전
    "AWSTemplateFormatVersion" : "2010-09-09",
    // 템플릿에 대한 설명
    "Description" : "AWS CloudFormation Sample Template: Sample template that can be used to test EC2 updates. **WARNING** This template creates an Amazon Ec2 Instance. You will be billed for the AWS resources used if you create a stack from this template.",
    "Parameters" : {
      // EC2 인스턴스 유형 파라미터
      "InstanceType" : {
        "Description" : "WebServer EC2 instance type", 
        // 매개변수 자료형 : 문자열
        "Type" : "String",
        // 기본값
        "Default" : "t2.nano",
        // 허용되는 값 목록
        "AllowedValues" : [ 
          "t1.micro", 
          "t2.nano",
          "t2.micro", 
          "t2.small"
        ],
         // 제약 조건에 대한 설명
        "ConstraintDescription" : "must be a valid EC2 instance type."
      }
    },
    "Mappings" : {
      // 인스턴스 유형에 따른 아키텍처 매핑
      "AWSInstanceType2Arch" : {
          // t1.micro에 대한 아키텍처
          "t1.micro"    : { "Arch" : "HVM64"  },
          // t2.nano에 대한 아키텍처
          "t2.nano"     : { "Arch" : "HVM64"  },
          // t2.micro에 대한 아키텍처
          "t2.micro"    : { "Arch" : "HVM64"  },
          // t2.small에 대한 아키텍처
          "t2.small"    : { "Arch" : "HVM64"  }
      },
      // 리전 및 아키텍처에 따른 AMI(ID) 매핑
      "AWSRegionArch2AMI" : {
        // us-east-1 리전에 대한 AMI 매핑
        "us-east-1"        : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"},
        "us-west-2"        : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"},
        "us-west-1"        : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"},
        "eu-west-1"        : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"},
        "eu-west-2"        : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"},
        "eu-west-3"        : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"},
        "eu-central-1"     : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"},
        "ap-northeast-1"   : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"},
        "ap-northeast-2"   : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"},
        "ap-northeast-3"   : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"},
        "ap-southeast-1"   : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"},
        "ap-southeast-2"   : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"},
        "ap-south-1"       : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"},
        "us-east-2"        : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"},
        "ca-central-1"     : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"},
        "sa-east-1"        : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"},
        "cn-north-1"       : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"},
        "cn-northwest-1"   : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"}
      }
    },
    "Resources" : {
      // EC2 웹 서버 인스턴스 리소스 정의
      "WebServerInstance": {  
        // 인스턴스 리소스 타입
        "Type" : "AWS::EC2::Instance",
        "Metadata" : {
          // 단순한 PHP 애플리케이션을 설치하는 메타데이터 설정
          "Comment" : "Install a simple PHP application",
          "AWS::CloudFormation::Init" : {
            "config" : {
              "packages" : {                           
                // Yum 패키지 관리자를 사용해 설치할 패키지 목록
                "yum" : {
                  // 아무런 추가 설정이 없는 Apache 웹 서버
                  "httpd"             : [],
                  // 추가 설정이 없는 PHP
                  "php"               : []
                }
              },
              "files" : {                              
                // 웹 서버 디렉토리에 새 PHP 파일 생성
                "/var/www/html/index.php" : {
                  // PHP 파일 내용
                  "content" : { "Fn::Join" : ["", [
                    "<?php\n",
                    "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n",
                    "?>\n"
                  ]]},
                  // 파일 권한 설정
                  "mode"    : "000644",
                  // 파일 소유자
                  "owner"   : "apache",
                  // 파일 그룹
                  "group"   : "apache"
                },
                // cfn-hup 설정 파일 생성
                "/etc/cfn/cfn-hup.conf" : {
                  // 설정 파일 내용
                  "content" : { "Fn::Join" : ["", [
                    "[main]\n",
                    "stack=", { "Ref" : "AWS::StackId" }, "\n",
                    "region=", { "Ref" : "AWS::Region" }, "\n"
                  ]]},
                  // 파일 권한 설정
                  "mode" : "000400",
                  // 파일 소유자
                  "owner" : "root",
                  // 파일 그룹
                  "group" : "root"
                },
                // cfn-auto-reloader 설정 파일 생성
                "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : {
                  // 설정 파일 내용
                  "content": { "Fn::Join" : ["", [
                    "[cfn-auto-reloader-hook]\n",
                    "triggers=post.update\n",
                    "path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", 
                    "action=/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, 
                       " -r WebServerInstance "," --region ", { "Ref" : "AWS::Region" }, "\n",
                    "runas=root\n"
                  ]]}
                }
              },
              "services" : {
                // 서비스 관리자(sysvinit)에 의해 관리되는 서비스 설정
                "sysvinit" : {
                  // Apache 웹 서버(httpd)를 시작하고, 활성화
                  "httpd"   : { "enabled" : "true", "ensureRunning" : "true" },
                  // cfn-hup 서비스를 시작하고, 활성화  
                  "cfn-hup" : { 
                    "enabled" : "true", "ensureRunning" : "true",
                    // cfn-hup의 설정 파일 위치를 지정  
                    "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]
                  }
                }
              }
            }
          }
        },
        // EC2 인스턴스의 속성
        "Properties": {
          // 인스턴스에 사용될 AMI(ID) 정의
          "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] },
           // EC2 인스턴스의 유형 정의
          "InstanceType" : { "Ref" : "InstanceType" },
          // EC2 인스턴스의 보안 그룹 설정
          "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ],
          // 인스턴스의 사용자 데이터(=인스턴스가 처음 실행될 때 실행되는 스크립트) 설정
          "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
               "#!/bin/bash -xe\n",
               "yum install -y aws-cfn-bootstrap\n",
               "# Install the files and packages from the metadata\n",
               "/opt/aws/bin/cfn-init -v ",
               "         --stack ", { "Ref" : "AWS::StackName" },
               "         --resource WebServerInstance ",
               "         --region ", { "Ref" : "AWS::Region" }, "\n",
               "# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n",
               "/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n",
               "# Signal the status from cfn-init\n",
               "/opt/aws/bin/cfn-signal -e $? ",
               "         --stack ", { "Ref" : "AWS::StackName" },
               "         --resource WebServerInstance ",
               "         --region ", { "Ref" : "AWS::Region" }, "\n"
          ]]}}        
        },
        // 인스턴스 생성 정책 설정
        "CreationPolicy" : {
          "ResourceSignal" : {
            // 리소스 신호 제한 시간 설정
            "Timeout" : "PT5M"
          }
        }
      },
      // 웹 서버 보안 그룹 리소스 정의
      "WebServerSecurityGroup" : {
        // 보안 그룹 리소스 타입
        "Type" : "AWS::EC2::SecurityGroup",
        "Properties" : {
          "GroupDescription" : "Enable HTTP access via port 80",
          "SecurityGroupIngress" : [
            // 포트 80을 통한 HTTP 엑세스 허용
            {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"}
          ]
        }      
      }          
    },
    "Outputs" : {
      // 웹사이트 URL 출력
      "WebsiteURL" : {
        "Description" : "Application URL",
        "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServerInstance", "PublicDnsName" ]}]] }
      }
    }
  }

CloudFormation 헬퍼 스크립트
CloudFormation으로 생성한 EC2 인스턴스에 소프트웨어를 설치하고 서비스를 시작하는데 사용할 수 있도록 제공하는 Python스크립트

aws-cfn-bootstrap

  • 정의
    • AWS에서 제공하는 유틸리티 패키지
    • EC2 인스턴스를 프로비저닝하고 초기화하기 위한 도구
  • 주요 구성요소
    1. cfn-init
      • EC2 인스턴스의 초기 설정을 관리
      • 리소스 메타데이터를 검색 및 해석하고, 패키지를 설치하고, 파일을 생성하고, 서비스를 시작하는데 사용
    2. cfn-signal
      • EC2 인스턴스가 성공적으로 초기화되었음을 CloudFormation 스택에 알림
      • 필수 리소스나 애플리케이션이 준비될 때 스택에서 다른 리소스를 동기화할 수 있도록 CreationPolicy 또는 WaitCondition에서 신호를 전송하는데 사용
    3. cfn-get-metadata
      • EC2 인스턴스의 CloudFormation 스택 메타데이터를 검색하는 데 사용
      • 스택에서 사용 가능한 메타데이터를 검색할 때 유용하며, 다른 명령에 전달해 활용할 수 있음
    4. cfn-hup
      • EC2 인스턴스에서 실행되며, 주기적으로 CloudFormation 스택의 변경 사항을 감지하고 업데이트된 메타데이터를 검색하여 인스턴스를 업데이트
      • 변경 사항을 실시간으로 반영하려는 스택에서 사용

AWS::CloudFormation::Init
CloudFormation 템플릿에서 사용되는 리소스 유형 중 하나
cfn-init 헬퍼 스크립트에 대하나 구성 작업을 정의
EC2 인스턴스를 생성할 때 초기 설정, 패키지 설치, 파일 다운로드, 명령 실행 및 다른 구성 단계를 선언적으로 정

  1. 디폴트 VPC 생성
    왜? VPC가 없으면 오류가 발생할 수 있기 때문에

3. 스택 생성

  1. 스택 생성
    CloudFormation > 스택 > 스택 생성 클릭

  2. 스택 템플릿 지정

  3. 스택 이름 및 파라미터 설정

Json 파일의 Parameter 부분에 해당

"Parameters" : {
      // EC2 인스턴스 유형 파라미터
      "InstanceType" : {
        "Description" : "WebServer EC2 instance type", 
        // 매개변수 자료형 : 문자열
        "Type" : "String",
        // 기본값
        "Default" : "t2.nano",
        // 허용되는 값 목록
        "AllowedValues" : [ 
          "t1.micro", 
          "t2.nano",
          "t2.micro", 
          "t2.small"
        ],
         // 제약 조건에 대한 설명
        "ConstraintDescription" : "must be a valid EC2 instance type."
      }
    },
  1. 나머지 설정은 변경하지 않고, 전송

  2. 스택 생성 확인

  3. 인스턴스 확인

Json 파일의 Properties 부분에 해당

// EC2 인스턴스의 속성
"Properties": {
  // 인스턴스에 사용될 AMI(ID) 정의
  "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] },
    // EC2 인스턴스의 유형 정의
    "InstanceType" : { "Ref" : "InstanceType" },
  1. 출력 값 확인
    CloudWatch > 스택

Json 파일의 file 부분에 /var/www/html/index.php에 해당

"files" : {                              
  // 웹 서버 디렉토리에 새 PHP 파일 생성
  "/var/www/html/index.php" : {
    // PHP 파일 내용
    "content" : { "Fn::Join" : ["", [
      "<?php\n",
      "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n",
      "?>\n"
    ]]},
      // 파일 권한 설정
      "mode"    : "000644",
      // 파일 소유자
      "owner"   : "apache",
      // 파일 그룹
      "group"   : "apache"
  },
  1. EC2인스턴스로 SSH접속이 가능하도록 템플릿을 수정
    WebApplication.json 을 복사에서 WebApplicationSSH.json 파일 생성
{
    "AWSTemplateFormatVersion" : "2010-09-09",
    "Description" : "AWS CloudFormation Sample Template: Sample template that can be used to test EC2 updates. **WARNING** This template creates an Amazon Ec2 Instance. You will be billed for the AWS resources used if you create a stack from this template.",
    "Parameters" : {
      "InstanceType" : {
        "Description" : "WebServer EC2 instance type",
        "Type" : "String",
        "Default" : "t2.nano",
        "AllowedValues" : [ 
          "t1.micro", 
          "t2.nano",
          "t2.micro", 
          "t2.small"
        ],
        "ConstraintDescription" : "must be a valid EC2 instance type."
      },
      //추가---------------------------------
      "SSHLocation":{
        "Description" : "SSH 접속을 허용할 IP 대역",
        "Type" : "String",
        "MaxLength" : "18",
        "MinLength" : "9",
        // 모든 IP 대역을 받는다.
        "Default" : "0.0.0.0/0",
        // 형식 : 숫자(1~3자리).숫자(1~3자리).숫자(1~3자리).숫자(1~3자리)/숫자(1~2자리)
        "AllowedPattern" : "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/(\\d{1,2}))",
        // 형식에 맞지 않는 경우 출력될 문구
        "ConstraintDescription" : "x.x.x.x/x 형식으로 입력하세요."
      },
      "KeyName" : {
        "Description" : "SSH 접속에 사용할 키페어 이름",
        "Type" : "AWS::EC2::KeyPair::KeyName"
      }
      //-------------------------------------
    },
    "Mappings" : {
      "AWSInstanceType2Arch" : {
          "t1.micro"    : { "Arch" : "HVM64"  },
          "t2.nano"     : { "Arch" : "HVM64"  },
          "t2.micro"    : { "Arch" : "HVM64"  },
          "t2.small"    : { "Arch" : "HVM64"  }
      },
      "AWSRegionArch2AMI" : {
        "us-east-1"        : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"},
        "us-west-2"        : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"},
        "us-west-1"        : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"},
        "eu-west-1"        : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"},
        "eu-west-2"        : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"},
        "eu-west-3"        : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"},
        "eu-central-1"     : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"},
        "ap-northeast-1"   : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"},
        "ap-northeast-2"   : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"},
        "ap-northeast-3"   : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"},
        "ap-southeast-1"   : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"},
        "ap-southeast-2"   : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"},
        "ap-south-1"       : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"},
        "us-east-2"        : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"},
        "ca-central-1"     : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"},
        "sa-east-1"        : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"},
        "cn-north-1"       : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"},
        "cn-northwest-1"   : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"}
      }
    },
    "Resources" : {
      "WebServerInstance": {  
        "Type" : "AWS::EC2::Instance",
        "Metadata" : {
          "Comment" : "Install a simple PHP application",
          "AWS::CloudFormation::Init" : {
            "config" : {
              "packages" : {                           
                "yum" : {
                  "httpd"             : [],
                  "php"               : []
                }
              },
              "files" : {                              
                "/var/www/html/index.php" : {
                  "content" : { "Fn::Join" : ["", [
                    "<?php\n",
                    "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n",
                    "?>\n"
                  ]]},
                  "mode"    : "000644",
                  "owner"   : "apache",
                  "group"   : "apache"
                },
                "/etc/cfn/cfn-hup.conf" : {
                  "content" : { "Fn::Join" : ["", [
                    "[main]\n",
                    "stack=", { "Ref" : "AWS::StackId" }, "\n",
                    "region=", { "Ref" : "AWS::Region" }, "\n"
                  ]]},
                  "mode" : "000400",
                  "owner" : "root",
                  "group" : "root"
                },
                "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : {
                  "content": { "Fn::Join" : ["", [
                    "[cfn-auto-reloader-hook]\n",
                    "triggers=post.update\n",
                    "path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", 
                    "action=/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, 
                       " -r WebServerInstance "," --region ", { "Ref" : "AWS::Region" }, "\n",
                    "runas=root\n"
                  ]]}
                }
              },
              "services" : {
                "sysvinit" : {
                  "httpd"   : { "enabled" : "true", "ensureRunning" : "true" },
                  "cfn-hup" : { 
                    "enabled" : "true", "ensureRunning" : "true",
                    "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]
                  }
                }
              }
            }
          }
        },
        "Properties": {
          "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] },
          "InstanceType" : { "Ref" : "InstanceType" },
          "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ],
          "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
               "#!/bin/bash -xe\n",
               "yum install -y aws-cfn-bootstrap\n",
               "# Install the files and packages from the metadata\n",
               "/opt/aws/bin/cfn-init -v ",
               "         --stack ", { "Ref" : "AWS::StackName" },
               "         --resource WebServerInstance ",
               "         --region ", { "Ref" : "AWS::Region" }, "\n",
               "# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n",
               "/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n",
               "# Signal the status from cfn-init\n",
               "/opt/aws/bin/cfn-signal -e $? ",
               "         --stack ", { "Ref" : "AWS::StackName" },
               "         --resource WebServerInstance ",
               "         --region ", { "Ref" : "AWS::Region" }, "\n"
          ]]}}        
        },
        "CreationPolicy" : {
          "ResourceSignal" : {
            "Timeout" : "PT5M"
          }
        }
      },
      "WebServerSecurityGroup" : {
        "Type" : "AWS::EC2::SecurityGroup",
        "Properties" : {
          "GroupDescription" : "Enable HTTP access via port 80",
          "SecurityGroupIngress" : [
            {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"}
          ]
        }      
      }          
    },
    "Outputs" : {
      "WebsiteURL" : {
        "Description" : "Application URL",
        "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServerInstance", "PublicDnsName" ]}]] }
      }
    }
  }
  1. 스택 업데이트
    CloudFormation > 스택 > 스택 선택 > 업데이트
    템플릿 파일 업로드

    KeyPair 선택

    변경사항 확인

    스택 업데이트 완료

  2. WebsiteURL로 접속해서 새로운 내용이 출력되는 것을 확인

  3. 인스턴스 확인
    EC2 > 인스턴스
    키페어가 할당된 것을 확인할 수 있다.

  4. Bitvise SSH Client로 확인



    로그인 확인하면 New Terminal Console 실행

    콘솔에 명령어 실행 해보기

  5. 리소스 정리
    스택 삭제

    S3버킷 삭제

    인스턴스 종료 확인

profile
공부 기록
post-custom-banner

0개의 댓글