Provedor Terraform AWS Épico para sua Infraestrutura Amazon

Se você planeja gerenciar e trabalhar com o Amazon Web Services (AWS), usar o provedor Terraform AWS é essencial. Isso permite interagir com os diversos recursos suportados pela AWS, como Amazon S3, Elastic Beanstalk, Lambda e muitos outros.

Neste guia completo, você vai aprender, passo a passo, praticamente tudo o que precisa saber sobre o provedor AWS e como usar este provedor com o Terraform para gerenciar sua Infraestrutura Amazon.

Vamos lá!

Pré-requisitos

Se deseja acompanhar este tutorial, certifique-se de ter o seguinte em vigor:

  • Uma conta de Serviço da Web da Amazon (AWS).
  • Um usuário IAM com uma chave de acesso e chave secreta configurada em sua máquina local.
  • Terraform v0.14.9 – As demonstrações deste tutorial são feitas no Ubuntu 18.04.5 LTS, mas outros sistemas operacionais com Terraform funcionarão.
  • A code editor – Even though you can use any text editor to work with Terraform configuration files, you should have one that understands the HCL Terraform language. Try out Visual Studio (VS) Code.

O que é o Provedor AWS do Terraform?

O Terraform depende de plugins para interagir com provedores de nuvem, como AWS, Google Cloud Platform (GCP) e Oracle. Um dos provedores mais amplamente utilizados é o provedor AWS. Este provedor interage com muitos recursos suportados pela AWS, como Amazon S3, Elastic Beanstalk, Lambda e muitos outros.

O Terraform utiliza o provedor AWS com credenciais adequadas para se conectar à Amazon e gerenciar ou implantar/atualizar dezenas de serviços AWS.

O provedor AWS é declarado dentro do arquivo de configuração do Terraform e inclui vários parâmetros, como versão, URLs de endpoint ou regiões na nuvem, etc.

Declarando o Provedor AWS

Quando precisar referir-se ao nome de um provedor, é necessário definir um nome local. O nome local é o nome do provedor atribuído dentro do bloco required_providers. Os nomes locais são atribuídos ao exigir um provedor e devem ser únicos por módulo.

Ao declarar os required_providers, também é necessário declarar o parâmetro source no Terraform 0.13 e versões posteriores. O parâmetro source define o endereço de origem de onde o Terraform pode baixar plugins.

Os endereços de origem consistem em três partes, conforme abaixo:

  • Nome do Host – O nome do host do registro do Terraform que distribui o provedor. O nome de host padrão é registry.terraform.io.
  • Namespace – Um namespace organizacional dentro do registro especificado.
  • Tipo – Um tipo é um nome curto que você fornece para a plataforma ou sistema que o provedor gerencia, e deve ser único.

Abaixo, você pode ver a sintaxe de declaração do parâmetro source, onde as três partes de um endereço de origem são delimitadas por barras (/).

## <HOSTNAME>/]<NAMESPACE>/<TYPE>

# EXEMPLO DE USO DA SINTAXE DO PARÂMETRO DE FONTE

# Declarando o local/endereço de origem de onde o Terraform pode baixar plugins
# O provedor oficial da AWS pertence ao namespace da hashicorp no 
# registro.terraform.io. Então, o endereço de origem da hashicorp é hashicorp/aws
source  = "hashicorp/aws"

Agora, a configuração do Terraform abaixo declara o nome do provedor necessário (aws), juntamente com o endereço de origem, a versão do provedor AWS e configura a região do provedor (us-east-2).

# Declarando os requisitos do provedor quando o Terraform 0.13 e posterior está instalado
terraform {
  # Um requisito de provedor consiste em um nome local (aws), 
  # localização de origem e uma restrição de versão. 
  required_providers {
    aws = {     
      # Declarando o local/endereço de origem de onde o Terraform pode baixar plugins
      source  = "hashicorp/aws"
      # Declarando a versão do provedor aws como maior que 3.0
      version = "~> 3.0"  
    }
  }
}

# Configurando o Provedor AWS na região us-east-2
provider "aws" {
  region = "us-east-2"
}

Autenticando uma Conta AWS com Credenciais Codificadas

Agora que você tem uma compreensão básica de como declarar o provedor AWS, vamos ver como autenticar uma conta AWS.

Você pode autenticar o provedor AWS por meio de alguns métodos diferentes, como declarar variáveis de ambiente e armazenar credenciais em um perfil nomeado. Mas a maneira mais rápida de autenticar uma conta AWS é codificar as credenciais diretamente no seu provedor AWS.

