본문 바로가기
IT/Terraform

Terraform - Module, Provisioning

by 스마일엔지니어 2025. 2. 5.

terraform init이 수행하는 3가지

1. provider plugin

2. backend

3. module  // 보통 모듈을 추가할 때마다 init을 함

 

모듈 지역화 (Module Localization)

: 보통 입력변수를 모듈을 참조할 때 동적으로 변화하는 환경에서 작업 수행을 목적으로 모듈에서 변수를 정의해야 하는데 특정 변수를 노출하고 싶지 않을 때 사용 (다른 외부에서 입력을 받지 않고 모듈 내에서만 변수를 사용)

↔ 외부 공개 무방하다면 모듈 입력해도 됨

 

- vi ~/terraform-demo/modules/service/webserver-cluster/main.tf 이동

 

 

modules에서만 이용되는 변수 입력 (locals란 블록 이용)

→ root 모듈에선 사용할 수 X

 

 

LB Listener의 포트부분과 aws_security_group의 ingress와 egress 부분을 모두 로컬 변수를 참조하도록 정정한다.

(egress 부분에 to_port 부분 _ 빼두기!! - 에러냄)

 

 

apply 했을 때 로컬 변수로만 실행했으므로  어제와 똑같이 변화없이 결과가 출력된 것을 확인할 수 있다.

 

 

-현재까지의 구성을 도식화한 것이다. stage 하위 디렉토리가 루트 모듈이고 modules는 외적 모듈이어서 modules에 localization하여 stage에서 apply했을 때 어제 결과와 변화가 없는 것이다.

(왜냐하면 stage에서는 local을 불러들일 수 없기 때문이다.)

 

 

현재 위치에 대한 트리구조

 

 

모듈 출력

 

- vi ~/terraform-demo/modules/service/webserver-cluster/main.tf 이동

 

 

- vi ~/terraform-demo/stage/service/webserver-cluster/main.tf 이동

 

 

각각의 출력 변수 선언

 

 

apply를 했을 때 stage main.tf에서 정의된 alb_dns_name이 출력으로 떨어지는 것을 확인할 수 있다.

module 디렉토리 밑 alb_dns_name은 aws_lb에서 참조되고 stage main.tf로 전달한 것이고 이가 출력으로 나온 것이다.

 

 

모듈에서 고려해야 할 사항 2가지

 

- 파일 경로

1. 파일의 경로를 지정할 때 어떤 경로로 지정하는 지 체크해야 함.

2. templatefile 호출 시 path.module 사용 (상대 경로로 입력할 수 있게 해줌) // ${path.module}

 

- vi ~/terraform-demo/stage/service/webserver-cluster/main.tf 이동

 

 

 

단순한 파일명이 아닌 경로를 참조하는 식으로 정정함

 

해당 user-data.sh 파일을 삭제하고 apply를 실행했을 때, 파일 삭제됐음에도 불구하고 경로를 참조하기 때문에 apply 정상적인 결과가 나오고 변화가 없었음을 확인할 수 있다.

 

- 인라인 블록

1. 인라인 블록과 별도의 리소스를 혼합하여 사용하려고 하면 Terraform의 설계 방식으로 인해 구성이 충돌하고 서로 덮어쓰는 오류가 발생한다. 둘 중 하나를 사용해야 하며 둘 중에서 별도의 리소스를 사용하는 것을 권장한다. 별도의 리소스를 사용하면 어디에든 추가할 수 있다는 장점이 있지만, 인라인 블록은 리소스를 생성하는 모듈 내에서만 추가할 수 있다. 따라서 별도의 리소스만 사용하면 모듈이 더욱 유연하고 구성 가능하다.

 

 

모듈 버져닝 (Module Versioning)

스테이징 환경과 프로덕션 환경이 모두 동일한 모듈 폴더를 가리키는 경우 해당 폴더를 변경하는 즉시 다음 배포 시 두 환경 모두에 영향을 미친다. 스테이징에서 한 버전(예: v0.0.2)을 사용하고 프로덕션에서 다른 버전(예: v0.0.1)을 사용할 수 있도록 버전이 지정된 모듈을 만드는 것입니다. 파일 경로 외에도 Terraform은 Git URL, Mercurial URL 및 임의 HTTP URL과 같은 다른 유형의 모듈 소스를 지원한다.

 

+ 태그 정보 꼭 추가하기 (명시안하면 latest가 디폴트로 들어가짐)

+ git 업로드 시 윈도우보단 VM으로 하는 것이 보안적으로 우위

 

 

Git에 등록된 정보 확인

 

store - 파일 형태로 저장

cache - 메모리에 임시로 저장 (expire: 10분) // 패스워드 입력할 때마다 동작

 

 

git add 해준다음 commit을 생성해준다.

 

 

그 다음 태그 달아주고 push를 하는데 패스워드가 틀려 헤맸었다..

(주의해야 할 건 여기서 패스워드는 계정 비밀번호가 아닌 토큰 비밀번호!!)

 

 

