Configurando o HashiCorp Boundary no Kubernetes para acessar bancos de dados

Dionathan Chrys
TOTVS Developers
Published in
8 min readJan 11, 2024
Logo do Boundary
HashiCorp Boundary

O que é o HashiCorp Boundary?

O Boundary da Hashicorp pode prover acesso a diversos sistemas através da identidade de usuário unificada, com apenas um login é possível conceder acesso a diversos sistemas como: instâncias (SSH ou RDP), bancos de dados, cluster Kubernetes e até mesmo requisições HTTP que precisam de autenticação.

Qual a vantagem?

Imagine um ambiente onde você tem um banco de dados postgres, uma instância linux e um cluster Kubernetes. Sem um gerenciamento de identidade unificado seria necessário criar credenciais para cada um destes sistemas, porém com o Boundary e um login, é possível acessar esses sistemas, criando os perfis e permissões necessárias.

Mãos a obra!

Eu criei um repositório no GitHub onde fiz uma POC para acessar os bancos de dados, pude testar bem essa funcionalidade do Boundary.

https://github.com/dionathanchrys/poc-boundary

Vou explicar agora como começar usar ele na sua máquina, simulando 3 ambientes diferentes. É isso mesmo que você leu, não vamos usar o modo dev, vamos subir 3 clusters (espero que sua máquina aguente 🤯 )

Vamos aos requisitos:

Após fazer o clone do repositório vamos executar o script em shell que irá criar todos os ambientes.

Estando na raiz do repositório, execute o script “create-envs.sh” localizado na pasta “app/kind-cluster/base”:

app/kind-cluster/base/create-envs.sh

Ele irá realizar as seguintes ações:

  • Criar uma rede docker para os cluster terem conexões entre eles.
  • Criar os cluster através do Kind.
  • Aplicas os manifestos Kubernetes, criando os componentes do Boundary (controller, workers e banco de dados), os bancos de dados de teste (simulando uma aplicação chamada foo)

Após a execução teremos 3 cluster diferentes, simulando ambiente de serviço, desenvolvimento e produção.

OBS: Entre os apply de deployments e jobs, tem o comando kubectl wait para esperar estar pronto para seguir o script, tem um timeout de 120s, caso seja pouco pode aumentar sem problema nenhum!
Use o comando a seguir para apagar tudo e poder rodar o script novamente sem problemas: “docker rm -f svc-cluster-control-plane dev-cluster-control-plane prd-cluster-control-plane && docker network rm cluster-kind”

Confirme se os contêineres (clusters) estão em execução usando o comando “docker container ls”, veja abaixo como deve ser a saída:

❯ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0fb7d586e3bd kindest/node:v1.25.3 "/usr/local/bin/entr…" 13 minutes ago Up 12 minutes 127.0.0.1:44133->6443/tcp prd-cluster-control-plane
dca90dcb21be kindest/node:v1.25.3 "/usr/local/bin/entr…" 14 minutes ago Up 13 minutes 127.0.0.1:37027->6443/tcp dev-cluster-control-plane
133d9eb5909e kindest/node:v1.25.3 "/usr/local/bin/entr…" 14 minutes ago Up 14 minutes 127.0.0.1:44399->6443/tcp svc-cluster-control-plane

Verifique a saída do terminal que ao executar o job de migração do boundary ele informa a senha do admin e salva ela também no repo. Acesse pelo seu navegador o seguinte endereço e use as credenciais recém obtidas.

http://192.168.222.10:32200

Tela de login do Boundary
Tela de Login do Boundary

Assim que realizar o login, vá até o menu Workers, deverá estar como no print abaixo, mostrando os 2 workers autenticados.

Tela dos Workers
Workers

Volte no menu Orgs e vamos criar uma nova organização (já existe uma de exemplo para que você possa explorar), clique no botão ‘New Org’ e dê um nome criativo.

Criando nova org
Criando nova Org

Agora vamos criar nossos projetos dentro da organização (Org), clique no menu Projects e após New.

Novo projeto
Criando projetos

Crie um projeto para cada ambiente para o nosso app imaginário foo, desenvolvimento (dev) e produção (prd).

Projetos criados
Novos projetos

Entre no projeto de dev e vá em Credential Store.

Vamos inserir as credenciais do banco, assim ao conectar no Target pelo CLI do Boundary ele irá conectar usando essas credenciais. (Não se preocupe veremos tudo isso mais tarde).

Criando Credential Store
Criando Credential Store

Crie uma do tipo Static.

Static Credential
Static Credential

Após criar vá em Credentials.

Nova credencial
Nova credencial

Insira um nome, tipo use: Username & Password e as credenciais do banco que se encontram no ConfigMap do Kubernetes.
app/foo-postgres/overlay/dev/kustomization.yaml:linha 15

Inserindo credenciais
Inserindo credenciais
Credenciais criadas
Credenciais criadas

Vá até o menu Targets e depois em New.

Menu targets
Targets

Na adição do target vamos direto ao ponto!

  • Target Address: Mostra como opcional porque você pode configurar os endereços através dos Host Catalogs e Hosts Sets, mas vamos configurar aqui o endereço diretamente no target, neste caso vamos configurar o nome do service do Kubernetes do banco de dados de dev, rode o comando abaixo para verificar:
