참조
https://docs.aws.amazon.com/ko_kr/AWSCloudFormation/latest/UserGuide/Welcome.html
AWS 리소스를 모델링, 프로비저닝 해주는 서비스
클라우드 환경 내 모든 인프라 리소스를 설명하고 프로비저닝할 수 있도록 공통 언어(JSON, YAML)를 통해 코드 기반 인프라를 구성하고 프로비저닝할 수 있음
AWS Cloudformation에는 추가 요금이 없으며 애플리케이션 실행에 필요한 AWS 리소스에 대해서만 요금을 지불하면 됨
코드형 인프라(Infrastructure as Code, iaC)란?
수동 프로세스 및 설정 대신 코드를 사용하여 컴퓨팅 인프라를 프로비저닝하고 지원하는 기능
테라폼이란?
하시코프(Hashicorp)에서 오픈소스로 개발중인 클라우드 인프라스트럭처 자동화를 지향하는 코드로서의 인프라스트럭처(IaC)도구
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
스택 생성
CloudFormation > 스택 > 스택 생성 클릭
스택 템플릿 지정
스택 이름 작성
나머지 설정 변경하지 않고 전송
스택 상태 확인
스택 상태가 CREATE_IN_PROGRESS → CREATE_COMPLETE 로 변경되는 거 확인
출력 확인
VPC확인
VPC > VPC
서브넷 확인
VPC > 서브넷
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
#---------------------------------
스택 업데이트
변경 세트 미리보기
VPC 서브넷에서 추가된 서브넷 확인
태그 탭에서 확인 시 PublicSubnet02
이 보인다.
스택 실행 결과 확인
스택 삭제 완료 되었다면 Refresh
스택 삭제 확인
VPC 확인
서브넷 확인
인터넷 게이트웨이 확인
S3 = 파일 저장소 서비스
파일? 객체(Object), 파일 저장소? 버킷(Bucket)
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 인스턴스를 프로비저닝하고 초기화하기 위한 도구
- 주요 구성요소
cfn-init
- EC2 인스턴스의 초기 설정을 관리
- 리소스 메타데이터를 검색 및 해석하고, 패키지를 설치하고, 파일을 생성하고, 서비스를 시작하는데 사용
cfn-signal
- EC2 인스턴스가 성공적으로 초기화되었음을 CloudFormation 스택에 알림
- 필수 리소스나 애플리케이션이 준비될 때 스택에서 다른 리소스를 동기화할 수 있도록 CreationPolicy 또는 WaitCondition에서 신호를 전송하는데 사용
cfn-get-metadata
- EC2 인스턴스의 CloudFormation 스택 메타데이터를 검색하는 데 사용
- 스택에서 사용 가능한 메타데이터를 검색할 때 유용하며, 다른 명령에 전달해 활용할 수 있음
cfn-hup
- EC2 인스턴스에서 실행되며, 주기적으로 CloudFormation 스택의 변경 사항을 감지하고 업데이트된 메타데이터를 검색하여 인스턴스를 업데이트
- 변경 사항을 실시간으로 반영하려는 스택에서 사용
AWS::CloudFormation::Init
CloudFormation 템플릿에서 사용되는 리소스 유형 중 하나
cfn-init 헬퍼 스크립트에 대하나 구성 작업을 정의
EC2 인스턴스를 생성할 때 초기 설정, 패키지 설치, 파일 다운로드, 명령 실행 및 다른 구성 단계를 선언적으로 정
스택 생성
CloudFormation > 스택 > 스택 생성 클릭
스택 템플릿 지정
스택 이름 및 파라미터 설정
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."
}
},
나머지 설정은 변경하지 않고, 전송
스택 생성 확인
인스턴스 확인
Json 파일의 Properties 부분에 해당
// EC2 인스턴스의 속성
"Properties": {
// 인스턴스에 사용될 AMI(ID) 정의
"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] },
// EC2 인스턴스의 유형 정의
"InstanceType" : { "Ref" : "InstanceType" },
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"
},
{
"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" ]}]] }
}
}
}
스택 업데이트
CloudFormation > 스택 > 스택 선택 > 업데이트
템플릿 파일 업로드
KeyPair 선택
변경사항 확인
스택 업데이트 완료
WebsiteURL로 접속해서 새로운 내용이 출력되는 것을 확인
인스턴스 확인
EC2 > 인스턴스
키페어가 할당된 것을 확인할 수 있다.
Bitvise SSH Client로 확인
로그인 확인하면 New Terminal Console 실행
콘솔에 명령어 실행 해보기
리소스 정리
스택 삭제
S3버킷 삭제
인스턴스 종료 확인