この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
안녕하세요 클래스메소드 김재욱(Kim Jaewook) 입니다. 이번에는 CloudFormation으로 EC2 인스턴스를 구축해 보는 과정을 정리해 봤습니다.
EC2를 구축하기에 앞서, VPC, 서브넷과 같은 네트워크가 구성 되어 있어야 합니다. CloudFormation으로 네트워크를 구성하는 방법은 아래 블로그를 참고해 주세요.
CloudFormation Output
이번에는 하나의 CloudFormation 스택에서 모든 작업 처리 하는 것이 아니기 때문에 다른 스택으로 값을 넘겨줄 필요가 있습니다. 값을 넘겨주기 위해서는「Outputs:」를 사용합니다.
#-------------------------------------------------------------------
#OutPut
#-------------------------------------------------------------------
Outputs:
# VPC
VPC:
Value: !Ref VPC
Export:
Name: !Sub "test-vpc"
VPCCIDR:
Value: !Ref VPCCIDR
Export:
Name: !Sub "test-vpc-cidr"
# Subnet
PublicSubnetA:
Value: !Ref PublicSubnetA
Export:
Name: !Sub "test-front-subnet-1a"
PublicSubnetACIDR:
Value: !Ref PublicSubnetACIDR
Export:
Name: !Sub "test-front-subnet-1a-cidr"
PublicSubnetC:
Value: !Ref PublicSubnetC
Export:
Name: !Sub "test-front-subnet-1c"
PublicSubnetCCIDR:
Value: !Ref PublicSubnetCCIDR
Export:
Name: !Sub "test-front-subnet-1c-cidr"
PrivateSubnetA:
Value: !Ref PrivateSubnetA
Export:
Name: !Sub "test-application-subnet-1a"
PrivateSubnetACIDR:
Value: !Ref PrivateSubnetACIDR
Export:
Name: !Sub "test-application-subnet-1a-cidr"
PrivateSubnetC:
Value: !Ref PrivateSubnetC
Export:
Name: !Sub "test-application-subnet-1c"
PrivateSubnetCCIDR:
Value: !Ref PrivateSubnetCCIDR
Export:
Name: !Sub "test-application-subnet-1c-cidr"
# Route
FRONTRTB:
Value: !Ref FRONTRTB
Export:
Name: !Sub "test-front-rtb"
APPRTB1A:
Value: !Ref APPRTB1A
Export:
Name: !Sub "test-application-rtb-1a"
APPRTB1C:
Value: !Ref APPRTB1C
Export:
Name: !Sub "test-application-rtb-1c"
먼저 파라미터에는 EC2에 접속하기 위한 키 페어 값을 입력합니다.
CloudFormation 내에서 키 페어를 생성할 수는 없기 때문에 콘솔 환경으로 들어가서 2개의 키 페어를 생성합니다. 편의상 키 페어 이름을 파라미터의 디폴트 값과 동일하게 적었지만 실제로 사용할 때는 디폴트 이름과 다른 이름을 사용할 필요가 있습니다.
파라미터 생성
AWSTemplateFormatVersion: "2010-09-09"
Description:
Create EC2, RDS
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "EC2 Configuration"
Parameters:
- BastionEC2KeyPair
- AppEC2KeyPair
ParameterLabels:
BastionEC2KeyPair:
default: "BastionEC2KeyPair"
AppEC2KeyPair:
default: "AppEC2KeyPair"
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
BastionEC2KeyPair:
Type: String
Default: "BastionEC2KeyPair"
AppEC2KeyPair:
Type: String
Default: "AppEC2KeyPair"
보안 그룹 생성
# ------------------------------------------------------------#
# Create Security Groups
# ------------------------------------------------------------#
Resources:
FrontBastionSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "test-front-bastion-sg"
GroupName: test-front-bastion-sg
SecurityGroupIngress:
IpProtocol: tcp
FromPort : 22
ToPort : 22
CidrIp: 0.0.0.0
VpcId: { "Fn::ImportValue": !Sub "test-vpc" }
Tags:
- Key: "Name"
Value: test-front-bastion-sg
APPSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "test-app-sg"
GroupName: test-app-sg
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort : 22
ToPort : 22
SourceSecurityGroupId: !GetAtt FrontBastionSecurityGroup.GroupId
VpcId: { "Fn::ImportValue": !Sub "test-vpc" }
Tags:
- Key: "Name"
Value: test-app-sg
테스트용이기 때문에 test-front-bastion-sg에서 0.0.0.0으로 아이피를 뚫어놨지만, 실제 사용할 때는 파라미터에서 자신의 아이피를 입력 받아서 넣는 편이 좋습니다.
EC2 인스턴스 생성
# ------------------------------------------------------------#
# Create EC2 Instance
# ------------------------------------------------------------#
# Bastion EC2
BastionEC2:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0f66bf23ed74d9284
InstanceType: t3.micro
KeyName: !Ref BastionEC2KeyPair
DisableApiTermination: true
BlockDeviceMappings:
- DeviceName: "/dev/xvda"
Ebs:
VolumeType: "gp2"
DeleteOnTermination: "true"
VolumeSize: "8"
SecurityGroupIds:
- !Ref FrontBastionSecurityGroup
SubnetId: { "Fn::ImportValue": !Sub "test-front-subnet-1a" }
Tags:
- Key: "Name"
Value: test-front-bastion
# test-app-1a
AppEC2:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0f66bf23ed74d9284
InstanceType: t3.micro
KeyName: !Ref AppEC2KeyPair
DisableApiTermination: true
BlockDeviceMappings:
- DeviceName: "/dev/xvda"
Ebs:
VolumeType: "gp2"
DeleteOnTermination: "true"
VolumeSize: "50"
SecurityGroupIds:
- !Ref APPSecurityGroup
SubnetId: { "Fn::ImportValue": !Sub "test-application-subnet-1a" }
Tags:
- Key: "Name"
Value: test-app-1a
Public Subnet에서 발판 서버를 만들고, Private Subnet에는 외부에서 접속이 불가능한 EC2 서버 한대를 구축 했습니다.
접속 테스트
-
ssh -i "BastionEC2KeyPair.pem" ec2-user@ec2-13-124-243-180.ap-northeast-2.compute.amazonaws.com
해당 명령어로 접속해 보면 정상적으로 발판 서버에 접속한 것을 확인할 수 있습니다.
- scp -i /BastionEC2KeyPair.pem /AppEC2KeyPair.pem ec2-user@13.124.243.180:~
- ssh -i "AppEC2KeyPair.pem" ec2-user@10.0.181.212
이어서 scp 명령어를 사용해서 발판 서버로 키 페어를 업로드 하고 ssh로 접속해 보면 프라이빗 EC2에도 문제 없이 접속 되는 것을 확인할 수 있습니다.
콘솔 환경에서 EC2 환경에 들어가보면 CloudFormation으로 생성한 EC2 인스턴스를 확인할 수 있습니다.