본문 바로가기
DevOps

[T1014-이론] 4장 프로바이더

by 서어켜엉 2024. 7. 7.
해당 내용은 cloudNet@ 팀의 가시다 님이 진행하는 테라폼 스터디 T101 4기에서 다룬 내용과 "테라폼으로 시작하는 IaC" (한빛미디어) 저서 내용을 정리한 것입니다.

 

1. 프로바이더 구성

프로바이더 구성에 대한 요구사항은 공식 레지스트리 사이트인 테라폼 레지스트리에 공개되어 잇는 각 프로바이더의 구성 방식을 참고하는 것이 올바른 방법이다.

테라폼 레지스트리의 프로바이더 목록에는 유지 보수 및 게시에 대한 권한에 따라 Tier 정보가 제공된다.

Tier 설명 네임스페이스
Official 공식 프로바이더로 하시코프가 소유 및 관리한다. hashicorp
Partner 파트너 프로바이더는 하시코프사 외의 기술 파트너가 소유하고 관리한다. 프로바이더의 제공자에 대한 검증이 되어 있고 하시코프 기술 파트너임을 나타낸다. 게시한 조직의 이름
(mongodb/mongodbatlas)
Community 커뮤니티 프로바이더는 개별 관리자가 그룹에서 Terraform의 레지스트리에 게시하고 관리한다.  개인 및 조직 계정 이름
(DeviaVir/gsuite)
Archived 아카이브된 프로바이더는 더는 유지 보수되지 않는 이전 프로바이더이다. API가 더는 사용되지 않거나 관심이 낮은 경우이다. hashicorp 또는 타 조직

 

로컬 이름과 프로바이더 지정

  • 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가 없는 프로바이더가 기본 프로바이더로 동작한다.
  • 예제 코드
provider "aws" {
    region = "us-east-1"
}

provider "aws" {
    alias = "seoul"
    region = "ap-northeast-2"
}

provider "aws" {
    alias = "ohio"
    region = "us-east-2"
}

resource "aws_instance" "t1014_server1" {
    ami = "ami-0f7712b35774b7da2"
    instance_type = "t2.micro"
}

resource "aws_instance" "t1014_server2" {
    provider = aws.seoul
    ami = "ami-0f7712b35774b7da2"
    instance_type = "t2.micro"
}
terraform init && terraform plan && terraform apply -auto-approve

t1014_server1 이 us-east-1(버지니아 북부) 리전에 실행된 것을 확인
t1014_server2이 ap-northeast-2(서울) 리전에 실행된 것을 확인

 

프로바이더 요구사항 정의

  • 테라폼 실행 시 요구되는 프로바이더 요구사항은 terraform 블록의 required_providers 블록에 여러 개를 정의할 수 있다.
  • source에는 프로바이더 다운로드 경로를 지정하고 version은 버전 제약을 명시한다.
  • 프로바이더 요구사항 정의 블록
    • 호스트 주소 : 프로바이더를 배포하는 주소로서 기본값은 registry.terraform.io
    • 네임 스페이스 : 지정된 레지스트리 내에서 구분하는 네임스페이스로, 공개된 레지스트리 및 Terraform Cloud의 비공개 레지스트리의 프로바이더를 게시하는 조직을 의미
    • 유형 : 프로바이더에서 관리되는 플랫폼이나 서비스 이름으로 일반적으로 접두사와 일치하나 일부 예외가 있을 수 있음.
terraform {
  required_providers {
    <프로바이더 로컬 이름> = {
      source = [<호스트 주소>/]<네임스페이스>/<유형>
      version = <버전 제약>
    }
    ...
  }
}
  • 프로바이더는 기능이나 조건이 시간이 지남에 따라 변경될 수 있다. 이 같은 변경에 특정 버전을 명시하거나 버전 호환성을 정의할 때, version에 명시할 수 있다. 이 값이 생략되는 경우 terraform init을 하는 당시의 가장 최신 버전으로 선택된다. 버전 상세 내용은 3.3장 버전 설정 확인

 

프로바이더 설치

  • 클라우드를 대상으로 테라폼을 사용하는 경우 다른 클라우드 프로바이더로 전환이 가능할까? ⇒ 불가능하다!
  • 테라폼은 인프라에 대한 단일 프로비저닝 도구로 사용되지만 대상이 되는 환경은 서로 다른 API로 구현된 프로바이더가 제공된다.
  • 프로바이더 간 대응되는 리소스 예시
Resource AWS GCP
VPC, Subnets, Firewall aws_vpc
aws_subnet
google_compute_network
google_compute_subnetwork
google_compute_firewall
Load Balancer aws_elb
aws_security_group
google_compute_backend_service
google_compute_global_forwarding_rule
google_compute_target_http_proxy
Virtual Machine aws_instance google_compute_instance
Database aws_db_instance google_sql_database_instance

 

2. 프로바이더 에코시스템

