IT/Public Cloud

AWS CloudFormation 으로 VPC부터 Bastion EC2 생성까지

엘티엘 2022. 3. 12. 22:13

CloudFormation이란?

AWS에서 제공하는 IaC (Infra as Code) 서비스이다. VPC, EC2, S3 등 모든 AWS 인프라를 코드로 관리할 수 있다.이렇게 인프라를 코드로 관리할 경우, 현재 인프라를 다른 지역에 동일하게 생성한다거나, 인프라의 변경이력을 확인하는 등 인프라를 좀더 체계적이고 효율적으로 관리 및 운영하는것이 가능하다.

CloudFomation을 위해서는 json 또는 yaml 형식의 template 파일을 작성한다. json과 yaml은 형식만 다를뿐 내용에는 차이가 없다. 개인적으로 가독성이 좋은 yaml 형식을 선호한다. 이렇게 작성한 template 파일(json 또는 yaml)을 CloudFormation에 업로드하면 Stack 이라는 단위로 관리된다. 따라서 이후에 관련 인프라를 삭제 또는 업데이트 할때 Stack을 삭제 또는 업데이트 하면, 관련 인프라 전체가 삭제 또는 업데이트 된다.

CloudFormation template 파일 살펴보기 (yaml 형식)

아래는 VPC와 Subnet을 생성하는 CloudFormation template 파일이다. 크게 2가지 섹션이 있다 (Parameters, Resources)

먼저 Resources 섹션을 먼저 살펴보자. 생성하고자 하는 AWS 자원이 (아래는 VPC와 Subnet을 생성한다) 이 나열되어 있다. 자세히 보면 3가지 항목으로 이루어져 있다.

  • 이름: CloudFormation내에서 사용되는 이름 (myVPC, PublicNet1)
  • Type: 생성할 리소스 (관련 내용은 링크 참고)
  • Properties: 리소스에 대한 각종 설정값

Parameter 섹션을 살펴보자. CloudFormation에서 자원을 생성하기 전에 사용자 입력을 받는 항목이다. 아래를 보면 vpcCidr 이라는 항목이 있고, 이 값을 myVCP의 CidrBlock 항목에서 사용하고 있다. CloudFormation이 실행되기 전에 Parameters에 정의된 항목은 사용자 입력을 받을수 있다.

Parameters:
  vpcCidr:
    Description: VPC CIDR
    Type: String
    Default: "10.2.0.0/16"
    
Resources:
  myVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref vpcCidr
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: myVPC

  PubSubNet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: ap-northeast-2a
      VpcId: !Ref myVPC
      CidrBlock: 10.2.2.0/24
      Tags:
        - Key: Name
          Value: PubSubNet1

이외에 Mappings, Outputs, Conditions 등 다양한 섹션이 있다. 이에대한 설명은 링크를 참고한다.

CloudFormation으로 Bastion EC2를 생성해보자

CloudFormation으로 Bastion EC2를 생성해보자. 아무것도 없는 상태를 가정했을때, EC2 를 생성하기 위해서는 아래와 같은 자원이 같이 생성되어야 한다. 따라서 아래 자원에 대한 내용도 CloudFormation에 같이 작성되어야 한다.

  • VPC, Subnet, Security Group, Route Table, Internet Gateway

먼저 콘솔에서 직접 만든다고 생각하면 아래와 같은 순서로 작업이 필요하다.

  1. VPC를 생성한다.
  2. VPC내 Public Subnet을 생성한다.
  3. Internet Gateway를 생성하고 VPC에 Attach한다.
  4. Public Subnet의 Outbound 를 수정한다: 0.0.0.0/0 -> internet gateway
  5. Security Group을 생성하고, 22번 port를 open 한다 (ssh 접속을 위해)
  6. 이미 생성한 VPC, Public Subnet, Security Group과 연결된 EC2를 생성한다.

아래는 위의 단계가 실행될수 있도록 작성된 CloudFormation yaml 파일이다.

Parameters:
  keypairName:
    Description: keypair name
    Type: String
    Default: udemy-key
  vpcCidr:
    Description: VPC CIDR
    Type: String
    Default: "10.2.0.0/16"

Resources:

  # 1. VPC를 생성한다.
  myVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.2.0.0/16
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: myVPC

  # 2. VPC내 Public Subnet을 생성한다.
  PubSubNet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: ap-northeast-2a
      VpcId: !Ref myVPC
      CidrBlock: 10.2.2.0/24
      Tags:
        - Key: Name
          Value: PubSubNet1
  
  PubSubNet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: ap-northeast-2b
      VpcId: !Ref myVPC
      CidrBlock: 10.2.4.0/24
      Tags:
        - Key: Name
          Value: PubSubNet2
          
  # 3. Internet Gateway를 생성하고 VPC에 Attach한다.
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: myIGW
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref myVPC
      InternetGatewayId: !Ref InternetGateway

  # 4. Public Subnet의 Outbound 를 수정한다: 0.0.0.0/0 -> internet gateway
  PublicRoutTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref myVPC
      Tags:
        - Key: Name
          Value: PublicRT

  PublicToIGW:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRoutTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  
  PublicSubnetRTAssociate1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRoutTable
      SubnetId: !Ref PubSubNet1
  
  PublicSubnetRTAssociate2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRoutTable
      SubnetId: !Ref PubSubNet2
  
  # 5. Security Group을 생성하고, 22번 port를 open 한다 (ssh 접속을 위해)
  BastionSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: bastion-sg
      GroupDescription: bation security group
      VpcId: !Ref myVPC
      SecurityGroupIngress:
      - CidrIp: 0.0.0.0/0
        FromPort: "22"
        ToPort: "22"
        IpProtocol: tcp
      - CidrIp: 0.0.0.0/0
        FromPort: "80"
        ToPort: "80"
        IpProtocol: tcp
      - CidrIp: 0.0.0.0/0
        FromPort: "443"
        ToPort: "443"
        IpProtocol: tcp
      Tags:
        - Key: Name
          Value: bastion-sg
  
  # 6. 이미 생성한 VPC, Public Subnet, Security Group과 연결된 EC2를 생성한다.
  BastionEc2Instance:
    Type: AWS::EC2::Instance
    Properties:
      KeyName: !Ref keypairName
      ImageId: ami-00192a6b2a7a94846
      InstanceType: t2.micro
      Tags:
        - Key: Name
          Value: bastion-ec2
      NetworkInterfaces: 
      - AssociatePublicIpAddress: "true"
        DeviceIndex: "0"
        GroupSet: 
          - Ref: "BastionSecurityGroup"
        SubnetId: !Ref PubSubNet1

CloudFormation 으로 인프라 생성하기

CloudFormation -> Create stack -> With new resources (standard) -> Upload a tempalte file -> 사용자 입력 -> 이름 및 파라미터 입력 -> 생성

아래와 같이 Parameters 섹션에 정의된 항목에 대해서 사용자 입력이 필요하다.

CloudFormation -> Stack 선택 -> Resources 을 하면 아래와 같이 Resource가 정상적으로 생성됬음을 확인할 수 있다. 에러가 발생할 경우 Events 탭에서 관련 로그를 확인한다.

반응형