Obs.: Antes de começar, lembro que trabalhar com dados sensíveis é algo delicado e relativo às políticas de segurança de sua organização . Assim, busque sempre uma solução que se adeque melhor ao seu ambiente.



O que vamos fazer?



Iremos provisionar clusters Kubernetes nas principais clouds atuais (AWS, Azure, GCP), através de códigos Terraform.



O Vault terá o papel de prover as credenciais para acessar as Clouds, utilizando o Dynamic Secrets (secrets on-demand) .



Por que o Hashicorp Vault?



Você pode estar se perguntando o porquê de utilizar o Vault para gerenciar as secrets nas Clouds, se pode usar as soluções nativas delas, como AWS KMS ou Azure Key Vault. Bom, alguns motivos seriam:



  • OpenSource



  • Cloud Agnostic (se integra aos principais serviços atuais, utilizando uma única solução para diversas clouds ou serviços, diminuindo a necessidade de aprender inúmeras ferramentas e reduzindo problemas de integração )



  • Centralized Security System (pode ser utilizado como um encryption system, KMS system, PKI system ou até mesmo como armazenamento de credenciais, ou seja, é possível mantê-lo como ponto central para a maioria das necessidades de segurança do seu ambiente)



Requisitos:



  • Vault Up & Running: você precisará de uma instância do Vault em execução. Talvez, esse vídeo possa ajudá-lo a provisionar o Vault de forma rápida e simples:



https://www.youtube.com/watch?v=807F0kH8iUM



repositório aqui



  • Ter noção básica, de leve, com Terraform e K8s.



  • Possuir uma account em cada Cloud (AWS, Azure, GCP).



Todo código para essa demo está aqui.



Get Started



AWS



Vamos iniciar na AWS, mas antes é importante entender que utilizaremos como base o module Terraform EKS (a grosso modo o EKS é o Kubernetes como serviço da AWS).



Com sua instância de Vault em execução e unseal, vamos iniciar habilitando a secret engine da AWS:



vault secrets enable aws



Obs.: Secrets Engines são componentes essenciais do Vault para gerar secrets, armazenar credenciais, criptografar dados, se integrar a serviços externos ou tudo isso ao mesmo tempo. É importante pensar em secrets engines de acordo com seu propósito.



Com a secret engine AWS habilitada, poderemos gerar credenciais de forma dinâmica, baseadas em IAM policies. Use sua access e secret key para configurar a secret engine:



vault write aws/config/root access_key=AKIAJWVN5Z4FOFT7NLNA secret_key=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 region=us-east-1



Atenção:
Nunca utilize sua credencial root da AWS. Crie um user ou role específico para o Vault. Siga as boas práticas de segurança IAM da AWS aqui.
Configurando a role que estará atrelada às credenciais:



vault write aws/roles/eks-role \
credential_type=iam_user \
policy_document=-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "eks:*",
"Resource": "*"
}
]
}
EOF



Neste ponto, o Vault já é capaz de gerar as credenciais realizando um read no endpoint/creds:



vault read aws/creds/admin
Key Value
--- -----
lease_id aws/creds/admin/f3e92392-7d9c-09c8-c921-575d62fe80d8
lease_duration 768h
lease_renewable true
access_key AKIAIOWQXTLW36DV7IEA
secret_key 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
security_token <nil>



Com a secret engine AWS configurada, podemos realizar o deployment do EKS na AWS. Faça clone do repositório:



git clone git@github.com:GuhAlex/terraform.git



Acesse o diretório terraform/aws/eks:



terraform/
├── aws
│ ├── eks <== here
│ └── iam
├── azure
│ └── aks
└── gcp
└── gke



Uma breve descrição de como organizei os arquivos TF :



  • main.tf — Contém todos os required providers utilizados.
    Required providers são uma forma explícita de controlar e manter as versões dos providers utilizados e devem ser declarados no bloco principal do seu código Terraform.



  • providers.tf — Nesse arquivo estão as configurações necessárias dos providers utilizados. Observe que os dados sensíveis são acessados por data sources através do Vault provider.



  • eks.tf — Onde estão todos os detalhes do module EKS que será provisionado.



  • variables.tf — Aqui estão os valores que devem ser fornecidos, como o token de acesso do Vault e sua URL (veja mais sobre a autenticação no Vault aqui).



