Post

최종 프로젝트 인프라 구축⑧ - 테라포머(terraformer)로 AWS 클라우드 코드화

최종 프로젝트 인프라 구축⑧ - 테라포머(terraformer)로 AWS 클라우드 코드화

IaC(Infrastructure as Code)

IaC와 테라폼

프로젝트 초기 기획 단계, 최종 서비스를 클라우드에 구현할 것을 예상하고 구성도를 그려보았다.

do11-img1

이렇게 기획했던 것이 여러 오류수정과 최적화를 거쳐…

do11-img2

이렇게 다듬어졌다.

아무튼 클라우드 짬밥(?)이대로 클라우드를 구현했는데 문제는 비용상의 문제(?)로
하루 8시간, 9~18시까지만 AWS를 사용할 수 밖에 없었다.

그 이상 쓰면 지원금 범위를 초과해버려서 할 수 없이 9시에 인프라를 올렸다 6시 전 인프라를 전부 삭제하는 식으로 클라우드를 써야 하니,
매번 인프라를 만들고 지우는 데 30여 분의 시간을 써야만 했다.
성향상 이런 의미없는(?) 반복작업을 굉장히 싫어하기도 하고…

그러다 옆 팀에서 자기들은 테라폼으로 해결했다는 말을 해주었고, 멘토링 때 어렴풋이 들어서 이걸 써보기로 했다.

결론부터 말하자면 이거 만드는 데 이틀을 소모했지만, 결국 명령어 딸깍(?)만으로 일일이 인프라를 구성하지 않게 되었다!

테라폼IaC, 인프라스트럭춰 애즈 코드, 즉 코드로 인프라를 만드는 방법인데

이전 우리가 아르고cd와 헬름형 깃허브 레포를 연동해서 일일이 deployment/service 등을 따로따로 올리지 않게 한 것처럼

미리 코드로 EC2, VPC 등의 명세서를 만들어놓고 terraform apply만 누르면 그거에 맞게 인프라가 생성되는 것이다.

테라폼 사전 준비

근데 당직(当職)은 테라폼으로 어떻게 인프라를 만드는 지 하나도 몰랐으니까 발상을 전환,
일단 수동으로 구성한 인프라를 테라폼으로 전환해보기로 했다.

마침 같은 생각을 한 사람이 당직뿐이 아닌지, 오픈 소스로 다양한 인프라스트럭춰를 테라폼 코드로 전환해주는 테라포머(terraformer)라는 게 존재했다.

테라폼, 테라포머 다운로드

일단 이걸 쓰려면 테라폼부터 받아야 하는데

여기에서 다운로드받을 수 있는데 각자 운영체제와 cpu 종류에 맞는 걸 받아주면 된다.

do11-img3

사실 리눅스나 유닉스(macos) 같은 경우면 그냥 CLI로 install terraform 하면 되지만,
당직 컴은 윈도우이기에 이렇게 파일을 직접 다운로드 받아야 한다.

테라포머도 마찬가지로 여기에 들어가서 Asset 항목에서, 맞는 terraformer-클라우드-운영체제-cpu아키텍춰.exe를 받아주면 된다.

do11-img4

당직의 경우 terraformer-aws-windows-amd64.exe 이겠죠?

do11-img5

이 두 개를 받았으면 알기 쉬운 장소에 넣어주고(예시로 C:\Program files\Terraform)

do11-img6

환경 변수(시스템,유저 다)의 Pathterraform.exe 파일 경로를 입력해주는 식으로 수동 설치해 줘야 한다.

AWS CLI 설치, 키 발급과 로그인

테라폼은 CLI 프로그램이기 때문에, 테라포머랑 연동하려면 AWS CLI도 설치해 거기서 IAM 키를 기반으로 로그인을 해 줘야 한다.

do11-img7

AWS CLI는 그냥 여기 들어가서 받고 설치해주면 끝난다.

설치하고 cmd 창에서 aws --version이 잘 뜨면 되는데, 로그인을 하기 위한 IAM 키를 발급해 줘야 한다.

do11-img8

AWS 콘솔에서 IAM→사용자→(내 계정)→보안 자격 증명→액세스 키 만들기 순서대로 클릭한 다음 사용 사례에서 Command Line Interface(CLI) 선택,
그러면 액세스 키와 비밀 액세스 키가 나오는데 이건 이 화면을 벗어나면 평생 볼 수 없으므로 미리 복사해 준다.
참고로 당연하겠지만 이게 인터넷망에 유출되면 님의 AWS가 공공재가 되어버리니까 실수로 깃허브 퍼블릭 레포 등에 올라가버리면 그 즉시 키를 삭제해