테라폼의 에코 시스템은 사용자가 사용하는 방식과 구조에 테라폼을 적용할 수 있도록 설계된다.

  • 에코시스템을 위한 테라폼 통합은 워크플로 파트너와 인프라 파트너로 나눈다.
  • 워크플로 파트너는 테라폼 실행 및 Terraform Cloud/Enterprise와 연계하여 동작하는 기능을 제공하는 항목으로 이루어져 있다.
  • 대표적으로 테라폼 구성을 관리하기 위한 VCS를 제공하는 깃허브, 깃랩, 비트버킷, 애저 데브옵스가 이 항목에 해당된다.
  • 프로바이더의 경우 인프라 파트너로 해당된다.
  • 인프라 파트너는 사용자가 테라폼으로 대상 플랫폼의 API로 상호작용 가능한 리소스를 관리할 수 있도록 한다.
  • 인프라 파트너의 분류와 프로바이더 대상은 다음과 같다.
    • IaaS, SaaS 및 PaaS를 포함한 다양한 서비스를 제공하는 대규모 글로벌 클라우드 제공
    컨테이너 오케스트레이션
    • 컨테이너 프로비저닝 및 배포를 지원
    IaaS(Infrastructure-as-a-Service)
    • 스토리지, 네트워킹 및 가상화와 같은 솔루션을 제공하는 인프라 및 IaaS 제공
    보안 및 인증
    • 인증 및 보안 모니터링 플랫폼
    자산 관리
    • 소프트웨어 라이선스, 하드웨어 자산 및 클라우드 리소스를 비롯한 주요 조직 및 IT 리소스의 자산 관리를 제공
    CI/CD
    • 지속적인 통합 및 지속적인 제공/배포
    로깅 및 모니터링
    • 로거, 측정 도구 및 모니터링 서비스와 같은 서비스를 구성하고 관리하는 기능
    유틸리티
    • 임의 값 생성, 파일 생성, http 상호 작용 및 시간 기반 리소스와 같은 도우미 기능
    클라우드 자동화
    • 구성 관리와 같은 전문화된 클라우드 인프라 자동화 관리 기능
    데이터 관리
    • 데이터 센터 스토리지, 백업 및 복구 솔루션
    네트워킹
    • 라우팅, 스위칭, 방화벽 및 SD-WAN 솔루션과 같은 네트워크별 하드웨어 및 가상화된 제품과 통합
    VCS(버전 제어 시스템)
    • Terraform 내에서 VCS(버전 제어 시스템) 프로젝트, 팀 및 리포지토리에 중점
    통신 및 메시징
    • 통신, 이메일 및 메시징 플랫폼과 통합
    데이터베이스
    • 데이터베이스 리소스를 프로비저닝 및 구성하는 기능
    PaaS(Platform-as-a-Service)
    • 다양한 하드웨어, 소프트웨어 및 애플리케이션 개발 도구를 제공하는 플랫폼 및 PaaS
    웹 서비스
    • 웹 호스팅, 웹 성능, CDN 및 DNS 서비스

 

퍼블릭 클라우드(Iaas, Paas) 프로바이더 + 프라이빗 클라우드/VM

  • AWS, Azure, GCP 등 퍼블릭 클라우드
  • Azure Stack, OpenStack 과 같은 IaaS

컨테이너 오케스트레이터

  • 다수의 호스트 환경에서 컨테이터를 배포 및 관리하는 도구
  • Nomad, Kubernetes, Rancher, Tanzu 등

SaaS 서비스

  • Software as a Service
  • 사용하고자 하는 소프트웨어의 설치, 구성, 관리에 대한 부담을 줄이고 주문형으로 빠른 시간 내에 원하는 자원을 획득할 수 있다.
  • MongoDB Atolas, Confluent Cloud, DataDog, Redis Cloud, Okta 등

기타 솔루션

  • 인프라 환경의 F5, Cisco의 네트워크 장비
  • Fortinet, Palo Alto의 하드웨어 방화벽
  • NetApp 스터리지
  • Elastic Stack, Splunk, Newrelic, Grafana 등의 모니터링 도구

 

3. 프로바이더 경험해보기

 

AWS

  • EC2, Lambda, EKS, ECS, VPC, S3, RDS, DynamoDB 등의 AWS 리소스를 관리하는 AWS 프로바이더는 클라우드 시장에서 점유율이 높고, 예제 또한 많이 제공한다. 
  • 실습 예제 코드

main.tf

provider "aws" {
  region = "ap-northeast-2"
  alias  = "seoul"
}

provider "aws" {
  region = "ap-southeast-1"
  alias  = "singapore"
}

data "aws_region" "seoul" {
  provider = aws.seoul
}

data "aws_region" "singapore" {
  provider = aws.singapore
}

data "aws_ami" "ubuntu_seoul" {
  provider = aws.seoul

  most_recent = true
  owners      = ["099720109477"] # Canonical

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
}

data "aws_ami" "ubuntu_singapore" {
  provider = aws.singapore

  most_recent = true
  owners      = ["099720109477"] # Canonical

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
}

ec2.tf

resource "aws_instance" "seoul_server1" {
  provider = aws.seoul

  ami           = data.aws_ami.ubuntu_seoul.id
  instance_type = "t2.micro"
  tags = {
    "Name": "t1014_test_seoul"
  }
}

resource "aws_instance" "singapore_server1" {
  provider = aws.singapore

  ami           = data.aws_ami.ubuntu_singapore.id
  instance_type = "t2.micro"
  tags = {
    "Name": "t1014_test_singapore"
  }
}

 

  • 확인
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

aws_instance "seoul_server1"
aws_instance "singapore_server1"

 

2가지 주의사항

  • Warning 1 : Multiregion is hard 프로덕션 수준의 멀티 리전은 어렵다
    • Active-Active 멀티 리전 서비스를 위해서 ‘지역간 지연 시간, 고유 ID, 최종 일관성’ 등 여러가지 고려사항이 많아서 쉽지 않다.
  • Warning 2 : Use aliases sparingly Alias 를 빈번하게 사용하지 말자
    • 별칭을 사용하여 두 리전에 배포하는 단일 테라폼 모듈은 한 리전이 다운 시, plan 과 apply 시도가 실패합니다
    • 프로덕션 환경은 멀티 리전의 별칭을 사용하는 것보다는, 3장에서 설명한 것 처럼 환경을 완전히 격리해야 합니다.
    • 이를 통해 영향도를 최소화 할 수 있습니다.