Embora credenciais codificadas não sejam recomendadas, pois estão sujeitas a vazamentos, você ainda pode declarar credenciais codificadas na configuração do Terraform para testar rapidamente qualquer recurso AWS. Mas continue lendo e você aprenderá posteriormente uma maneira melhor de autenticar uma conta AWS, declarando variáveis de ambiente.

A configuração abaixo declara um nome local (aws) junto com a região do provedor (us-east-2), como mostrado abaixo. Você pode ver que o bloco do provedor AWS também declara uma chave de acesso e uma chave secreta para autenticar uma conta AWS.

# Declarando um provedor AWS chamado aws
provider "aws" {
  # Declarando a região do provedor
  region = "us-east-2"
  # Declarando a access_key e secret_key
  access_key = "access-key"
  secret_key = "secret-key"
}

Protegendo Credenciais ao Declarar Variáveis de Ambiente

Você acabou de aprender que é possível codificar estaticamente as credenciais para autenticar o serviço de nuvem AWS com o Terraform. No entanto, a codificação estática não é segura e é recomendada apenas ao implantar em um ambiente de teste para testar rapidamente o código.

Existe outra maneira de garantir credenciais? Sim, declarando-as como variáveis de ambiente, não há limite para quantas você pode declarar. Variáveis de ambiente são variáveis cujos valores são definidos fora do arquivo de configuração do Terraform e são compostos por um par de nome/valor.

Execute a série de comandos export abaixo para exportar cada variável de ambiente. Exportar variáveis de ambiente as torna disponíveis ao longo do programa ou até que o Terraform execute.

# Exportando variável AWS_ACCESS_KEY_ID
export AWS_ACCESS_KEY_ID="access-key"
# Exportando AWS_SECRET_ACCESS_KEY
export AWS_SECRET_ACCESS_KEY="secret-key"
# Exportando AWS_DEFAULT_REGION
export AWS_DEFAULT_REGION="us-east-2"

Armazenamento de Múltiplas Credenciais em um Perfil Nomeado

Tanto a codificação rígida quanto a declaração de credenciais como variáveis de ambiente permitem autenticar uma conta da AWS de cada vez. Mas e se você precisar armazenar múltiplas credenciais e usá-las quando necessário? Armazenar credenciais em um perfil nomeado é a opção ideal.

O código abaixo cria um perfil nomeado (MeuPerfil) que contém uma chave de acesso e uma chave secreta.

O local padrão dos perfis nomeados é em $HOME/.aws/credentials/MeuPerfil no Linux e macOS, ou %USERPROFILE%\.aws\credentials\MeuPerfil no Windows. Substitua MeuPerfil pelo nome real do perfil nomeado.

# Criando o Perfil Nomeado chamado 'MeuPerfil'
[Myprofile]
aws_access_key_id = AKIAVWOJMI5836154yRW31
aws_secret_accesss_key = vIaGmx2bJCAK90hQbpNhPV2k5wlW7JsVrP1bm9Ft

Depois de criar um perfil nomeado em ~/.aws/credentials, você pode referenciar esse perfil na sua configuração do Terraform usando o atributo profile. Abaixo, você está referenciando o perfil nomeado chamado MeuPerfil.

# Configurando o Provedor AWS nomeado 'aws' na região us-east-2
provider "aws" {
  region = "us-east-2"
  # Declarando o perfil nomeado (MeuPerfil)
  profile = "Myprofile"
}

Declarando o Assume Role no Provedor AWS

Você acabou de aprender a configurar um Provedor AWS declarando credenciais codificadas antes de executar o Terraform. Mas talvez você queira declarar credenciais durante a execução. Se for o caso, a API AssumeRole é o que você precisa. AssumeRole fornece credenciais temporárias contendo um ID de chave de acesso, chave de acesso secreta e um token de segurança. Essas credenciais permitem que você se conecte ao AWS.

O código abaixo declara o provedor nomeado aws e um assume_role que contém um nome de função e um nome de sessão. Para configurar o acesso AssumeRole, você deve definir uma função IAM que especifique os privilégios concedidos por ela e quais entidades podem assumi-la.

