프로바이더
- 테라폼은 terraform 바이너리 파일을 시작으로 로컬 환경에나 배포 서버와 같은 원격 환경에서 원하는 대상을 호출하는 방식으로 실행된다. 이때 ‘원하는 대상’은 호출하는 방식이 서로 다르지만 대상의 공급자, 즉 프로바이더가 제공하는 API를 호출해 상호작용을 한다. 여기서 테라폼이 대상과의 상호작용을 할 수 있도록 하는 것이 ‘프로바이더’다.
- 각 프로바이더의 API구현은 서로 다르지만 테라폼의 고유 문법으로 동일한 동작을 수행하도록 구현되어 있다. 프로바이더는 플러그인 형태로 테라폼에 결합되어 대상이 되는 클라우드, SaaS, 기타 서비스 API를 사용해 동작을 수행한다. 각 프로바이더는 테라폼이 관리하는 리소스 유형과 데이터 소스를 사용할 수 있도록 연결한다.
- 즉, 테라폼은 프로바이더 없이는 어떤 종류의 인프라와 서비스도 관리할 수 없다는 의미다. 대부분의 프로바이더는 대상 인프라 환경이나 서비스 환경에 대한 리소스를 관리하므로, 프로바이더를 구성할 때는 대상과의 연결과 인증에*(예. AWS 자격증명 등)* 필요한 정보가 제공되어야 한다.
- 각 프로바이더는 테라폼 실행 파일과는 별도로 자체 관리되고 게시된다. 테라폼 레지스트리 사이트에서 주요 프로바이더와 관련 문서를 확인 가능
4.1 프로바이더 구성
테라폼 레지스트리의 프로바이더 목록에는 유지 보수 및 게시에 대한 권한에 따라 Tier 정보가 제공 - 링크
지정하는 프로바이더의 요구사항을 정의 : 레지스트리의 Overview 항목 오른쪽에 있는 [USE PROVIDER] 클릭해 현재 버전의 정의 방법을 확인
- 지정하는 프로바이더의 요구사항을 정의 : 레지스트리의 Overview 항목 오른쪽에 있는 [USE PROVIDER] 클릭해 현재 버전의 정의 방법을 확인
로컬 이름과 프로바이더 지정
- terraform 블록의 required_providers 블록 내에 <로컬 이름> = { } 으로 여러 개의 프로바이더를 정의할 수 있다. 여기서 사용되는 로컬 이름은 테라폼 모듈 내에서 고유해야 한다. 로컬 이름과 리소스 접두사는 독립적으로 선언되며, 각 프로바이더의 소스 경로가 지정되면 프로바이더의 고유 접두사가 제공된다. 만약 동일한 접두사를 사용하는 프로바이더가 선언되는 경우 로컬 이름을 달리해 관련 리소스에서 어떤 프로바이더를 사용하는지 명시적으로 지정할 수 있다.
- 예를 들어 다음의 main.tf에서처럼 동일한 http 이름을 사용하는 다수의 프로바이더가 있는 경우 각 프로바이더에 고유한 이름을 부여하고 리소스와 데이터 소스에 어떤 프로바이더를 사용할지 provider 인수에 명시한다. 단, 동일한 source에 대해 다수의 정의는 불가능한다.
- 동일한 http 접두사를 사용하는 다수의 프로바이더 사용 정의
terraform {
required_providers {
architech-http = {
source = "architect-team/http"
version = "~> 3.0"
}
http = {
source = "hashicorp/http"
}
aws-http = {
source = "terraform-aws-modules/http"
}
}
}
data "http" "example" {
provider = aws-http
url = "https://checkpoint-api.hashicorp.com/v1/check/terraform"
request_headers = {
Accept = "application/json"
}
}
단일 프로바이더의 다중 정의
- 동일한 프로바이더를 사용하지만 다른 조건을 갖는 경우, 사용되는 리소스마다 별도로 선언된 프로바이더를 지정해야 하는 경우가 있다. 예를 들면, AWS 프로바이더를 사용하는데 서로 다른 권한의 IAM을 갖는 Access ID 또는 대상 리전을 지정해야 하는 경우다. 이때는 프로바이더 선언에서 alias를 명시하고 사용하는 리소스와 데이터 소스에서는 provider 메타인수를 사용해 특정 프로바이더를 지정할 수 있다. provider 메타인수에 지정되지 않은 경우 alias가 없는 프로바이더가 기본 프로바이더로 동작한다.
- 아래 예제는 리전을 다르게 구성한 AWS 프로바이더를 aws_instance에 지정하는 방법이다
provider "aws" {
region = "ap-southeast-1"
}
provider "aws" {
alias = "seoul"
region = "ap-northeast-2"
}
resource "aws_instance" "app_server1" {
ami = "ami-06b79cf2aee0d5c92"
instance_type = "t2.micro"
}
resource "aws_instance" "app_server2" {
provider = aws.seoul
ami = "ami-0ea4d4b8dc1e46212"
instance_type = "t2.micro"
}
# 배포 실행
terraform init && terraform plan
terraform apply -auto-approve
# 확인
terraform state list
echo "aws_instance.app_server1.public_ip" | terraform console
echo "aws_instance.app_server2.public_ip" | terraform console
aws ec2 describe-instances --filters Name=instance-state-name,Values=running --output table
aws ec2 describe-instances --filters Name=instance-state-name,Values=running --output table --region ap-southeast-1
# 삭제
terraform destroy -auto-approve
프로바이더 요구사항 정의
- 테라폼 실행 시 요구되는 프로바이더 요구사항은 terraform 블록의 required_providers 블록에 여러 개를 정의할 수 있다.
- source에는 프로바이더 다운로드 경로를 지정하고 version은 버전 제약을 명시한다.
- 프로바이더 요구사항 정의 블록
- 호스트 주소 : 프로바이더를 배포하는 주소로서 기본값은 registry.terraform.io
- 네임스페이스 : 지정된 레지스트리 내에서 구분하는 네임스페이스로, 공개된 레지스트리 및 Terraform Cloud의 비공개 레지스트리의 프로바이더를 게시하는 조직을 의미
- 유형 : 프로바이더에서 관리되는 플랫폼이나 서비스 이름으로 일반적으로 접두사와 일치하나 일부 예외가 있을 수 있음
terraform {
required_providers {
<프로바이더 로컬 이름> = {
source = [<호스트 주소>/]<네임스페이스>/<유형>
version = <버전 제약>
}
...
}
}
- 프로바이더는 기능이나 조건이 시간이 지남에 따라 변경될 수 있다. 이 같은 변경에 특정 버전을 명시하거나 버전 호환성을 정의할 때, version에 명시할 수 있다. 이 값이 생략되는 경우 terraform init을 하는 당시의 가장 최신 버전으로 선택된다.
프로바이더 설치
- 테라폼을 실행하기 전 terraform init 명령을 통해 정의된 프로바이더를 다운로드, 복사, 캐시에서 읽어오게 된다. 항상 지정된 구성에 대해 동일한 프로바이더를 설치하도록 하려면 테라폼 구성에 사용되는 프로바이더에 대해 명시적으로 terraform 블록에 정의하거나 .terraform.lock.hcl 잠금 파일을 코드 저장소에 공유하는 방안이 요구된다.
- 2장에서 살펴본 것처럼 required_providers에 지정된 프로바이더가 있는 경우 코드상 구성에서 사용 여부에 관계없이 프로바이더를 다운로드하게 되고, required_providers에 지정하지 않더라고 테라폼 구성 코드사에서 사용된 프로바이더를 테라폼에서 추론해 최신 버전의 프로바이더를 다운로드 한다.
프로바이더 간 전환 여부
- 클라우드를 대상으로 테라폼을 사용하는 경우 다른 클라우드 프로바이더로 전환이 가능할까? ⇒ 불가능하다!
- 테라폼은 인프라에 대한 단일 프로비저닝 도구로 사용되지만 대상이 되는 환경은 서로 다른 API로 구현된 프로바이더가 제공된다.
4.2 프로바이더 에코시스템
테라폼의 에코시스템은 사용자가 사용하는 방식과 구조에 테라폼을 적용할 수 있도록 설계된다.
- 에코시스템을 위한 테라폼 통합은 워크플로 파트너와 인프라 파트너로 나눈다.
- 워크플로 파트너는 테라폼 실행 및 Terraform Cloud/Enterprise와 연계하여 동작하는 기능을 제공하는 항목으로 이루어져 있다.
- 대표적으로 테라폼 구성을 관리하기 위한 VCS를 제공하는 깃허브, 깃랩, 비트버킷, 애저 데브옵스가 이 항목에 해당된다.
- 프로바이더의 경우 인프라 파트너로 해당된다.
- 인프라 파트너는 사용자가 테라폼으로 대상 플랫폼의 API로 상호작용 가능한 리소스를 관리할 수 있도록 한다.
- 인프라 파트너의 분류와 프로바이더 대상은 다음과 같다.
- IaaS, SaaS 및 PaaS를 포함한 다양한 서비스를 제공하는 대규모 글로벌 클라우드 제공
- 컨테이너 프로비저닝 및 배포를 지원
- 스토리지, 네트워킹 및 가상화와 같은 솔루션을 제공하는 인프라 및 IaaS 제공
- 인증 및 보안 모니터링 플랫폼
- 소프트웨어 라이선스, 하드웨어 자산 및 클라우드 리소스를 비롯한 주요 조직 및 IT 리소스의 자산 관리를 제공
- 지속적인 통합 및 지속적인 제공/배포
- 로거, 측정 도구 및 모니터링 서비스와 같은 서비스를 구성하고 관리하는 기능
- 임의 값 생성, 파일 생성, http 상호 작용 및 시간 기반 리소스와 같은 도우미 기능
- 구성 관리와 같은 전문화된 클라우드 인프라 자동화 관리 기능
- 데이터 센터 스토리지, 백업 및 복구 솔루션
- 라우팅, 스위칭, 방화벽 및 SD-WAN 솔루션과 같은 네트워크별 하드웨어 및 가상화된 제품과 통합
- Terraform 내에서 VCS(버전 제어 시스템) 프로젝트, 팀 및 리포지토리에 중점
- 통신, 이메일 및 메시징 플랫폼과 통합
- 데이터베이스 리소스를 프로비저닝 및 구성하는 기능
- 다양한 하드웨어, 소프트웨어 및 애플리케이션 개발 도구를 제공하는 플랫폼 및 PaaS
- 웹 호스팅, 웹 성능, CDN 및 DNS 서비스
- 퍼블릭 클라우드
- 퍼블릭 클라우드(Iaas, Paas) 프로바이더 + 프라이빗 클라우드/VM
- 컨테이너 오케스트레이터
- SaaS 서비스
- 기타 솔루션
4.3 프로바이더 실습
2개의 리전에 Ubuntu EC2 배포하기
- provider_data.tf 파일 생성 : 리전 별 AMI ID값이 다르므로, 필터를 활용하자
provider "aws" {
region = "ap-northeast-2"
alias = "region_1"
}
provider "aws" {
region = "ap-southeast-1"
alias = "region_2"
}
data "aws_region" "region_1" {
provider = aws.region_1
}
data "aws_region" "region_2" {
provider = aws.region_2
}
data "aws_ami" "ubuntu_region_1" {
provider = aws.region_1
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
data "aws_ami" "ubuntu_region_2" {
provider = aws.region_2
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
ec2.tf 파일 생성 : 리전, ami 참조
resource "aws_instance" "region_1" {
provider = aws.region_1
ami = data.aws_ami.ubuntu_region_1.id
instance_type = "t2.micro
}
resource "aws_instance" "region_2" {
provider = aws.region_2
ami = data.aws_ami.ubuntu_region_2.id
instance_type = "t2.micro"
}
실행
# [터미널1] ap-northeast-2
while true; do aws ec2 describe-instances --region ap-northeast-2 --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text ; echo "------------------------------" ; sleep 1; done
# [터미널2] ap-southeast-1
while true; do aws ec2 describe-instances --region ap-southeast-1 --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text ; echo "------------------------------" ; sleep 1; done
# init & plan & apply
terraform init && terraform plan && terraform apply -auto-approve
terraform state list
# 확인
aws ec2 describe-instances --region ap-northeast-2 --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
aws ec2 describe-instances --region ap-southeast-1 --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
'🍀 Cloud Architect > IaC' 카테고리의 다른 글
[Terraform] Module & Runner (0) | 2024.07.14 |
---|---|
[Terraform] 테라폼 State (0) | 2024.07.06 |
[Terraform] 프로비저너, terraform_data, moved, CLI 환경변수 (0) | 2024.06.30 |
[Terraform] 테라폼 반복문, 조건문, 함수 (0) | 2024.06.29 |
[Terraform] 테라폼 데이터 관리 (0) | 2024.06.22 |