🕹 AWS CLI를 통해 AWS 인프라를 구축해보자

서론

콘솔을 통해서 인프라를 구축할 수 있지만 Medium 글을 통해서 배웠던 Bash 스크립트를 통해서
몇 초안에 다음 AWS 아키텍처를 구축했던 것을 복습해보고자 한다.

  • VPC
  • VPC에 연결된 인터넷 게이트웨이
  • 퍼블릭 서브넷
  • 퍼블릭 서브넷 및 인터넷 게이트웨이에 대한 라우팅 규칙과 연결된 라우팅 테이블
  • Java 및 Docker 엔진이 설치된 EC2 인스턴스 2개.
    두 인스턴스는 작업자 노드(t2.micro 크기) 마스터 노드(t2.small 크기)입니다.
    SSH를 통해 원격으로 액세스 할 수 있어야 하며 서로 연결할 수 있어야 합니다.
  • 모든 리소스는 ap-apnortheast-2 리전에 있어야 합니다.

 

 

인프라 구축 전에 필요한 것

1. AWS 계정

2. 액세스 키 ID와 보안 액세스 키가 있는 IAM 사용자

3. 터미널 이용 (본인은 윈도우 컴퓨터로 진행해서 Git Bash를 사용했다)

4. AWS CLI 설치 : https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/getting-started-install.html

 

 

IAM 사용자 생성하기

 AWS 계정을 생성한 후 CLI를 사용하여 AWS 리소스를 관리하려면 IAM 사용자를 생성해야 한다.

1. AWS 로그인 - IAM 으로 이동

 

2. 사용자 생성 - 직접 정책 연결 - AdministratorAccess 정책 설정 (관리자 권한 부여) 

 

3. 이후 생성한 사용자 클릭 - 보안 자격 증명 - 액세스 키 만들기 (AWS CLI 통한 인증에 사용된다)

 

4. Command Line Interface(CLI) 선택 후 - CSV 파일 다운로드(✅중요)

참고로 절~대 유출되면 안된다.

 

5. 이후 터미널 열어서 aws configure 명령어 입력 및 설정을 하기

4번 단계에서 다운로드한 .csv 파일에 입력할 내용이 적혀있다.

 

인증이 끝나면 이제 모든 명령이 AWS 계정, IAM 사용자 및 사전 정의된 지역에 대해 실행된다.

즉, ap-northeast-2 리전에서 본인이 생성한 IAM 사용자로
AWS 구성을 실행한 후 ec2 인스턴스를 생성하는 명령을 실행하면 ec2 인스턴스가 AWS 계정에서 시작된다.

 

 

 

AWS 인프라 프로비저닝 Bash 스크립트 생성

1. 소프트웨어 스크립트 작성하기

EC2 인스턴스에 필요한 소프트웨어를 설치하는 스크립트를 먼저 작성한다.

본 스크립트를 통해서 EC2는 생성과 동시에 소프트웨어를 설치할 것이다.

sh 파일명은 : software.sh

참고로 본인은 바탕화면에 폴더를 만들고 거기에 sh 파일을 넣어놨다.
#!/bin/bash

#Update and upgrade packages
sudo apt update -y
sudo apt upgrade -y

#Install Docker
sudo apt install docker.io -y
sudo usermod -a -G docker $USER

#Install Java
sudo apt install -y openjdk-11-jre-headless

 

2. AWS 인프라 구축 스크립트 작성하기

글의 핵심적인 파트이다. 차근차근 인프라 구축 코드를 살펴보겠다.

 

1. VPC 생성

#!/bin/bash

REGION="ap-northeast-2"

#Create VPC
#minho_cli_vpc 라는 이름으로 만들 것이다.
VPC_ID=$(aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--tag-specification 'ResourceType=vpc,Tags=[{Key=Name,Value=minho_cli_vpc}, {Key=project,Value=minhocloud}]' \
--region $REGION \
--output text \
--query 'Vpc.VpcId')

echo "VPC $VPC_ID created successfully."

 

 

2. Internet Gateway  생성

attach-internet-gateway 명령어를 통해서 VPC와 연결한다.

#Create Internet Gateway
IGW_ID=$(aws ec2 create-internet-gateway \
--tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=minho_cli-igw}, {Key=project,Value=minhocloud}]' \
--output text \
--query 'InternetGateway.InternetGatewayId')

echo "IGW $IGW_ID created successfully."

#Attach Internet Gateway to VPC
aws ec2 attach-internet-gateway \
--internet-gateway-id $IGW_ID \
--vpc-id $VPC_ID