아무튼 키를 복사해놓은 다음 다시 cmd창으로 가서 aws configure 입력,

do11-img9

Access Key Id, Secret Access Key Id에 아까 키를 순서대로 입력하고 나머지 두 개는 그냥 엔터,

이러면 로그인이 끝난다. 이제 님의 컴퓨터는 님 계정의 aws를 맘대로 다룰 수 있다.

테라포머로 aws 임포트

테라포머로 aws 인프라를 불러오려면 테라포머를 실행할 경로에서 versions.tf 파일을 만들어

1
2
3
4
5
6
7
terraform {
	required_providers {
		aws = {
	    version = "~> 6.9.0"
		}
  }
}

이렇게 입력해 준 뒤 terraform init을 , 이 과정이 귀찮다면

do11-img10

do11-img11

여기서 테라폼 플러그인을 (똑같이 클라우드, 버전과 cpu에 따라)받아 준 다음
C:\.terraform.d\plugins\ 경로에 압축 푼 폴더를 넣으면 된다.

(눈치 채셨겠지만, 테라포머는 aws뿐만 아닌 GCP, Azure 등의 타 클라우드도 지원한다. 이건 테라폼도 동일하지만)

아무튼 이제 준비가 모두 끝났다.
terraformer import aws list를 하면 테라포머에서 지원하는 aws 인프라 종류가 나타난다.

do11-img12

당직은 현재 aws에 vpc, igw(인터넷 게이트웨이), nat(NAT 게이트웨이) 등등을 올려 놓았으므로

do11-img13

terraformer import aws --resources=(임포트하고자 싶은 인프라, 쉼표로 구분) --region=(내 리전, 서울의 경우 ap-northeast-2)

이렇게 하면 임포트가 된다.

주의할 점으로는 이런 프로그램이 다 그렇듯이 버그가 많아, AWS 상에 DocumentDB와 RDS가 둘 다 있을 시, rds를 임포트하면 설정이 docdb의 것으로 덮어씌워져 버린다.
즉 위 사진은 잘못된 것으로 rds를 임포트할 때는 반드시 DocumentDB 클라스터를 삭제해 주자.

버그픽스, 합치기

임포트가 완료되면 위 사진처럼 서비스별로 테라폼 파일이 폴더화돼서 나온다.

각 폴더에 들어가 terraform state replace-provider -auto-approve -- -/aws hashicorp/aws로 버그를 수정해 줘야 한다.

do11-img14

이 다음 terraform init으로 초기화한 다음, terraform plan으로 준비한 다음 terraform apply로 aws 상에 적용하면 되지만…

역시 이런 게 한 방에 될 리가 없다. (이 프로그램은 구글 클라우드에서 만든 오픈소스 프로그램이라 하네요)

어차피 당직들은 테라포머를 사용한 이유가 일종의 템플릿을 만들기 위함이므로
오류를 수정하고, 서비스별로 terraform apply하는 게 아닌 한 방에 모든 인프라가 생성되도록 한 폴더로 tf파일들을 합쳐야 한다.

여기서 설명하기에는 여백이 부족하므로 기초 원칙만 말하겠다.

우선 eks_cluster.tfec2_instance 같은 서버형 인스턴스 테라폼을 보면

1
2
3
subnet_ids              = ["subnet-1uifdhsp3jvn", "subnet-1kbvnczhoiuq"]
...
vpc_security_group_ids = ["sg-9379817t5ui2h3hfdskj"]

이런 식으로 보안 그룹, 써브넷 id 등이 하드코딩되어 있는데 이런 것들을 변수로 바꿔 줘야 한다.
당연하겠지만 이것들은 매번 지우고 생길 때마다 id값이 바뀌기 때문이다.

보안 그룹을 예로 들면, security_group.tf

1
2
3
resource "aws_security_group" "tfer-sg-9379817t5ui2h3hfdskj"{
    ...
}

이런 식으로 resource "aaa" "bbb"{} 들이 있을 텐데, 이 resource 한 개가 하나의 보안 그룹에 해당된다.

bbb는 tfer-(보안 그룹 ID) 형식이기에 일치하는 걸 찾아다 하드 코딩을 "${aaa.bbb.id}" 이렇게 바꿔주면 된다.

하드 코딩은 보안 그룹, 써브넷 외에도 ..._id 처럼 id 값에 해당되는 부분 거의 대부분에 있으니까
각각에 해당되는 인프라 tf파일의 resource명을 찾아 위처럼 바까주면 된다.