Após fornecer os valores no arquivo variables. tf , podemos iniciar deploy do EKS com o workflow do Terraform:



terraform init
terraform plan
terraform apply



Se tudo ocorrer bem, seu cluster EKS será provisionado na AWS, com as credenciais utilizadas dinamicamente.



AZURE



Agora vamos partir para Azure onde utilizaremos o seguinte module do Terraform para provisionar o AKS (Kubernetes como serviço da Azure).



De forma semelhante à secret engine da AWS, todos os dados sensíveis estarão centralizados no Vault, mas para isso vamos precisar habilitar dois tipos de secrets engines:



vault secrets enable azure
vault secrets enable kv



secret engine da Azure irá nos fornecer service principals de forma dinâmica com as atribuições de role e groups.



Na Azure, o service principal é uma identidade de segurança utilizada para acessar recursos específicos da Azure.



secret engine KV é uma forma genérica para armazenar credenciais e nesse caso iremos utilizá-la para manter a subscription id e tenant id .



Para configurar a secret engine da Azure, você vai precisar dos seguintes dados:



  • subscription_id



  • tenant_id



  • client_id



  • client_secret



No portal da Azure, siga os seguintes caminhos para acessar os valores:



Subscription ID:



Portal Azure → Subscriptions → Overview



Tenant ID:



Portal Azure → Azure Active Directory → Overview



Você vai precisar criar um app registration (client_id) e uma client secret:



Client ID:



Portal Azure → Azure Active Directory →App registrations → New registration



Client Secret:



Portal Azure → App registration → Certificates & secrets → New client Secret



Agora é necessário habilitar o Microsoft Graph API desta app registration que acabamos de criar e o caminho é este:



Portal Azure → App registration →API permissions → Add a permission



Veja as seguintes permissões que precisam estar habilitadas aqui.



Com as permissões da API Microsoft Graph configuradas e com os valores de autenticação, já podemos configurar nossa secret engine:



vault write azure/config \
subscription_id=$AZURE_SUBSCRIPTION_ID \
tenant_id=$AZURE_TENANT_ID \
client_id=$AZURE_CLIENT_ID \
client_secret=$AZURE_CLIENT_SECRET \
use_microsoft_graph_api=true



Configurando a role, ela estará atrelada à secret:



vault write azure/roles/myrole ttl=1h azure_roles=-<<EOF
[
{
"role_name": "Owner",
"scope": "/subscriptions/$AZURE_SUBSCRIPTION_ID"
}
]
EOF



Observe que a role tem um escopo para todos os recursos da Azure, com time-to-live de uma hora. Realize um read no endpoint /creds para validar a configuração:



vault read azure/creds/my-role

Key Value
--- -----
lease_id azure/creds/sp_role/1afd0969-ad23-73e2-f974-962f7ac1c2b4
lease_duration 60m
lease_renewable true
client_id 408bf248-dd4e-4be5-919a-7f6207a307ab
client_secret ad06228a-2db9-4e0a-8a5d-e047c7f32594



Legal, agora nosso Vault é capaz de gerar secrets da Azure on-demand.



Mas ainda não é o suficiente para implantarmos o AKS, porque no Azure provider — quando utilizamos a autenticação com service principal e client secret — é requerido o subscription e tenant id em hardcoded (não recomendado) ou em variáveis de ambiente.



É aí que entra a secret engine KV, mencionada anteriormente. Para isso, realize a seguinte instrução:



vault kv put kv/azure subscription_id=$AZURE_SUBSCRIPTION_ID tenant_id=$AZURE_TENANT_ID



Agora sim, podemos provisionar nosso AKS! Na raiz do repositório, acesse o diretório azure/aks:



terraform/
├── aws
│ ├── eks
│ └── iam
├── azure
│ └── aks <== here
└── gcp
└── gke