# Declarando o Fornecedor AWS chamado 'aws'
provider "aws" {
  # Declarando AssumeRole
  assume_role {
		# Declarando um nome de recurso.
    # O role_arn é o Amazon Resource Name (ARN) da função IAM a assumir.
    # ARN é um número único que está alinhado a todos os recursos na conta da AWS.
    role_arn     = "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"
    # Declarando um nome de sessão
    session_name = "SESSION_NAME"
  }
}

Declarando Múltiplos Fornecedores AWS

Agora, você aprendeu como declarar e configurar o Fornecedor AWS no Terraform que funciona com uma única região. Mas e se você precisar gerenciar sua infraestrutura ou serviços AWS em várias regiões de nuvem? Nesse caso, você precisará declarar a palavra-chave alias.

O alias permite definir várias configurações para o mesmo provedor e selecionar qual usar em uma base de recurso ou módulo por recurso ou suportar várias regiões.

O código abaixo declara o Fornecedor AWS padrão chamado aws com a region definida como us-east-2. E então declara um Fornecedor AWS adicional com o mesmo nome, mas com um alias declarado chamado west e uma region definida como us-west-2.

Declarar um alias permite que você crie recursos na região us-east-2 por padrão ou na região us-west-2 se escolher o provedor aws.west, dependendo dos requisitos.

# Os recursos de configuração do provedor padrão começam com aws.
provider "aws" {
  # Declarando a região us-east-2 para o provedor AWS chamado 'aws'
  region = "us-east-2" 
}

# Configuração adicional do provedor para a região oeste.
# Os recursos podem fazer referência a isso como aws.west.
provider "aws" {
  alias  = "west"
  # Declarando a região us-west-2 para o provedor AWS referenciado como 'west'
  region = "us-west-2"
}

# Declarando o recurso usando um provedor adicional na região oeste
resource "aws_instance" "west-region" {
  # Declarando o provedor como aws.west
  # aws.west é referenciado pelo provedor AWS chamado 'aws' e com o alias 'west'
  provider = aws.west
}

# Declarando o recurso usando o provedor padrão
resource "aws_instance" "east-region" 
}

Personalizando a Configuração do Endpoint do Provedor AWS

Personalizar a configuração do endpoint é útil ao se conectar a endpoints de serviço AWS não padrão, como AWS Snowball ou ao realizar testes locais.

Configurar o provedor AWS do Terraform para usar endpoints personalizados. Faça isso declarando o bloco de configuração endpoints dentro do bloco do provedor, conforme mostrado abaixo.

A configuração abaixo permite que você acesse o serviço AWS S3 na porta local 4572 como se estivesse realmente acessando o serviço AWS S3 em uma conta AWS. Da mesma forma, a configuração permite que você acesse dynamodb localmente na porta 4569. O DynamoDB é um serviço de banco de dados NoSQL que oferece desempenho rápido com escalabilidade contínua.

Verifique a lista de endpoints personalizados que o provedor AWS do Terraform permite.

# Declarando o provedor AWS chamado 'aws'
provider "aws" {
  # Declarando endpoints
  endpoints { 
    # Declarando o dynamodb no localhost com a porta 4569 
    dynamodb = "<http://localhost:4569>"  
    # Declarando o S3 no localhost com a porta 4572
    s3 = "<http://localhost:4572>"  
  }
}

Adicionando Tags

Anteriormente, você aprendeu como um provedor AWS é declarado com configurações como região, localização da fonte, etc. Mas para gerenciar melhor seus recursos, você precisa adicionar tags no nível do provedor.

Tags são rótulos compostos por chaves e valores definidos pelo usuário. As tags são úteis quando é necessário verificar a faturação, propriedade, automação, controle de acesso e muitos outros casos de uso na conta AWS.

Em vez de adicionar tags a todos os recursos individualmente, vamos aprender como adicionar tags a todos os recursos no nível do provedor, o que ajudará a economizar muito código e tempo.

O código abaixo configura um provedor AWS com tags definidas dentro de default_tags. O benefício de adicionar tags dentro do provedor é que as tags especificadas serão automaticamente adicionadas ao criar qualquer recurso com este provedor.

# Configurando o provedor AWS chamado 'aws'
provider "aws" {
  # Adicionando as tags padrão Environment e Owner no nível do provedor
  default_tags {
    # Declarando os valores das tags
    tags = {
      Environment = "Production"
      Owner       = "shanky"
    }
  }
}
# Criando o recurso 'aws_vpc' marcado com Nome=MyVPC
resource "aws_vpc" "myinstance" {
  tags = {
    Name = "MyVPC"
  }
}

Ignorando Tags