❯ kubectl get services --context kind-dev-cluster -n foo-app
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
foo-postgres-svc ClusterIP 10.96.45.70 <none> 5432/TCP 25 minutes

O nome do service é “foo-postgres-svc”, porém como vamos acessar de um namespace para outro dentro do mesmo cluster, precisamos passar o endereço completo do service, que é composto do nome do “service.namespace.svc.cluster.local”. O nosso ficará assim: foo-postgres-svc.foo-app.svc.cluster.local

  • Default Port: Porta de acesso ao nosso banco de dados, nosso caso é a 5432, padrão do postgres.
Criando target
Criando target

Mais abaixo temos a configuração de Workers, neste caso como temos “múltiplos ambientes” precisamos configurar e dizer ao Controller qual Worker deve ser usado para realizar a conexão com o Target, isso é feito através da tag.

O desenho da nossa estrutura é como essa abaixo, ela foi se baseada nesta página da documentação do Boundary

Exemplo acessando um target no ambiente de DEV

… voltando a configuração de Worker dentro do Target precisamos colocar a tag do Worker, as tags foram configuradas na linha 17 do arquivo de DEV:

  • app/boundary-worker/overlay/dev/config/pki-worker.hclem DEV
  tags {
env = ["dev"]
type = ["egress"]
}

Aqui na documentação você pode conferir mais detalhes sobre as tags dos workers.
No filtro use conforme o print abaixo:

"dev" in "/tags/env"
tag do worker
Tag do worker

Depois de criar o target entre nele novamente e vá em brokered credentials.

Adicionando Brokered Credentials
Adicionando Brokered Credentials

Faça a associação.

Associando Brokered Credentials
Associando Brokered Credentials
Brokered Credentials Associado
Brokered Credentials Associado

Agora você repetir o processo para o ambiente de PRD, criando as credenciais, o target e associando.

Vamos ver funcionando!

Agora que está tudo configurado e ok, vamos acessar.
Iremos usar o client CLI do Boundary, poderíamos fazer pelo app com interface, porém não conseguimos usar o Brokered Credentials e perderia o sentido deste artigo. É claro que poderíamos integrar com um Vault e melhorar ainda mais o gerenciamento das senhas, mas isso ficará para um outro momento.

Vamos ao terminal…

boundary authenticate password \
-addr http://192.168.222.10:32200 \
-keyring-type secret-service \
-auth-method-id ampw_eSdigWzNW1 \
-scope-id o_KV9tApRJlT

Use as mesmas credenciais que foram utilizadas para fazer login na interface web.

Para entender bem os parâmetros você pode rodar o seguinte comando “boundary authenticate --help” ou pode consultar a documentação.

Os ids vão mudar em cada instalação, para consulta-los segue os links:

Todos esses parâmetros podem ser configurados com variáveis de ambiente, o que agilizaria o processo de login(sugiro que faça isso), para consultar o nome das variáveis, use os seguintes comandos:

  • boundary authenticate --help
  • boundary authenticate password --help

Caso tenha logado com sucesso, terá a seguinte saída:

❯boundary authenticate password \
-addr http://192.168.222.10:32200 \
-keyring-type secret-service \
-scope-id o_KV9tApRJlT \
-auth-method-id ampw_eSdigWzNW1
Please enter the login name (it will be hidden):
Please enter the password (it will be hidden):

Authentication information:
Account ID: acctpw_nIvOD6rkRR
Auth Method ID: ampw_eSdigWzNW1
Expiration Time: Tue, 16 Jan 2024 21:46:54 -03
User ID: u_d0hKJ0jcXH

The token was successfully stored in the chosen keyring and is not displayed here.

Agora podemos nos conectar no target, vamos ao comando:

boundary connect postgres \
-addr http://192.168.222.10:32200 \
-keyring-type secret-service \
-target-id ttcp_lwgSUO7dSG \
-dbname postgres

Se quiser saber mais… “boundary connect --help”

Dando tudo certo teremos a seguinte saída:

❯ boundary connect postgres \                                                                                       ⏎ 23:19:30 - 2024-01-09
-addr http://192.168.222.10:32200 \
-keyring-type secret-service \
-target-id ttcp_lwgSUO7dSG \
-dbname postgres
psql (14.10 (Ubuntu 14.10-0ubuntu0.22.04.1), server 13.13 (Debian 13.13-1.pgdg120+1))
Type "help" for help.

postgres=#

Isso que significa que você está dentro do banco de dados, sem informar as credenciais no momento do login, pois ele usou aquelas que associamos anteriormente. Em um cenário real a pessoa que fará acesso ao banco não terá contato com as credenciais, você deverá configurar Roles e Grupos para que ela tenha acesso somente aos targets.

Conclusão

Apresentamos uma POC, onde podemos simular de forma simples alguns ambientes, mas em um cenário real onde teremos OIDC para logar e Vault para guardar as senhas fica bem mais interessante.

Pretendo no futuro ainda implementar mais algumas coisas nessa POC, listei elas nas issues do repositório, mas caso você tenha alguma sugestão ou encontre algum problema, não deixe de abrir uma issue no GitHub.

Espero ter te ajudado de alguma forma, qualquer dúvida deixe um comentário.

--

--

Dionathan Chrys
TOTVS Developers

DevOps Analyst | AWS Cloud Practitioner Certified | Kubernetes | Docker | Azure Pipelines