

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 테라폼 제공자에 대한 이해
<a name="providers"></a>

Terraform에서 공급자는 클라우드 *제공업체*, 타사 도구 및 기타 API와 상호 작용하는 플러그인입니다. Terraform을 함께 AWS사용하려면 리소스와 상호 작용하는 [AWS 공급자를](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) 사용해야 합니다. AWS 

[AWS CloudFormation 레지스트리를](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/registry.html) 사용하여 타사 확장을 배포 스택에 통합한 적이 없다면 Terraform [공급자가](https://developer.hashicorp.com/terraform/language/providers) 익숙해지는 데 시간이 걸릴 수 있습니다. CloudFormation 가 기본으로 제공되기 때문에 기본적으로 AWS 리소스 공급자가 이미 있습니다. AWS반면 Terraform에는 단일 기본 공급자가 없으므로 주어진 리소스의 출처에 대해 아무 것도 가정할 수 없습니다. 즉, Terraform 구성 파일에서 가장 먼저 선언해야 할 것은 리소스가 정확히 어디로 가고 어떻게 전달되는지입니다.

이러한 구분은 Terraform에는 존재하지 않는 복잡성을 한층 더 가중시킵니다. CloudFormation 하지만 이러한 복잡성으로 인해 유연성이 향상됩니다. 단일 Terraform 모듈 내에서 여러 공급자를 선언할 수 있으며, 그러면 생성된 기본 리소스가 동일한 배포 계층의 일부로 서로 상호 작용할 수 있습니다.

이는 다양한 방식으로 유용할 수 있습니다. 제공업체가 반드시 별도의 클라우드 공급자를 위한 것은 아닙니다. 공급자는 클라우드 리소스의 모든 소스를 대표할 수 있습니다. 아마존 엘라스틱 쿠버네티스 서비스 (Amazon EKS) 를 예로 들어 보겠습니다. Amazon EKS 클러스터를 프로비저닝할 때 Helm 차트를 사용하여 타사 확장을 관리하고 Kubernetes 자체를 사용하여 포드 리소스를 관리하는 것이 좋습니다. [Helm과](https://registry.terraform.io/providers/hashicorp/helm/latest/docs) [Kubernetes에는](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs) 모두 자체 Terraform 공급자가 있으므로 AWS이러한 리소스를 모두 동시에 프로비저닝 및 통합한 다음 이들 간에 값을 전달할 수 있습니다.

Terraform의 다음 코드 예제에서 AWS 제공자는 Amazon EKS 클러스터를 생성한 다음 결과 쿠버네티스 구성 정보가 헬름 및 쿠버네티스 제공자 모두에게 전달됩니다.

```
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 4.33.0"
    }

    helm = {
      source  = "hashicorp/helm"
      version = "2.12.1"
    }

    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "2.26.0"
    }
  }
  required_version = ">= 1.2.0"
}

provider "aws" {
  region = "us-west-2"
}

resource "aws_eks_cluster" "example_0" {
  name     = "example_0"
  role_arn = aws_iam_role.cluster_role.arn
  vpc_config {
    endpoint_private_access = true
    endpoint_public_access  = true
    subnet_ids              = var.subnet_ids
  }
}

locals {
  host        = aws_eks_cluster.example_0.endpoint
  certificate = base64decode(aws_eks_cluster.example_0.certificate_authority.data)
}

provider "helm" {
  kubernetes {
    host                   = local.host
    cluster_ca_certificate = local.certificate
    # exec allows for an authentication command to be run to obtain user
    # credentials rather than having them stored directly in the file
    exec {
      api_version = "client.authentication.k8s.io/v1beta1"
      args        = ["eks", "get-token", "--cluster-name", aws_eks_cluster.example_0.name]
      command     = "aws"
    }
  }
}

provider "kubernetes" {
  host                   = local.host
  cluster_ca_certificate = local.certificate
  exec {
    api_version = "client.authentication.k8s.io/v1beta1"
    args        = ["eks", "get-token", "--cluster-name", aws_eks_cluster.example_0.name]
    command     = "aws"
  }
}
```

두 IaC 도구의 경우 공급자와 관련하여 절충점이 있습니다. Terraform은 배포를 주도하는 엔진인 외부에 위치한 공급자 패키지에 전적으로 의존합니다. CloudFormation 모든 주요 AWS 프로세스를 내부적으로 지원합니다. 를 사용하면 타사 확장 프로그램을 통합하려는 경우에만 타사 공급자에 대해 걱정할 필요가 있습니다. CloudFormation 각 접근 방식에는 장단점이 있습니다. 어느 것이 적합한지는 이 가이드의 범위를 벗어나지만, 두 도구를 모두 평가할 때는 차이점을 기억하는 것이 중요합니다.

## Terraform 별칭 사용
<a name="using-terraform-aliases"></a>

Terraform에서는 사용자 지정 구성을 각 공급자에게 전달할 수 있습니다. 그렇다면 동일한 모듈 내에서 여러 공급자 구성을 사용하려면 어떻게 해야 할까요? 이 경우 [별칭을](https://developer.hashicorp.com/terraform/language/providers/configuration#alias-multiple-provider-configurations) 사용해야 합니다.   별칭은 리소스별 또는 모듈별 수준에서 사용할 제공자를 선택하는 데 도움이 됩니다. 동일한 제공자의 인스턴스가 두 개 이상 있는 경우 별칭을 사용하여 기본이 아닌 인스턴스를 정의합니다. 예를 들어 기본 제공자 인스턴스는 특정 AWS 리전제공자 인스턴스일 수 있지만 별칭을 사용하여 대체 지역을 정의할 수 있습니다.

다음 Terraform 예제는 별칭을 사용하여 다양한 버킷을 프로비저닝하는 방법을 보여줍니다. AWS 리전공급자의 기본 지역은 이지만`us-west-2`, east 별칭을 사용하여 리소스를 프로비저닝할 수 있습니다. `us-east-2` 

```
provider "aws" {
  region = "us-west-2"
}

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

resource "aws_s3_bucket" "myWestS3Bucket" {
  bucket = "my-west-s3-bucket"
}

resource "aws_s3_bucket" "myEastS3Bucket" {
  provider = aws.east
  bucket   = "my-east-s3-bucket"
}
```

이전 예제에서 볼 수 있듯이 `provider` 메타 인수와 `alias` 함께 를 사용하면 특정 리소스에 대해 다른 제공자 구성을 지정할 수 있습니다. 단일 스택에 여러 리소스를 프로비저닝하는 것은 AWS 리전 시작에 불과합니다. 앨리어싱 공급자는 여러 면에서 매우 편리합니다.

예를 들어, 한 번에 여러 Kubernetes 클러스터를 프로비저닝하는 것은 매우 일반적입니다. 별칭은 Helm 및 Kubernetes 공급자를 추가로 구성하는 데 도움이 되므로 Amazon EKS 리소스별로 이러한 타사 도구를 다르게 사용할 수 있습니다. 다음 Terraform 코드 예제는 별칭을 사용하여 이 작업을 수행하는 방법을 보여줍니다.

```
resource "aws_eks_cluster" "example_0" {
  name     = "example_0"
  role_arn = aws_iam_role.cluster_role.arn
  vpc_config {
    endpoint_private_access = true
    endpoint_public_access  = true
    subnet_ids              = var.subnet_ids[0]
  }
}

resource "aws_eks_cluster" "example_1" {
  name     = "example_1"
  role_arn = aws_iam_role.cluster_role.arn
  vpc_config {
    endpoint_private_access = true
    endpoint_public_access  = true
    subnet_ids              = var.subnet_ids[1]
  }
}

locals {
  host         = aws_eks_cluster.example_0.endpoint
  certificate  = base64decode(aws_eks_cluster.example_0.certificate_authority.data)
  host1        = aws_eks_cluster.example_1.endpoint
  certificate1 = base64decode(aws_eks_cluster.example_1.certificate_authority.data)
}

provider "helm" {
  kubernetes {
    host                   = local.host
    cluster_ca_certificate = local.certificate
    exec {
      api_version = "client.authentication.k8s.io/v1beta1"
      args        = ["eks", "get-token", "--cluster-name", aws_eks_cluster.example_0.name]
      command     = "aws"
    }
  }
}

provider "helm" {
  alias = "helm1"
  kubernetes {
    host                   = local.host1
    cluster_ca_certificate = local.certificate1
    exec {
      api_version = "client.authentication.k8s.io/v1beta1"
      args        = ["eks", "get-token", "--cluster-name", aws_eks_cluster.example_1.name]
      command     = "aws"
    }
  }
}

provider "kubernetes" {
  host                   = local.host
  cluster_ca_certificate = local.certificate
  exec {
    api_version = "client.authentication.k8s.io/v1beta1"
    args        = ["eks", "get-token", "--cluster-name", aws_eks_cluster.example_0.name]
    command     = "aws"
  }
}

provider "kubernetes" {
  alias                  = "kubernetes1"
  host                   = local.host1
  cluster_ca_certificate = local.certificate1
  exec {
    api_version = "client.authentication.k8s.io/v1beta1"
    args        = ["eks", "get-token", "--cluster-name", aws_eks_cluster.example_1.name]
    command     = "aws"
  }
}
```