Habilitar tags no nível do provedor ajuda a aplicar tags em todo o ambiente. Mas às vezes, é necessário ignorar as tags, como quando não se deseja adicionar uma tag padrão a uma instância EC2 e prefere aplicar ao restante dos recursos na conta AWS. Vamos conferir!

O código abaixo configura um provedor AWS com ignore_tags definido dentro do provedor. O benefício de usar a tag de ignorar é quando não deseja adicionar tags padrão a certos recursos e aplicar ao restante dos recursos.

No código abaixo, ao criar qualquer recurso usando o provedor aws, todos os recursos irão ignorar as tags LastScanned e kubernetes.io.

# Configurando o Provedor AWS nomeado aws
provider "aws" {
	# Ignorar prefixos e chaves de tag em todos os recursos sob o provedor AWS (aws)
  ignore_tags {
    key_prefixes = ["kubernetes.io"]
  }
  ignore_tags {
    keys = ["LastScanned"]
  }
}

Criando um Bucket AWS S3

Até agora, você aprendeu tudo sobre como declarar e configurar os provedores AWS em profundidade. Mas apenas declarar o provedor AWS não fará nada até que você gerencie os recursos AWS, como provisionar um bucket AWS S3 ou excluir uma instância Ec2 etc. Então, vamos aprender como criar um bucket AWS S3!

1. Crie uma pasta chamada ~/terraform-s3-demo, depois altere (cd) o diretório de trabalho para essa pasta. A pasta ~/terraform-s3-demo conterá seu arquivo de configuração e todos os arquivos associados que o Terraform criará.

mkdir ~/terraform-s3-demo
cd ~/terraform-s3-demo

2. Copie e cole a configuração abaixo em seu editor de código favorito e salve-a como main.tf no diretório ~/terraform-s3-demo.

O arquivo main.tf cria alguns recursos necessários:

  • Requisito de provedor: Um requisito de provedor consiste em um nome local, localização da fonte e uma restrição de versão.
  • Chave de criptografia: A chave de criptografia do Amazon S3 ajuda o bucket S3 para que todos os novos objetos sejam criptografados ao serem armazenados no bucket. As chaves de criptografia são criadas usando aws_kms_key no Terraform.
  • Configurando o Provedor AWS: Declarando o nome do provedor (aws) juntamente com a região us-east-2.
  • Bucket: Este módulo do Terraform cria um bucket chamado terraformdemobucket. O Terraform não pode destruir este bucket, pois contém uma flag force_destroy.

Versionamento: O versionamento no Amazon S3 significa manter múltiplas versões de um objeto no mesmo bucket

# Configurando o Provedor AWS chamado aws
provider "aws" {
# Ignorar tags de prefixos de chave e chaves em todos os recursos sob um provedor aws. 
  ignore_tags {
    key_prefixes = ["kubernetes.io/"]
  }
  ignore_tags {
    keys = ["LastScanned"]
  }
}

# Declarando os Requisitos do Provedor
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

# Configurando o Provedor AWS (aws) com a região definida como 'us-east-2'
provider "aws" {
  region = "us-east-2"
}

# Concedendo Acesso ao Bucket
resource "aws_s3_bucket_public_access_block" "publicaccess" {
  bucket = aws_s3_bucket.demobucket.id
  block_public_acls = false
  block_public_policy = false
}

# Criando a chave de criptografia que irá criptografar os objetos do bucket
resource "aws_kms_key" "mykey" {
  deletion_window_in_days = "20"
}

# Criando o bucket chamado terraformdemobucket
resource "aws_s3_bucket" "demobucket" {
  bucket = terraformdemobucket
  force_destroy = false
  server_side_encryption_configuration {
    rule {
        apply_server_side_encryption_by_default {
        kms_master_key_id = aws_kms_key.mykey.arn
        sse_algorithm = "aws:kms"
      }
    }
  }
  # Mantendo múltiplas versões de um objeto no mesmo bucket
  versioning {
    enabled = true
  }
}

3. Agora, execute os comandos abaixo para navegar até o diretório ~\\terraform-s3-demo e iniciar o Terraform. O Terraform inicializa os plugins e provedores necessários para trabalhar com recursos.

O Terraform geralmente utiliza uma abordagem de três comandos em ordem sequencial terraform init, terraform plan e terraform apply.

cd ~\terraform-s3-demo       # Mudar para o diretório ~\terraform-s3-demo
terraform init               # Iniciar o Terraform
terraform plan               # Garantir que a sintaxe da sua configuração esteja correta
terraform apply -auto-approve # Provisionar o bucket AWS S3