echo "IGW $IGW_ID successfully attached to VPC $VPC_ID."

 

3. Public Subnet 생성

#Create public subnet
SUBNET_PUBLIC_AZ="ap-northeast-2a"
SUBNET_ID=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.0.0/24 \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=minho_cli_subnet}, {Key=project,Value=minhocloud}]' \
--availability-zone $SUBNET_PUBLIC_AZ \
--region $REGION \
--output text \
--query 'Subnet.SubnetId')

echo "Subnet $SUBNET_ID created successfully."

#Enable subnet to auto-assign public IP (퍼블릭 IP 할당)
aws ec2 modify-subnet-attribute --subnet-id $SUBNET_ID --map-public-ip-on-launch
echo "Public IP auto-assign enabled successfully."

 

 

4. Routing Table 생성

Routing Table 생성 - Routing Table에 IGW 경로 생성 - Routing Table을 Subnet 연결

#Create route table
RT_ID=$(aws ec2 create-route-table --vpc-id $VPC_ID --output text --query 'RouteTable.RouteTableId' \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=minho_cli_rtb}, {Key=project,Value=minhocloud}]')

echo "Route Table $RT_ID created successfully."



#Create route to internet gateway
aws ec2 create-route --route-table-id $RT_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID

echo "Route to the IGW $IGW_ID created successfully."


#Associate the subnet with the route table
aws ec2 associate-route-table --subnet-id $SUBNET_ID --route-table-id $RT_ID

echo "Subnet $SUBNET_ID associated with route table $RT_ID."

 

 

5. 보안그룹 생성

SSH 및 ICMP (ping Test 위한)를 허용하는 보안그룹을 생성한다.

#Create security group
SG_ID=$(aws ec2 create-security-group \
    --group-name project1_sg \
    --description "SG to allow SSH Access" \
    --tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=minho_cli_sg_}, {Key=project,Value=minhocloud}]' \
    --vpc-id $VPC_ID \
    --output text \
    --query 'GroupId')

echo "Security group $SG_ID created successfully."

#Enable the security group to allow SSH and ICMP access
aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 22 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol icmp --port -1 --source-group $SG_ID
echo "Security group $SG_ID authorized for SSH and ICMP ingress."

 

6. 키 생성

인스턴스에  SSH 연결 위한 Key를 생성하는 것이다.

(스크립트를 실행하는 것과 동일한 폴더에 있음).

#Create key-pair 
#키이름 수정하자 (minho_cli_key)
aws ec2 create-key-pair \
--key-name minho_cli_key \
--key-type rsa \
--query 'KeyMaterial' \
--output text \
> minho_cli_key.pem 

echo "Key-pair 'minho_cli_key.pem' created successfully."

 

7. Instance 생성

MasterNode, WorkerNode를 생성한다.

자신이 만든 key로 수정을 해야 하며 EC2 이미지 이름도 수정하길 권고한다.

이미지 명은 EC2 생성에서 확인할 수 있다.

#Create EC2 Instance Master-Node-1

MASTER_NODE=$(aws ec2 run-instances \
    --image-id {원하는 이미지 명} \ 
    --count 1 \
    --instance-type t2.small \
    --key-name minho_cli_key \
    --subnet-id $SUBNET_ID \
    --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=minho_cli_master-node-01}, {Key=project,Value=minhocloud}]' \
    --user-data file://software.sh \
    --security-group-ids $SG_ID \
    --output text \
    --query 'Instances[0].InstanceId')

    echo "Instance Master Node $MASTER_NODE created successfully."


#Create EC2 Instance Worker-Node-1

WORKER_NODE1=$(aws ec2 run-instances \
    --image-id {원하는 이미지 명} \
    --count 1 \
    --instance-type t2.micro \
    --key-name minho_cli_key \
    --subnet-id $SUBNET_ID \
    --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=minho_cli_worker-node-01}, {Key=project,Value=minhocloud}]' \
    --user-data file://software.sh \
    --security-group-ids $SG_ID \
    --output text \
    --query 'Instances[0].InstanceId')

echo "Instance Worker Node 1 $WORKER_NODE1 created successfully."

 

 

 

전체 스크립트 

#!/bin/bash

REGION="ap-northeast-2"

#Create VPC
VPC_ID=$(aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--tag-specification 'ResourceType=vpc,Tags=[{Key=Name,Value=minho_cli_vpc}, {Key=project,Value=minhocloud}]' \
--region $REGION \
--output text \
--query 'Vpc.VpcId')

echo "VPC $VPC_ID created successfully."

