ChatGPT에게 CloudFormation 코드 작성을 부탁해 봤습니다.
안녕하세요 클래스메소드 김재욱(Kim Jaewook) 입니다. 이번에는 ChatGPT에게 CloudFormation 코드 작성을 부탁해 봤습니다.
ChatGPT에게 블로그 작성을 부탁해 보기도 했는데, 이와 관련된 내용은 아래 블로그에서 확인할 수 있습니다.
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]이 하드코딩되어 있는 부분이 신경쓰이기 때문에 다시 부탁해 봅시다.
두 번째 결과물
이번에는 조금 세세하게 설정을 가해봅시다. 각 리소스에 대한 이름을 추가해서 넣어줍시다. 또한, [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의 라우팅 테이블이 기본 생성되는 디폴트 라우팅 테이블로 지정되어 있는 것이 마음에 들지 않으므로 수정해 주도록 합시다.
최종 결과물
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에서 네트워크 환경을 생성한 것을 확인할 수 있습니다.
마무리
생각보다 깔끔하게 CloudFormation 코드를 작성해 줘서 놀랐습니다. 사용자 요구에 맞게 작성을 하려면 보다 자세한 요구 사항을 적을 필요가 있지만, 직접 코드를 적는 것 보다는 훨씬 편한 것 같습니다. 이번 블로그에서는 비교적 간단한 VPC의 CloudFormation 코드 작성이었지만, 보다 난이도 있는 작업도 충분히 가능할 것 같습니다. 다만, 실제로 동작하고 테스트하는 건 사람의 몫이니 충분한 검토가 필요한 것 또한 사실입니다.
본 블로그 게시글을 읽고 궁금한 사항이 있으신 분들은 jaewookkim533@yahoo.com로 보내주시면 감사하겠습니다.