참고로 bbb에 해당되는 tfer-(ID명) 이 부분도 나중에 관리하기 어려워지니까 알기 쉽게 바꿔주되,
그럴 때마다 outputs.tf에 있는 동일한 부분도 바꿔줘야 한다.

사실 위의 여백이 없어 다 못 적는다는 건 농담이 아닌,
매번 값을 바꿔가고 수정하며 terraform apply를 해 오류를 하나씩 없애는 등 시행착오를 많이 해 봐야 완성이 된다. 진짜로!

합칠 때 각종 시행착오들

output.tf 관련

각 폴더마다 output.tfprovider.tf 파일이 있을 텐데, provider.tf는 모든 폴더가 동일한 내용이지만 output.tf는 각 인프라별로 고유해 합쳐야 한다.

예로 vpc의 output.tf

1
2
3
output "aws_vpc_asso-rtb-main_id" {
  value = "${aws_vpc.cloud-vpc.id}"
}

이렇게 있고 igw의 output.tf

1
2
3
output "aws_internet_gateway_cloud-igw_id" {
  value = "${aws_internet_gateway.cloud-igw.id}"
}

이럴 때 둘을 합치면 output.tf

1
2
3
4
5
6
7
8
9
#rds
output "aws_vpc_asso-rtb-main_id" {
  value = "${aws_vpc.cloud-vpc.id}"
}

#igw
output "aws_internet_gateway_cloud-igw_id" {
  value = "${aws_internet_gateway.cloud-igw.id}"
}

이런 식으로 (.tf파일은 #가 주석이다)

참고로 output.tfterraform apply 시의 반환 값 지정, provider.tf는 테라폼의 클라우드 엔진(?) 설정이라 보면 된다.

반환 값을 왜 지정하냐면, 테라폼은 이 반환 값을 보고 현재 상태를 저장했다, 설정이 바뀌거나 특정 인프라만 추가/제거할 수 있기 때문이다.

provider.tf의 내용은 위에서 말한 versions.tf 값과 똑같아

오류나는 설정 삭제

그리고 테라포머 특유의 버그 문제로 subnet.tf

1
2
enable_lni_at_device_index
map_customer_owned_ip_on_launch 

각 써브넷에 있는 위 두 줄을 제거해 줘야 하고 vpc.tf

1
ipv6_netmask_length

이걸 제거해 줘야 하며, nat_gateway.tf

1
secondary_private_ip_address_count

이 줄을, ec2_instance.tf

1
2
3
cpu_options {
  ...
}

이 부분을 지워야 terraform apply시 에라가 나지 않는다.

variables.tf는 제거해야

테라포머를 쓸 때 중요한 부분인데 variables.tf가 있는 폴더의 경우,
${} 중 ${data.}로 시작하는 변수들을 전부 위에서 말한 ${aaa.bbb.id} 형식으로 교체하고, variables.tf는 지워 준다.

저게 있으면 terraform plan이 되지 않더라구

docdb_cluster_parameter_group.tf도 삭제

do11-img15

docdb를 임포트할 때 나오는 docdb_cluster_parameter_group.tf는 docdb의 파라메터 그룹을 생성하는 부분인데, 어차피 당직들은 aws에서 기본 제공하는 파라메터 그룹(default.docdb5.0)을 사용할 것이다.

tf 파일을 삭제하고, docdb_cluster.tf에 있는 관련 부분도 삭제해 주자.

마무리

do11-img16

아무튼 이런 식으로 하나씩 오류를 해결해 나가서 terraform apply를 했을 때,

기존에 뿜었던 오류들 없이 인프라가 생성되는 것을 보니 도파민이 터지더라고

테라포머는 당직처럼 맨땅에 헤딩 용도로 사용할 것보다, 기존 인프라를 기반으로
콘솔에서 무언가를 바꿨을 때 테라폼 값을 확인하는 것이 가장 유용하다는 것을 깨닫게 되었다.
(결국은 테라폼을 배워야 한다는 소리)

그럼 다음 시간에는 클라우드 1차 작업인 프로메테우스-그라파나 모니터링으로 돌아오겠다.

테라폼 파일 공유(25.09.18)

테라폼 깃허브 링크

프로젝트 구축할 때 사용한 테라폼 파일을 보안 정보를 검열해서 깃허브로 공유하겠습니다.

인프라 상세 정보와 사용 방법은 깃허브 README 파일에 적혀 있어요!!

This post is licensed under CC BY 4.0 by the author.