ChatGPT에게 CloudFormation 코드 작성을 부탁해 봤습니다.

ChatGPT에게 CloudFormation 코드 작성을 부탁해 봤습니다.

ChatGPT에게 CloudFormation 코드 작성을 부탁해 봤습니다.
Clock Icon2025.06.05

안녕하세요 클래스메소드 김재욱(Kim Jaewook) 입니다. 이번에는 ChatGPT에게 CloudFormation 코드 작성을 부탁해 봤습니다.

ChatGPT에게 블로그 작성을 부탁해 보기도 했는데, 이와 관련된 내용은 아래 블로그에서 확인할 수 있습니다.

https://dev.classmethod.jp/articles/jw-ask-chatgpt-to-write-a-blog/

ChatGPT에게 부탁할 파라미터를 준비

먼저 ChatGPT에게 부탁할 파라미터를 준비합시다. 이번에는 간단하게 VPC 생성을 부탁할 생각입니다.

복잡하게 생각할 필요없이, 리전, VPC와 서브넷의 CIDR 정도만 지정하고 CloudFormation 코드 작성을 부탁해 봅시다.

다음 파라미터를 이용해서 CloudFormation을 만들어줘

Region : seoul
VPC CIDR : 10.0.0.0/16
Public Subnet1 CIDR : 10.0.1.0/24
Public Subnet2 CIDR : 10.0.2.0/24
Private Subnet1 CIDR : 10.0.11.0/24
Private Subnet2 CIDR : 10.0.12.0/24

첫 번째 결과물

ChatGPT가 생성해 준 첫 번째 결과물은 다음과 같습니다.

AWSTemplateFormatVersion: '2010-09-09'
Description: VPC with 2 public and 2 private subnets in Seoul region

Parameters:
  VpcCidr:
    Type: String
    Default: 10.0.0.0/16
  PublicSubnet1Cidr:
    Type: String
    Default: 10.0.1.0/24
  PublicSubnet2Cidr:
    Type: String
    Default: 10.0.2.0/24
  PrivateSubnet1Cidr:
    Type: String
    Default: 10.0.11.0/24
  PrivateSubnet2Cidr:
    Type: String
    Default: 10.0.12.0/24

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: MyVPC

  InternetGateway:
    Type: AWS::EC2::InternetGateway

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

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PublicSubnet1Cidr
      AvailabilityZone: ap-northeast-2a
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet1

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PublicSubnet2Cidr
      AvailabilityZone: ap-northeast-2c
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet2

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PrivateSubnet1Cidr
      AvailabilityZone: ap-northeast-2a
      Tags:
        - Key: Name
          Value: PrivateSubnet1

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PrivateSubnet2Cidr
      AvailabilityZone: ap-northeast-2c
      Tags:
        - Key: Name
          Value: PrivateSubnet2

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC

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

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

파라미터를 각각 지정해주고 성공적으로 만들어주는 것을 확인할 수 있습니다.

실제로 CloudFormation을 생성해 보면, VPC와 서브넷, 라우팅 테이블, 인터넷 게이트웨이가 문제 없이 연결되어 있습니다. 다만, 이름 태그가 일정하게 설정되어 있지 않는 부분이 조금 거슬리는 것과 [AvailabilityZone: ap-northeast-2a]이 하드코딩되어 있는 부분이 신경쓰이기 때문에 다시 부탁해 봅시다.

jw-chatcloudf-1

두 번째 결과물

이번에는 조금 세세하게 설정을 가해봅시다. 각 리소스에 대한 이름을 추가해서 넣어줍시다. 또한, [AvailabilityZone: ap-northeast-2a] 처럼 하드코딩된 것은 보기 싫으므로 [!Select [ 0, !GetAZs "" ]] 형식으로 코드 수정을 부탁했습니다.

다음 파라미터를 이용해서 CloudFormation을 만들어줘

각 리소스의 이름은 {EnvName}-{SystemName}-resourcename
ex) {EnvName}-{SystemName}-vpc

AvailabilityZone 값을 !Select와 !GetAZs를 사용해 하드코딩 없이 동적으로 설정하도록 수정

Region : seoul
VPC CIDR : 10.0.0.0/16
Public Subnet1 CIDR : 10.0.1.0/24
Public Subnet2 CIDR : 10.0.2.0/24
Private Subnet1 CIDR : 10.0.11.0/24
Private Subnet2 CIDR : 10.0.12.0/24
EnvName : prd
SystemName : test

생성해 준 결과물은 다음과 같습니다.

