서론
Windows 환경 + vscode로 진행했다.
IaC(Infrastructure as Code)인 테라폼을 공부하는 겸 AWS 인프라를 구축해보고자 한다.
🎈 기본 개념
1. 프로바이더 (Provider)
테라폼과 외부서비스를 연결하는 기능하는 모듈
즉, AWS 서비스의 자원을 생성하기 위해선 AWS 프로바이더를 먼저 준비해야한다.
2. 리소스 (Resource)
특정 프로바이더가 제공해 주는 조작 가능한 대상의 최소 단위
즉, AWS 프로바이더는 aws_instance 리소스 타입을 제공
이 리소스 타입 사용해서 EC2의 가상 머신 리소스 선언 및 조작이 가능
3. 계획 (Plan)
테라폼 프로젝트 디렉터리 아래 모든 .tf 파일의 내용을 실제로 적용가능한지 확인하는 작업을 계획
테라폼에서는 이를 terraform plan 명령어로 제공
명령어 실행 시 어떤 리소스 생성, 수정, 실행, 삭제될지 계획 보여준다
4. 적용 (Apply)
테라폼 프로젝트 디렉터리 아래 모든 .tf 파일의 내용대로 리소스 생성, 수정, 삭제하는 일을 적용
테라폼에서는 이를 terraform apply 명령어로 제공
변경 예정사항 plan을 통해 확인 가능
✅ AWS 인프라 구축해 보기
1. AWS 프로바이더 정의
프로젝트 디렉터리와 테라폼 파일 2개를 생성해 준다.
원칙은 없으니 자신이 원하는 디렉토리명을 만들어주자.
테라폼은 디렉터리에 있는 모든 .tf 파일 읽고 리소스 생성, 수정, 삭제 작업을 한다.
mkdir aws_infra
touch provider.tf web_infra.tf
이후 provider.tf 파일을 작성해 주자.
사용자 정보와 리전을 의미하는 내용이다.
참고로 보안을 위해 root 계정이 아닌 IAM 사용자를 만들어서 하는 것을 추천한다.
#provider.tf 파일 내용
provider "aws" {
access_key = "<AWS_ACCESS_KEY>"
secret_key = "<AWS_SECRET_KEY>"
region = "ap-northeast-2"
}
✅ 추가적으로 이러한 민감한 정보를 저장소에 기록하지 않도록 주의해야 한다.
✅ 이러한 인증 정보를 프로바이더 속성 값 설정이 아닌 테라폼 실행하는 환경에 직접 환경변수로 정의하면 노출 피할 수 있다.
# 환경변수 설정 방법
$ export AWS_ACCESS_KEY_ID="<AWS_ACCESS_KEY_ID>" # access_key
$ export AWS_SECRET_ACCESS_KEY="<AWS_SECRET_ACCESS_KEY>" # secret_key
$ export AWS_DEFAULT_REGION="ap-northeast-2" # region
만약 환경변수를 설정했다면, 다음과 같이 프로바이더를 정의하면 된다.
#provider.tf 파일 내용
provider "aws" {}
2. init 하기
프로바이더 설정이 마무리 됐으니, 프로젝트 디렉터리에서 다음 명령어를 수행
terrafrom init
3. EC2용 SSH 키 페어 생성하기
EC2 생성하기 전 키페어를 생성하여 EC2 인스턴스에 접근할 준비를 하자
3-1. HCL 언어로 리소스 정의하기
web_infra.tf 파일에 다음 내용을 추가하자
resource "aws_key_pair" "web_admin" {
key_name = "web_admin"
public_key = "<PUBLIC_KEY>"
}
"aws_key_pair" : 리소스 타입의 이름을 의미, 프로바이더에서 제공하는 리소스 타입이름은 한정적
"web_admin" : 리소스에 붙이는 임의 이름 *참고로 AWS에 정의되는 이름은 아니다!!
key_name : AWS에 정의하는 이름
public_key : 접속에 사용할 공개키 값 필요
키가 없다면 다음 명령어로 SSH 키 생성 가능
#SSH 키 생성
#참고로 Powershell 에서 본인은 진행 with VSC
ssh-keygen -t rsa -b 4096 -C "{본인이메일주소}" -f "$HOME/.ssh/web_admin"
키 생성했다면 다시 web_infra.tf를 다음과 같이 정의할 수 있다.
resource "aws_key_pair" "web_admin" {
key_name = "web_admin"
public_key = file("~/.ssh/web_admin.pub")
}
file() 함수는 경로를 문자열로 읽음
4. Plan 해보기
앞에서 만든 aws키페어 리소스 생성이 aws에 실제로 가능한지 확인해볼 것이다.
프로젝트 디렉터리에서 다음 명령어 수행해 보자
terraform plan
그렇다면 테라폼이 어떤 작업 수행할지 계획을 보여준다
+ 생성하겠다는 의미이다.
5. Apply 해보기
계획(Plan)을 이제 적용해보고자 한다.
다음 명령어를 수행하자
terraform apply
Plan을 보여주고 yes를 입력하여서 Apply 하면 된다.
✅ 기억해야 할 것은 plan을 습관화하고 Apply를 함으로써 변경사항을 수시로 확인하는 것이다!
6. 보안그룹 열기
이번에 적용할 리소스는 aws_security_group, 즉 보안그룹이다.
EC2 인스턴스에 접근하기 위해선 SSH port를 열어줘야 하기 때문이다. 따라서 보안그룹을 만들어줘야 한다.
webinfra.tf 에서 다음 코드를 작성하자
resource "aws_security_group" "ssh" {
name = "allow_ssh"
description = "ssh port open"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
name : 보안그룹 이름
description : 보안그룹 설명
ingress : 인바운드 속성
from_port, to_port : 열어줄 포트를 의미
protocol : 통신 프로토콜
cidr_blocks : 보안그룹 적용할 사이더 범위
이후 plan을 적용해 보자
terraform plan
apply 적용해 보기
terraform apply
7. VPC default 보안그룹 불러오기
테라폼은 클라우드에 이미 정의되어 있는 리소스를 데이터 소스로 불러오는 기능을 제공
따라서 기본 default 보안그룹을 불러와보자
data "aws_security_group" "default" {
name = "default"
}
8. EC2 인스턴스 정의하기
EC2 인스턴스를 정의하는 리소스는 다음과 같다.
resource "aws_instance" "web" {
ami = "ami-0e6f2b2fa0ca704d0" #2024.06.20 기준 ubuntu AMI ID
instance_type = "t2.micro"
key_name = aws_key_pair.web_admin.key_name
vpc_security_group_ids = [
aws_security_group.ssh.id,
data.aws_security_group.default.id
]
}
ami : 에는 본인이 희망하는 EC2 인스턴스 AMI ID를 설정하면 된다. 본인은 ubuntu로 설정
key_name : 키페어 리소스 aws_key_pair.web_admin 에서 설정했었던 key_name이라는 속성을 참조한다.
vpc_security_group_ids : 배열 형식이고, 위에서 추가한 보안 그룹 ssh의 id 속성과 default 보안 그룹의 id 속성을 참조한다.
이후 terraform plan을 실행시켜 주자
이후 terraform apply 실행
..?
에러가 발생해서 보아하니 subnet 이 없었다.. 흠 하여튼 그래서 본인은 서브넷을 resource에 추가를 해줬다.
resource "aws_instance" "web" {
ami = "ami-0e6f2b2fa0ca704d0" #2024.06.20 기준 ubuntu AMI ID
instance_type = "t2.micro"
subnet_id = "subnet-01df07e67164e0468" #서브넷 추가
key_name = aws_key_pair.web_admin.key_name
vpc_security_group_ids = [
aws_security_group.ssh.id,
data.aws_security_group.default.id
]
associate_public_ip_address = true
}
9. EC2 인스턴스 접속해 보기
성공적으로 생성했으니 한번 접속해 보겠다.
SSH 접속을 위해 인스턴스의 ip를 조회해 보겠다
terraform console
> aws_instance.web.public_ip
SSH로 출력된 ip에 접속해 보자
ssh -i ~\.ssh\web_admin ubuntu@13.125.216.105
10. RDS 정의하기
이제 AWS 데이터베이스 서비스인 RDS의 MySQL 리소스를 만들어보겠다.
#2024.06.20 기준
resource "aws_db_instance" "web_db" {
allocated_storage = 20 #최소용량 20GB
engine = "mysql"
engine_version = "8.0.35" #엔진버전
instance_class = "db.t3.micro"
username = "admin"
password = "{원하는 비밀번호입력 8자리 이상}" #DB 비밀번호
skip_final_snapshot = true #인스턴스 제거시 스냅샷 만들지 않고 제거할지 결정
}
정확한 엔진버전 등 정보들은 AWS RDS에 접속하여 확인하는 수밖에 없다.
이후 Plan, Apply를 적용시켜서 생성시켜 주자
성공적으로 생성!
11. EC2 인스턴스로 RDS 접속해 보기
이제 생성한 EC2에 MySQL을 설치하고 RDS에 접속해보고자 한다
그러기 위해선 RDS 엔드포인트 정보가 필요하다
terraform console
> aws_db_instance.web_db.endpoint
이후 EC2에 MySQL을 설치하자
본인은 Ubuntu 인스턴스이다
sudo apt install mysql-server
설치 후 RDS endpoint를 활용하여 mysql에 접속해 보자
참고로. com까지이다.
mysql -h {RDS ENDPOINT} -u admin -p
성공적으로 RDS까지 접속이 완료!!
✅ AWS 인프라 정리하기
이제 모든 인프라 구축을 끝냈으니 정리를 해볼 시간이다.
생성된 인프라를 한 번에 종료할 수 있는 것도 테라폼의 장점이다.
다음 명령어를 통해서 모든 리소스를 정리할 plan을 확인할 수 있다
terraform plan -destroy
이 계획 즉 plan을 실행시키려면 apply를 하면 된다.
terraform apply -destroy
yes를 입력하면 리소스를 모두 제거할 수 있다
실제 모든 리소스가 제거됐음을 확인할 수 있었다.
마무리
처음으로 테라폼을 이용해 보니 오히려 번거로운 부분도 있었던 거 같다.
하지만 코드를 활용함으로써 인프라 상태를 확인하기가 더 쉬울 수가 있고, 기록이 남기 때문에 관리가 더 수월할 거 같다는 생각이 들었다.
또한 코드를 저장소에 관리함으로써 인프라를 공유할 수도 있고,,
여러모로 재밌는 테라폼 첫 경험이었던 거 같다.