Criando Instâncias AWS EC2 e Usuários IAM

Na seção anterior, você aprendeu como criar um único objeto (bucket AWS S3) usando o Terraform com o provedor AWS. Mas na verdade, você pode criar vários objetos do mesmo tipo usando o Terraform com o provedor AWS.

1. Crie uma pasta chamada ~/terraform-ec2-iam-demo, e então navegue até ela.

2. Abra seu editor de código favorito, copie/cole a configuração abaixo e salve o arquivo como main.tf no diretório ~/terraform-ec2-iam-demo.

O código abaixo cria duas instâncias EC2 ec21a e ec21a, com os tipos de instância t2.micro e t2.medium , em seguida, cria usuários IAM com quatro nomes diferentes. A ami declarada no código é uma Amazon Machine Image (AMI), que fornece as informações necessárias para iniciar uma instância, como o tipo de sistema operacional, quais softwares instalar, etc.

Você pode encontrar AMIs do Linux usando o console da Amazon EC2.

# Criando a instância com o tipo de instância t2.micro e t2.medium
resource "aws_instance" "my-machine" {
# Declarando a AMI
  ami = "ami-0a91cd140a1fc148a"
  for_each  = {
      key1 = "t2.micro"
	    key2 = "t2.medium"
   }
  instance_type  = each.value
	key_name       = each.key
    tags =  {
	   Name  = each.value
	}
}
# Criando usuários IAM com quatro nomes diferentes
resource "aws_iam_user" "accounts" {
  for_each = toset( ["Account1", "Account2", "Account3", "Account4"] )
  name     = each.key
}

3. Em seguida, crie outro arquivo, copie/cole o código abaixo e salve o arquivo como vars.tf no diretório ~/terraform-ec2-iam-demo.

O código abaixo declara todas as variáveis, que são referenciadas no arquivo main.tf. Após executar o código Terraform, a variável tag_ec2 é atribuída aos valores ec21a e ec21b para as duas instâncias EC2 definidas no arquivo main.tf.

variable "tag_ec2" {
  type = list(string)
  default = ["ec21a","ec21b"]
}

4. Crie outro arquivo de configuração Terraform chamado output.tf no diretório ~/terraform-ec2-iam-demo, em seguida, copie/cole o código abaixo no arquivo output.tf.

Após a execução bem-sucedida do comando terraform apply, você deverá ver os valores de ${aws_instance.my-machine.*.id} e ${aws_iam_user.accounts.*.name} no final da saída do comando.

O código abaixo instrui o Terraform a referenciar os recursos aws_instance e aws_iam_user definidos no arquivo de configuração main.tf.

output "aws_instance" {
   value = "${aws_instance.my-machine.*.id}"
}
output "aws_iam_user" {
   value = "${aws_iam_user.accounts.*.name}"
}

5. Crie mais um arquivo de configuração no diretório ~/terraform-ec2-iam-demo chamado provider.tf e cole o código abaixo no arquivo provider.tf. O arquivo provider.tf abaixo define o provedor AWS do Terraform para que o Terraform saiba como interagir com todos os recursos AWS que você definiu nos passos anteriores.

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

6. Agora, verifique se todos os arquivos necessários abaixo estão contidos na pasta ~/terraform-ec2-iam-demo executando o comando tree.

Showing all the Terraform configuration files required

7. Execute os comandos abaixo na ordem sequencial para inicializar o Terraform e criar Instâncias EC2 da AWS e Usuários IAM.

terraform init
terraform plan
terraform apply
Terraform apply command executed successfully.

Finalmente, acesse o Console de Gerenciamento da AWS e depois vá para o serviço EC2 da AWS e o console IAM.

Nas seguintes capturas de tela, você pode verificar que as instâncias EC2 e os usuários IAM existem.

Verifying the two EC2 instances that got created using Terraform
Verifying the four IAM users that got created using Terraform

Conclusão

Com este guia definitivo, agora você tem o conhecimento necessário para trabalhar com o Provedor AWS, desde declarar até executar o Provedor AWS dentro do Terraform. Você também aprendeu como o Provedor AWS permite que você declare credenciais de várias maneiras de forma segura.

Agora, qual serviço AWS você tem em mente para gerenciar com o Provedor AWS e o Terraform?

Source:
https://adamtheautomator.com/terraform-aws/