Os arquivos TF seguem praticamente a mesma estrutura do aws/eks/, porém nesse caso o arquivo apps.tf foi adicionado:



  • aks.tf — Onde estão todos os detalhes do module AKS que será provisionado.



  • apps.tf — Contém alguns helms release que serão aplicados junto ao K8s



Após fornecer os valores no arquivo variables. tf, podemos iniciar deploy do AKS com o workflow do Terraform:



terraform init
terraform plan
terraform apply



GCP



Na Cloud do Google, iremos nos basear no seguinte módulo do Terraform para provisionarmos nosso GKE.



Vamos começar habilitando a secret engine do gcp.



vault secrets enable gcp



A engine do GCP pode gerar secrets keys (google services accounts) ou OAuth tokens on-demand baseados em IAM policies.



Mas antes de configurarmos a secret engine GCP é importante entender alguns detalhes:



Rolesets



Rolesets são services accounts do GCP atreladas a um conjunto de bindings do IAM, controladas pelo Vault.



Static Accounts



Static accounts são services accounts do GCP criadas fora do Vault e fornecidas ao Vault para gerar access tokens ou keys.



Aqui, utilizaremos Static accounts para gerar access tokens.
Para configurar nossa secret engine precisaremos da account credential:



Acesse a console do gcp e siga o seguinte caminho para gerar o arquivo json com as credenciais:



Home → IAM & Admin → Service accounts



Consulte as permissões que a service account precisa aqui.
Crie uma service account e nela gere uma key no formato json:





e a utilize para ajustar a secret engine:



vault write gcp/config credentials=@credentials.json



Na raiz do repositório, acesse o diretório do gcp/gke:



terraform/
├── aws
│ ├── eks
│ └── iam
├── azure
│ └── aks
└── gcp
└── gke <== here



No diretório gcp/gke, utilize o arquivo roleset.hcl para criar a Vault policy para leitura dos tokens:



vault policy write roleset-policy roleset.hcl



Configure a Static account para gerar os tokens access através do arquivo mybindings.hcl:



vault write gcp/static-account/token-account service_account_email="your-service-account-email@project.com.br" secret_type="access_token" token_scopes="https://www.googleapis.com/auth/cloud-platform" bindings=@mybindings.hcl



Obs.: ajuste o arquivo mybindings.hcl com o nome do projeto que você está utilizando.



Cheque a configuração:



vault read gcp/static-account/token-account/token
Key Value
--- -----
expires_at_seconds 1537402548
token ya29.c.ElodBmNPwHUNY5gcBpnXcE4ywG4w1k...
token_ttl 3599



Neste ponto já podemos criar o GKE. Os arquivos TF estão da mesma maneira que /aws/eks e o /azure/aks. Após fornecer os valores no arquivo variables. tf,, podemos iniciar deploy do GKE com o workflow do Terraform:



terraform init
terraform plan
terraform apply



Conclusão



Tentei com esse artigo demonstrar uma forma de utilizar o Vault da Hashicorp para manter seu workflow IaC um pouco mais seguro, utilizando o dynamic secrets para autenticação nas principais Clouds atuais. Além disso, nos códigos Terraform você verá exemplos interessantes da utilização do provider Vault do Terraform.



É importante ressaltar que essa é apenas uma demonstração do uso de dynamic secrets do Vault para fins de testes e desenvolvimento. Em um ambiente produtivo é imprescindível que o Vault esteja configurado com TLS para garantir encriptação na comunicação ponto a ponto.



Veja aqui as boas práticas para manter seu Vault mais seguro. E lembre-se: segurança é um processo que não tem fim e sempre é possível melhorá-lo (ou não rsrs).



Autor: Gustavo


Social

Contact us

Almeda Campinas 802, CJ 12, Jardim Paulista,

São Paulo - SP, 01404-001

Opportunities

Our content

Social

Contact us

Almeda Campinas 802, CJ 12, Jardim Paulista,

São Paulo - SP, 01404-001

Opportunities

Our content

Social

Contact us

Almeda Campinas 802, CJ 12, Jardim Paulista,

São Paulo - SP, 01404-001

Opportunities

Our content