확실히 파라미터를 포함해서 깔끔하게 정리된 느낌입니다.

AWSTemplateFormatVersion: '2010-09-09'
Description: VPC with 2 public and 2 private subnets using naming convention

Parameters:
  EnvName:
    Type: String
    Default: prd
  SystemName:
    Type: String
    Default: test
  VpcCidr:
    Type: String
    Default: 10.0.0.0/16
  PublicSubnet1Cidr:
    Type: String
    Default: 10.0.1.0/24
  PublicSubnet2Cidr:
    Type: String
    Default: 10.0.2.0/24
  PrivateSubnet1Cidr:
    Type: String
    Default: 10.0.11.0/24
  PrivateSubnet2Cidr:
    Type: String
    Default: 10.0.12.0/24

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-vpc"

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-igw"

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

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PublicSubnet1Cidr
      AvailabilityZone: !Select [ 0, !GetAZs "" ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-public-subnet-1"

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PublicSubnet2Cidr
      AvailabilityZone: !Select [ 1, !GetAZs "" ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-public-subnet-2"

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PrivateSubnet1Cidr
      AvailabilityZone: !Select [ 0, !GetAZs "" ]
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-private-subnet-1"

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PrivateSubnet2Cidr
      AvailabilityZone: !Select [ 1, !GetAZs "" ]
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-private-subnet-2"

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-public-rt"

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

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

CloudFormation을 생성하고 확인해 보면, 한 가지 걸리는 점이 있습니다. Private의 라우팅 테이블의 리소스 명이 설정되어 있지 않은 것인데, 아마 특별한 설정(인터넷 게이트웨이 등)이 없었기 때문에 Private의 라우팅 테이블은 코드에 포함되어 있지 않았던 것 같습니다. 이에 따라 Private의 라우팅 테이블이 기본 생성되는 디폴트 라우팅 테이블로 지정되어 있는 것이 마음에 들지 않으므로 수정해 주도록 합시다.

jw-chatcloudf-2

최종 결과물

Private 라우팅 테이블까지 추가해 주도록 합시다. 이 부분은 사용자가 직접 수정해 줍시다.

AWSTemplateFormatVersion: '2010-09-09'
Description: VPC with 2 public and 2 private subnets using naming convention

Parameters:
  EnvName:
    Type: String
    Default: prd
  SystemName:
    Type: String
    Default: test
  VpcCidr:
    Type: String
    Default: 10.0.0.0/16
  PublicSubnet1Cidr:
    Type: String
    Default: 10.0.1.0/24
  PublicSubnet2Cidr:
    Type: String
    Default: 10.0.2.0/24
  PrivateSubnet1Cidr:
    Type: String
    Default: 10.0.11.0/24
  PrivateSubnet2Cidr:
    Type: String
    Default: 10.0.12.0/24

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-vpc"

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-igw"

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

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PublicSubnet1Cidr
      AvailabilityZone: !Select [ 0, !GetAZs "" ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-public-subnet-1"

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PublicSubnet2Cidr
      AvailabilityZone: !Select [ 1, !GetAZs "" ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-public-subnet-2"

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PrivateSubnet1Cidr
      AvailabilityZone: !Select [ 0, !GetAZs "" ]
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-private-subnet-1"

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PrivateSubnet2Cidr
      AvailabilityZone: !Select [ 1, !GetAZs "" ]
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-private-subnet-2"

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-public-rt"

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

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${EnvName}-${SystemName}-private-rt"

  PrivateSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable

코드 수정이 끝났다면, CloudFormation을 생성하고 결과를 확인해 봅시다.

결과를 확인해 보면, 성공적으로 AWS에서 네트워크 환경을 생성한 것을 확인할 수 있습니다.

jw-chatcloudf-3

마무리

생각보다 깔끔하게 CloudFormation 코드를 작성해 줘서 놀랐습니다. 사용자 요구에 맞게 작성을 하려면 보다 자세한 요구 사항을 적을 필요가 있지만, 직접 코드를 적는 것 보다는 훨씬 편한 것 같습니다. 이번 블로그에서는 비교적 간단한 VPC의 CloudFormation 코드 작성이었지만, 보다 난이도 있는 작업도 충분히 가능할 것 같습니다. 다만, 실제로 동작하고 테스트하는 건 사람의 몫이니 충분한 검토가 필요한 것 또한 사실입니다.

본 블로그 게시글을 읽고 궁금한 사항이 있으신 분들은 jaewookkim533@yahoo.com로 보내주시면 감사하겠습니다.

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.