반응형
지금부터 실제 사이드 프로젝트에 적용시킨 테라폼 코드를 알아보자
📌 서론
테라폼을 실전에 적용하면서 많은 것을 배웠지만 주로 한국보다는 외국 블로그나 커뮤니티에 필요했던 자료가 존재했던 것 같다. 나와 같은 주니어들이 테라폼을 사용하고 싶을 때 이 글을 보고 따라 할 수 있었으면 좋겠다는 마음에 이 글을 추가적으로 작성한다.
지금부터 알아볼 테라폼 코드는 아래의 MSA 프로젝트에서 사용된 인프라를 기반으로 진행된다.
우리 팀(chillwave)에서 작성한 테라폼 모듈의 구성은 아래와 같이 SubModule 패키지(ec2_instance)를 생성하고 그 하위에 main.tf, variables.tf, outputs.tf 이런식으로 구성된다. 이렇게 선언된 서브모듈들은 root경로에 생성된 main.tf 파일에서 사용한다. 앞으로 설명에서 서브모듈에 접근해서 리소스를 생성하는 main.tf는 main.tf(root)라고 표현하도록 하겠다.
1. 클라우드 제공자 선언하기 - main.tf (root)
1-1. AWS 제공자 설정
- main.tf 파일에 AWS를 제공자로 명시하면, 테라폼이 AWS의 API와 상호작용하여 인프라를 자동으로 생성하고 관리할 수 있게 된다.
provider "aws" {
region = "ap-northeast-2"
}
2. network 모듈 작성 및 사용
2-1. network 서브모듈 생성 (vpc, public subnet)
- Terraform이 AWS 리소스와 상호 작용하는 방법을 설정하는 기본 단계다.
- network 패키지를 생성한 후 그 내부에 3개의 tf파일(main, outputs, variables)을 만들고 코드를 작성했다.
- main.tf 코드는 아래와 같이 작성했다.
# AWS VPC 데이터 리소스를 가져온다.
data "aws_vpc" "main" {
id = var.vpc_id # VPC ID. 변수를 통해 지정
}
# 여러 AWS 서브넷 데이터 리소스를 가져온다.
data "aws_subnet" "subnets" {
count = length(var.subnet_ids) # 가져올 서브넷의 수
id = var.subnet_ids[count.index] # 각 서브넷의 ID
}
- outputs.tf
output "vpc_id" {
value = data.aws_vpc.main.id
}
output "subnet_ids" {
value = [for s in data.aws_subnet.subnets : s.id]
}
- variables.tf
variable "vpc_id" {
description = "The ID of the VPC"
type = string
}
variable "subnet_ids" {
description = "List of subnet IDs"
type = list(string)
}
2-2. 서브모듈의 main.tf내부의 코드가 resource가 아니라 data로 선언된 이유
- 테라폼에서 resource와 data는 다음과 같이 사용된다.
- resource 사용
- resource 블록은 새로운 인프라 자원을 생성하거나 관리하기 위해 사용된다.
- 예를 들어, 새로운 VPC나 서브넷을 만들고 싶을 때 resource 블록을 사용한다.
- Terraform은 이 resource 블록을 통해 AWS나 다른 클라우드 제공자에게 새로운 자원을 생성하라는 명령을 내린다.
- data 사용
- 반면에, data는 이미 존재하는 인프라 자원에 대한 정보를 읽기 위해 사용된다.
- 예를 들어, 이미 생성된 VPC나 서브넷의 세부 정보를 가져오고 싶을 때 data 소스를 사용한다.
- data는 새로운 자원을 생성하지 않고, 기존 자원의 정보를 Terraform 구성으로 가져오는 데 사용된다.
- 왜 data를 사용하는가?
- VPC나 서브넷과 같은 자원이 이미 AWS 환경에 존재하고, 이 자원들을 다른 Terraform 리소스와 연동하고 싶을 때 data를 사용한다. 예를 들어, 이미 생성된 VPC 내에 새로운 EC2 인스턴스를 배치하거나, 특정 서브넷에 연결된 리소스를 구성하고 싶을 때, 이 VPC와 서브넷의 세부 정보가 필요하다.
- data를 사용하면 이미 생성된 자원의 정보를 가져와서 다른 리소스의 설정에 활용할 수 있다. 이렇게 하면 기존 자원을 중복 생성하지 않고도 필요한 정보를 활용할 수 있다.
2-3. aws에서 기존에 생성한 vpc와 subnet 정보 알아보기
- vpc 콘솔에 들어가서 이름을 클릭하면 아래와 같은 "세부 정보" 화면으로 이동된다. 여기서 vpc id값을 확인한다.
- vpc id를 확인한 후 페이지 하단을 보면 "리소스 맵"이 있을 것이다. 여기에 적혀있는 서브넷에서 id값을 복사한다. (3개 복사 추천)
2-4. main.tf(root)에 모듈 코드 작성하기
- 가장 먼저 source를 작성하는데 여기에는 어떤 서브모듈을 참조하는지 그 경로를 작성하면 된다. 위의 경로이미지를 보면 알겠지만 나는 network라는 패키지를 만들고 그 안에 tf 파일을 선언하고 코드를 작성했기에 경로를 "./network"로 설정했다.
- vpc_id와 subnet_ids에는 위에서 확인한 id값들을 적어주면 된다. subnet은 여러 개라 배열 형태로 적어준다.
# 네트워크 설정 - vpc, subnet
module "{원하는 모듈명}" {
source = "{내 서븜모듈 패키지 경로}"
vpc_id = "{내 vpc id}"
subnet_ids = [{원하는 서브넷 id들}]
}
2-5. main.tf(root)에 적은 모듈이 동작하는 과정 이해하기
- main.tf(root) 파일에서는 어떻게 network모듈을 사용하는지 이미지를 통해 이해해보자 (모듈을 생성하는 main.tf(root)에 있는 코드를 이해를 돕기 위해 잠깐 같은 경로에 가지고 왔다. 원래대로면 서로 다른 파일에 코드가 존재한다.)
- marin.tf(root)의 vpc_id에 적어준 코드는 서브모듈에 선언한 data의 var.vpc_id에 매핑되고 subnet_ids도 동일하게 매핑된다.
3. EC2 런치 템플릿 모듈1: 코드 작성하기
3-1. EC2 런치 템플릿을 작성하는 이유
- EC2 런치 템플릿은 오토 스케일링 그룹(ASG)과 함께 사용되어 인스턴스 생성을 자동화하고 표준화하는 데 사용된다. 나는 ASG를 사용하고자 했기에 EC2 런치 탬플릿을 작성해 줬다. (ASG를 사용하지 않을 생각이라면 이 과정은 생략해도 된다.)
3-2. EC2 런치 템플릿 서브모듈 생성
- ec2_launch_template 패키지를 생성한 후 5개의 파일을 생성했다. 3개는 tf파일(main, outputs, variables)이고 나머지 2개는 런치 템플릿이 내부적으로 사용하는 sh 파일이다.
- ec2_launch_template(서브모듈)의 main.tf 파일에 리소스를 구성하는 코드를 작성했다.
- main.tf
# EC2 런치 템플릿 리소스 생성
resource "aws_launch_template" "launch_template" {
name_prefix = var.name_prefix # 템플릿 이름 접두사
image_id = var.image_id # 사용할 AMI ID
instance_type = var.instance_type # EC2 인스턴스 타입
key_name = var.key_name # EC2 키 페어 이름
vpc_security_group_ids = var.vpc_security_group_ids # VPC 보안 그룹 ID 목록
iam_instance_profile { # IAM 인스턴스 프로파일 설정
name = var.iam_instance_profile
}
block_device_mappings { # 블록 디바이스 매핑 설정
device_name = "/dev/xvda"
ebs {
volume_size = 30 # EBS 볼륨 크기 (GB)
volume_type = "gp2" # EBS 볼륨 타입
}
}
tag_specifications { # 인스턴스에 적용될 태그 설정
resource_type = "instance"
tags = {
Name = var.ec2_instance_name # 인스턴스 이름 태그
}
}
user_data = filebase64("${path.module}/${var.user_data_file}") # 인스턴스 생성 시 실행될 사용자 데이터 스크립트
}
- outputs.tf
output "launch_template_id" {
value = aws_launch_template.launch_template.id
}
- variables.tf
variable "name_prefix" {
description = "Prefix of the launch template name"
}
variable "image_id" {
description = "AMI ID to be used in the launch template"
}
variable "instance_type" {
description = "Instance type to be used in the launch template"
}
variable "key_name" {
description = "Key name to be used in the launch template"
}
variable "ec2_instance_name" {
description = "ec2 instance name"
}
variable "vpc_security_group_ids" {
description = "List of security group IDs to be used in the launch template"
type = list(string)
}
variable "iam_instance_profile" {
description = "IAM instance profile to be used in the launch template"
}
variable "user_data_file" {
description = "Path to the user data file"
}
- user_data
#!/bin/bash
echo ECS_CLUSTER={ec2와 연결해줄 ecs 클러스터명 적기} >> /etc/ecs/ecs.config
4. EC2 런치 템플릿 모듈2: 코드 분석
4-1. 작성한 user_data 코드 이해하기
- user_data는 EC2 인스턴스가 처음 시작될 때 자동으로 실행되는 스크립트나 명령어를 지정하는 데 사용되는 설정이다. 이 기능은 인스턴스가 부팅될 때 단 한 번만 실행되며 Amazon ECS(Elastic Container Service)를 사용하는 EC2 인스턴스에서 특정 ECS 클러스터에 인스턴스를 등록하는 데 사용된다.
1.코드 분석하기
1. #!/bin/bash |
|
2. echo ECS_CLUSTER=member-ecs-cluster >> /etc/ecs/ecs.config |
|
2.좀 더 자세히 코드 분석하기
1. ECS_CLUSTER=member-ecs-cluster |
|
2. /etc/ecs/ecs.config |
|
위에 적혀있는 EC2 인스턴스에 있는 ECS 에이전트에 대한 설명이 더 필요하다.
4-2. EC2인스턴스에 있는 ECS 에이전트란?
- EC2 인스턴스에 있는 ECS 에이전트는 Amazon Elastic Container Service (ECS)의 일부로 작동하는 소프트웨어 컴포넌트다. 이 에이전트는 Amazon ECS와 통신하면서 EC2 인스턴스에서 컨테이너화된 애플리케이션의 배포와 관리를 담당한다. ECS 에이전트의 주요 역할은 다음과 같다.
- ECS와의 통신:
- ECS 에이전트는 ECS 서비스와 지속적으로 통신하면서 컨테이너 관리 명령을 받고 상태 정보를 전송한다.
- ECS 에이전트는 ECS 서비스와 지속적으로 통신하면서 컨테이너 관리 명령을 받고 상태 정보를 전송한다.
- 컨테이너 관리:
- 에이전트는 ECS로부터 받은 작업 할당에 따라 EC2 인스턴스에서 컨테이너를 시작하거나 중지하는 등의 작업을 수행한다.
- 에이전트는 ECS로부터 받은 작업 할당에 따라 EC2 인스턴스에서 컨테이너를 시작하거나 중지하는 등의 작업을 수행한다.
- 자원 모니터링:
- 실행 중인 컨테이너의 자원 사용량을 모니터링하고, 이 정보를 ECS로 보내서 최적의 자원 배분과 관리를 도와준다.
만약 ECS 생성을 안 하고 EC2 만 생성한다면 ECS에이전트가 같이 생성될까?
4-3. EC2 생성과 ECS 에이전트 생성의 관계
- EC2 인스턴스를 생성할 때, ECS 에이전트는 기본적으로 포함되어 있지 않다. ECS 에이전트를 사용하려면, 몇 가지 추가적인 설정을 해줘야 한다.
- ECS 에이전트 설치:
- EC2 인스턴스에 ECS 에이전트를 설치해야 한다. 이는 Amazon Linux AMI와 같이 ECS에 최적화된 몇몇 AMI에서는 사전 설치되어 있을 수 있지만, 다른 AMI를 사용한다면 수동으로 설치해야 한다.
- EC2 인스턴스에 ECS 에이전트를 설치해야 한다. 이는 Amazon Linux AMI와 같이 ECS에 최적화된 몇몇 AMI에서는 사전 설치되어 있을 수 있지만, 다른 AMI를 사용한다면 수동으로 설치해야 한다.
- IAM 역할:
- EC2 인스턴스에 ECS 에이전트를 사용하려면, 해당 인스턴스가 ECS와 통신할 수 있도록 적절한 IAM 역할을 할당해야 한다. 이 IAM 역할은 ECS 에이전트가 ECS 서비스와 통신하고 AWS 리소스에 접근하는 데 필요한 권한을 제공해야 한다.
- EC2 인스턴스에 ECS 에이전트를 사용하려면, 해당 인스턴스가 ECS와 통신할 수 있도록 적절한 IAM 역할을 할당해야 한다. 이 IAM 역할은 ECS 에이전트가 ECS 서비스와 통신하고 AWS 리소스에 접근하는 데 필요한 권한을 제공해야 한다.
- ECS 클러스터 구성:
- ECS 에이전트가 있는 EC2 인스턴스를 원하는 ECS 클러스터에 등록하기 위해, `ecs.config` 파일에 클러스터 이름을 설정해야 한다. 이는 `user_data` 스크립트를 통해 구성할 수 있다.
- ECS 에이전트가 있는 EC2 인스턴스를 원하는 ECS 클러스터에 등록하기 위해, `ecs.config` 파일에 클러스터 이름을 설정해야 한다. 이는 `user_data` 스크립트를 통해 구성할 수 있다.
따라서 ECS 에이전트를 사용하기 위해서는 EC2 인스턴스 생성 시 명시적으로 설치 및 구성 작업을 수행해야 한다. 기본적으로는 이러한 설정이 자동으로 이루어지지 않기 때문에, ECS를 사용하려는 경우 이를 고려해야 한다.
user_data에 대한 이해를 마쳤다면 main.tf(root)로 가서 선언한 모듈 코드를 작성해 보자
5. EC2 런치 템플릿 모듈3: 모듈 사용
5-1. 선언한 EC2 런치 템플릿 모듈 사용하기 - main.tf(root)
- 처음 vpc, subnet을 설정했을 때와 마찬가지로 이번에도 source를 적어준다. (선언해 준 ec2_launch_tempate 서브모듈 경로를 적어준다.)
- user_data_file에는 디렉토리 경로에 생성한 member_user_data.sh 파일을 적어줬다. (확장자 포함)
# 오토스케일링에서 사용할 ec2 런치 템플릿 설정
module "{원하는 모듈명}" {
source = "{서브모듈 경로}"
name_prefix = "{ec2 이름 앞에 들어갈 prefix}"
image_id = "{인스턴스에 설정할 ami}"
instance_type = "{원하는 인스턴스 타입}"
key_name = "{생성한 keypair 적기}"
vpc_security_group_ids = ["{연결할 보안그룹}"]
iam_instance_profile = "{원하는 iam role}"
ec2_instance_name = "{ec2 인스턴스 이름}"
user_data_file = "{파일을 따로 만들고 경로 작성}"
}
5-2. main.tf(root)에 적은 모듈이 동작하는 과정 이해하기
- 이미지를 보면 2개만 표시해 뒀지만 main.tf(root) 파일에 작성한 module에 선언된 모든 값들이 EC2 런치 템플릿 서브모듈(main.tf) 내부에 선언한 var에 매핑되어 리소스가 생성된다.
다음 포스트에서는 "AutoScailingGroup"과 "용량 공급자"를 생성하고 ASG와 용량 공급자를 연결해 볼 예정이다. 이 작업이 완료된 후에 Zipkin서버가 사용할 EC2까지 생성해 보자
다음 포스트 👇🏻👇🏻
모듈화가 무엇인지 아래의 글을 통해 알아보자
이 포스트는 Team chillwave에서 사이드 프로젝트 중 적용했던 부분을 다시 공부하며 기록한 것입니다.
시간이 괜찮다면 팀원 '평양냉면 7'님의 블로그도 한번 봐주세요 :)
반응형
'AWS > 테라폼(Terraform)' 카테고리의 다른 글
실전! 테라폼 적용기 [추가설명] - dynamic 블록 사용하기 (0) | 2023.12.18 |
---|---|
실전! 테라폼 적용기3편 - Auto Scaling Group과 용량 공급자(Capacity provider) 작성 (1) | 2023.12.18 |
실전! 테라폼 정복기 1편 - 테라폼(Terraform) 모듈화 (1) | 2023.12.09 |
테라폼(Terraform) 사용 가이드 7: AutoScailingGroup과 LoadBalancer을 생성하고 연결하기 (0) | 2023.12.07 |
테라폼(Terraform) 사용 가이드 6: 테라폼으로 IAM 정책 생성/관리하기 (1) | 2023.12.05 |