#Create Internet Gateway
IGW_ID=$(aws ec2 create-internet-gateway \
--tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=minho_cli-igw}, {Key=project,Value=minhocloud}]' \
--output text \
--query 'InternetGateway.InternetGatewayId')

echo "IGW $IGW_ID created successfully."

#Attach Internet Gateway to VPC
aws ec2 attach-internet-gateway \
--internet-gateway-id $IGW_ID \
--vpc-id $VPC_ID

echo "IGW $IGW_ID successfully attached to VPC $VPC_ID."

#Create public subnet
SUBNET_PUBLIC_AZ="ap-northeast-2a"
SUBNET_ID=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.0.0/24 \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=minho_cli_subnet}, {Key=project,Value=minhocloud}]' \
--availability-zone $SUBNET_PUBLIC_AZ \
--region $REGION \
--output text \
--query 'Subnet.SubnetId')

echo "Subnet $SUBNET_ID created successfully."

#Enable subnet to auto-assign public IP (퍼블릭 IP 할당)
aws ec2 modify-subnet-attribute --subnet-id $SUBNET_ID --map-public-ip-on-launch
echo "Public IP auto-assign enabled successfully."

#Create route table
RT_ID=$(aws ec2 create-route-table --vpc-id $VPC_ID --output text --query 'RouteTable.RouteTableId' \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=minho_cli_rtb}, {Key=project,Value=minhocloud}]')

echo "Route Table $RT_ID created successfully."



#Create route to internet gateway
aws ec2 create-route --route-table-id $RT_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID

echo "Route to the IGW $IGW_ID created successfully."


#Associate the subnet with the route table
aws ec2 associate-route-table --subnet-id $SUBNET_ID --route-table-id $RT_ID

echo "Subnet $SUBNET_ID associated with route table $RT_ID."

#Create security group
SG_ID=$(aws ec2 create-security-group \
    --group-name project1_sg \
    --description "SG to allow SSH Access" \
    --tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=minho_cli_sg_}, {Key=project,Value=minhocloud}]' \
    --vpc-id $VPC_ID \
    --output text \
    --query 'GroupId')

echo "Security group $SG_ID created successfully."

#Enable the security group to allow SSH and ICMP access
aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 22 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol icmp --port -1 --source-group $SG_ID
echo "Security group $SG_ID authorized for SSH and ICMP ingress."

#Create key-pair 
aws ec2 create-key-pair \
--key-name minho_cli_key \
--key-type rsa \
--query 'KeyMaterial' \
--output text \
> minho_cli_key.pem 

echo "Key-pair 'minho_cli_key.pem' created successfully."


#Create EC2 Instance Master-Node-1
MASTER_NODE=$(aws ec2 run-instances \ 
--image-id ami-0e6f2b2fa0ca704d0 \ 
--count 1 \ 
--instance-type t2.small \ 
--key-name minho_cli_key \ 
--subnet-id $SUBNET_ID \ 
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=minho_cli_master-node-01}, {Key=project,Value=minhocloud}]' \ 
--user-data file://software.sh \ 
--security-group-ids $SG_ID \ 
--output text \ 
--query 'Instances[0].InstanceId')

echo "Instance Master Node $MASTER_NODE created successfully."


#Create EC2 Instance Worker-Node-1
WORKER_NODE1=$(aws ec2 run-instances \
    --image-id ami-0e6f2b2fa0ca704d0 \ 
    --count 1 \ 
    --instance-type t2.micro \ 
    --key-name minho_cli_key \ 
    --subnet-id $SUBNET_ID \ 
    --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=minho_cli_worker-node-01}, {Key=project,Value=minhocloud}]' \ 
    --user-data file://software.sh \ 
    --security-group-ids $SG_ID \ 
    --output text \ 
    --query 'Instances[0].InstanceId')

echo "Instance Worker Node 1 $WORKER_NODE1 created successfully."

 

 

테스트해보기

#실행 전 권한주기
chmod u+x aws_setup.sh 
chmod u+x software.sh

이제 스크립트 파일을 실행시킴으로써 AWS 인프라를 구축해 보고자 한다.

aws_setup.sh 에 인프라 구축 코드를 넣고 실행시켜보자

 

생성되는 과정
EC2 생성된 모습

 

docker랑 Java 설치 된 모습
Master -> Worker로 Ping Test 성공

 

 

 

마무리

이로서 코드를 통해서 AWS 인프라를 10초도 안되게 구축하는 과정을 살펴봤다.

VPC삭제, 인스턴스 종류, 키 제거 등 깔끔하게 삭제하고 마무리하자!