Entendendo os fornecedores do Terraform - AWS Orientação prescritiva

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Entendendo os fornecedores do Terraform

No Terraform, um provedor é um plug-in que interage com provedores de nuvem, ferramentas de terceiros e outras APIs. Para usar o Terraform com AWS, você usa o AWS Provider, que interage com AWS os recursos.

Se você nunca usou o AWS CloudFormation registro para incorporar extensões de terceiros em suas pilhas de implantação, talvez os fornecedores do Terraform levem algum tempo para se acostumar. Por ser CloudFormation nativo do AWS, o provedor de AWS recursos já está lá por padrão. O Terraform, por outro lado, não tem um único provedor padrão, então nada pode ser assumido sobre as origens de um determinado recurso. Isso significa que a primeira coisa que precisa ser declarada em um arquivo de configuração do Terraform é exatamente para onde os recursos estão indo e como eles vão chegar lá.

Essa distinção adiciona uma camada extra de complexidade ao Terraform que não existe com o. CloudFormation No entanto, essa complexidade proporciona maior flexibilidade. Você pode declarar vários provedores em um único módulo do Terraform e, em seguida, os recursos subjacentes criados podem interagir entre si como parte da mesma camada de implantação.

Isso pode ser útil de várias maneiras. Os provedores não precisam necessariamente ser provedores de nuvem separados. Os provedores podem representar qualquer fonte de recursos de nuvem. Por exemplo, pegue o Amazon Elastic Kubernetes Service (Amazon EKS). Ao provisionar um cluster Amazon EKS, talvez você queira usar gráficos do Helm para gerenciar extensões de terceiros e usar o próprio Kubernetes para gerenciar recursos de pod. Como AWS o Helm e o Kubernetes têm seus próprios provedores do Terraform, você pode provisionar e integrar esses recursos ao mesmo tempo e depois passar valores entre eles.

No exemplo de código a seguir para o Terraform, o AWS provedor cria um cluster Amazon EKS e, em seguida, as informações de configuração do Kubernetes resultantes são passadas para os provedores Helm e Kubernetes.

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" } }

Há uma desvantagem em relação aos fornecedores quando se trata das duas ferramentas de IaC. O Terraform depende totalmente de pacotes de fornecedores localizados externamente, que são o mecanismo que impulsiona suas implantações. CloudFormation suporta internamente todos os principais AWS processos. Com isso CloudFormation, você precisa se preocupar com fornecedores terceirizados somente se quiser incorporar uma extensão de terceiros. Há prós e contras em cada abordagem. Qual é a melhor opção para você está além do escopo deste guia, mas é importante lembrar a diferença ao avaliar as duas ferramentas.

Usando aliases do Terraform

No Terraform, você pode passar configurações personalizadas para cada provedor. E se você quiser usar várias configurações de provedor no mesmo módulo? Nesse caso, você teria que usar um alias.  Os aliases ajudam você a selecionar qual provedor usar em um nível por recurso ou por módulo. Quando você tem mais de uma instância do mesmo provedor, você usa um alias para definir as instâncias não padrão. Por exemplo, sua instância de provedor padrão pode ser específica Região da AWS, mas você usa aliases para definir regiões alternativas.

O exemplo do Terraform a seguir mostra como usar um alias para provisionar buckets em diferentes. Regiões da AWS A região padrão para o provedor éus-west-2, mas você pode usar o alias east para provisionar recursos emus-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" }

Ao usar um alias junto com o provider meta-argumento, conforme mostrado no exemplo anterior, você pode especificar uma configuração de provedor diferente para recursos específicos. Provisionar recursos em vários Regiões da AWS em uma única pilha é só o começo. Os provedores de aliases são incrivelmente convenientes de várias maneiras.

Por exemplo, é muito comum provisionar vários clusters Kubernetes ao mesmo tempo. Os aliases podem ajudá-lo a configurar provedores adicionais de Helm e Kubernetes para que você possa usar essas ferramentas de terceiros de forma diferente para diferentes recursos do Amazon EKS. O exemplo de código do Terraform a seguir ilustra como usar aliases para realizar essa tarefa.

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" } }