토큰 비밀번호를 다니 실행이 되었다.

그리고 remote 명령어를 통해 편리성을 위해 별칭을 달아준다. 

 

 

무중단 배포

 

 

terraform registry 들어가서 vpc 생성해보려고 한다.

 

 

terraform-demo가 아닌 홈 디렉토리에서 'vpc' 란 디렉토리 생성하고 main.tf를 만든다.

 

 

terraform registry에 있는 vpc 코드를 참고하여 다음 조건을 만족하는 VPC 구성 main.tf를 작성한다.

 

여기서 가용영역 4개, 프라이빗/퍼블릭 서브넷은 각각 3개인데 자동으로 할당되는 방식이다.

(무조건 가용영역 개수와 서브넷 개수가 일치할 필요는 없다.)

Region 하나 당 사용할 수 있는 퍼블릭 서브넷은 5개!

single_nat_gateway -> 비용 및 ip 개수 절감

 

 

terraform init으로 백엔드를 받아준다.

 

 

 

terraform apply 하고나면 eks-vpc 이름의 vpc가 생성된 것을 볼 수 있다.

 

 

다음은 해당 조건을 만족하는 eks.tf를 작성한다.

 

 

해당 모듈의 코드와 아웃풋을 참고하여 코드와 조건을 반영하여 작성한다.

 

 

 

coredns 부분에서 버그가 나면서 시간이 오래 걸려 문제가 발생했다.

 

 

c5a.large 인스턴스에 퍼블릭 ip주소가 없는 것을 확인할 수 있다.

 

따라서, main.tf에서 map_public_ip_on_launch를 활성화시켜준다.

그 다음 terraform destroy로 기존 클러스터를 삭제하고 다시 apply 생성한다. 

 

*kubectl 자격증명

aws eks update-kubeconfig --name test-cluster

 

*kubectl 통한 coredns 배포 및 파드 조회

kubectl rollout restart deploy coredns -n kube-system

kubectl get pod -A

 

 

시간이 지난 후 test-cluster 에 대한 eks를 업데이트하여 파드를 조회하면 제대로 작동하는 것을 확인할 수 있다.

 

 

퍼블릭 아이피 주소도 할당되어있는 것을 확인할 수 있다.

 

-NGINX 배포

 

testweb 이름의 nginx 이미지 deploy 생성

 

 

expose 명령어를 통해 서비스를 만들 수 있다.

ClusterIP 유형의 서비스가 만들어진 것을 볼 수 있다.

 

 

testweb

client는 curl 이미지를 실행할 수 있는 pod로 배포

sleep 1d : 하루(1 day)동안 대기

 

 

ClusterIP면 내부 클러스터에 있으므로 서로 통신이 가능할 것이다.

testweb의 ip 주소인 172.20.66.18에 통신을 보내본다.

 

 

client의 bourne shell로 접속하여 해당 ip주소로 curl을 보낸 결과 응답이 정상적으로 오는 것을 볼 수 있다.

 

 

-Service Discovery

 

 

서비스 testweb에 curl을 보내면 똑같이 정상적으로 응답이 온다. 이런식으로 서비스가 존재하는지 확인하는 것이 service discovery이다.

실제로는 curl SERVICE_NAME.NAMESPACE_NAME.svc.cluster.local

(같은 클러스터라면 svc~ 생략가능, 혹은 curl SERVICE_NAME.default(네임스페이스도 같다면 생략가능) ....)

 

 

coredns: 서비스 ip주소를 reserving 해줌

 

PROBE

 

 

-Liveness Probe

 

client pod 삭제

pod 조회 -> Ready, Restarts 수치 확인 !!

 

 

testweb 파드 3개로 scale out 

 

 

kubectl edit deploy/testweb -> testweb을 vi편집기로 열어 편집

template 하위 spec란에 livenessProbe에 대한 설명 기재

 

- httpGet

- exec

- tcpSocket

중 httpGet 이용

 

-> 현재 내용에선 healthz라는 경로가 없기 때문에 liveness Probe는 재실행을 할 것이다.

 

 

pod 조회 결과 restart 횟수가 증가한 것을 확인할 수 있다.

 

watch kubectl get pod -> 실시간 파드 모니터링

 

kubectl describe pod [pod명]

 

상세 내용에서 Liveness에 문제가 있는 것을 확인

 

 

디렉토리 안에 존재하는 index.html로 수정

 

 

경로가 적절하게 설정되었고 에러가 없으므로 재가동 횟수가 0임을 확인할 수 있다.

 

-Readiness Probe

 

문제가 생기게 경로를 아까처럼 잘못 설정 잡아준다.

 

 

모니터링 결과, 재가동 횟수가 증가하지 않고 ready부분에 0이 뜬 것을 확인할 수 있다.

+ Deployment는 Readiness Probe의 영향을 받음!

: readiness 성공 X -> deployment 확장 X