↓Pular para o conteúdo principal
  1. blog/
ARTIGO TÉCNICO

AWS CLI e OCI CLI no Semaphore sem colocar credenciais no Git

Como separar imagem do executor, arquivos de configuração cloud, profiles do projeto e secrets para usar AWS/OCI em automações Semaphore sem versionar credenciais.

·5 minutos

Playbooks Ansible que operam cloud frequentemente dependem de algo além do próprio Ansible.

No meu executor Semaphore, algumas automações precisam chamar diretamente:

1
2
AWS CLI
OCI CLI

O caminho mais rápido seria colocar configurações e credenciais junto do repositório.

É também um caminho que eu não quero manter.

A stack privada separa três coisas:

1
2
3
ferramenta
configuração/credencial
contexto do projeto

Essa separação permite reconstruir o executor sem versionar o material sensível.

A CLI pertence à imagem #

AWS CLI e OCI CLI são dependências do ambiente de execução.

Por isso entram no Dockerfile.

A imagem de referência instala AWS CLI pelo sistema e OCI CLI dentro de um virtualenv Python.

Conceitualmente:

1
2
3
RUN instalar aws-cli python3 venv
RUN python -m venv /opt/cloud-cli
RUN /opt/cloud-cli/bin/pip install oci-cli

Assim um playbook não depende de alguém ter instalado a CLI manualmente no host do Semaphore.

Credencial não pertence à imagem #

O Dockerfile não contém:

1
2
3
4
access key
secret key
private key OCI
tenancy/user/fingerprint reais

Esses dados entram em runtime.

Na implementação privada, diretórios AWS e OCI do host são montados no home do usuário Semaphore como read-only.

1
2
3
volumes:
  - ./aws:/home/semaphore/.aws:ro
  - ./oci:/home/semaphore/.oci:ro

Isso mantém imagem e segredo com ciclos de vida diferentes.

:ro reduz alteração acidental #

O mount read-only não impede a task de usar uma credencial.

Ele impede que aquela task altere o arquivo montado através do container.

Essa proteção é útil para comandos que só deveriam consumir configuração.

Mas não resolve tudo.

Um processo que consegue ler credenciais ainda pode utilizá-las conforme as permissões IAM associadas.

O controle principal continua sendo:

  • privilégio mínimo na conta cloud;
  • RBAC no Semaphore;
  • templates revisados;
  • secrets protegidos no host;
  • logs sem vazamento de tokens.

O caminho dos arquivos é explícito #

A stack informa ao executor onde procurar configuração:

1
2
3
AWS_CONFIG_FILE
AWS_SHARED_CREDENTIALS_FILE
OCI_CLI_CONFIG_FILE

Isso evita depender de descoberta implícita se o home ou contexto mudar.

Também facilita diagnosticar:

1
qual arquivo a task está usando?

Profile de projeto não precisa virar campo de Survey #

Na documentação do Semaphore, profiles fixos do projeto ficam em Variable Group.

A ideia é evitar que a pessoa escolha credencial estrutural toda vez que executa uma receita.

O Survey deve pedir decisões da tarefa:

1
2
3
4
target
ambiente
motivo
ticket

E não:

1
qual conta cloud devo usar hoje?

quando essa resposta já deveria pertencer ao próprio projeto/template.

Validar identidade antes da mudança #

Quando existe operação multi-account, gosto de tornar a identidade observável.

Na AWS:

1
aws sts get-caller-identity --profile "$AWS_PROFILE"

Na OCI, uma chamada de leitura simples pode validar o profile, por exemplo listagem de regiões ou outra operação IAM read-only adequada ao ambiente.

O princípio é:

1
2
3
4
profile configurado
→ chamada de identidade/leitura
→ confirmar contexto
→ executar mudança

Não presumir que um nome de profile prova a conta efetivamente acessada.

O repositório público não deve trazer nem os profiles reais #

Mesmo sem secret, publicar nomes de profiles, account IDs, ARNs, tenancy ou usuário cloud reais pode revelar topologia e organização desnecessárias.

Num blueprint eu usaria algo como:

1
2
AWS_PROFILE=example-prod
OCI_CLI_PROFILE=EXAMPLE

E exemplos fictícios de configuração.

A documentação explica o padrão sem copiar a identidade operacional.

.env.example não deve virar .env disfarçado #

Um exemplo público deveria conter somente placeholders:

1
2
AWS_PROFILE=example
OCI_CLI_PROFILE=EXAMPLE

Nunca:

1
2
3
4
chave real mascarada pela metade
OCID real
ARN real
hostname interno

Exemplo serve para ensinar formato, não para preservar uma fotografia de produção.

Secrets de cloud não deveriam aparecer em output #

Playbooks e wrappers precisam evitar:

1
2
3
set -x
cat ~/.aws/credentials
cat ~/.oci/config

em logs do orquestrador.

Se uma task precisa manipular material sensível, Ansible também oferece no_log: true para pontos específicos — com cuidado porque isso reduz observabilidade de erro.

O melhor cenário é não imprimir segredo em primeiro lugar.

Uma imagem grande pede política de atualização #

Adicionar AWS/OCI CLIs ao executor cria dependências que envelhecem.

O ambiente precisa saber:

1
2
3
qual versão está instalada?
quando atualizar?
como testar compatibilidade?

No caso da imagem base do Semaphore, a versão do produto está fixada.

Para um blueprint público, eu também evitaria depender de latest em componentes críticos e colocaria validação das CLIs no CI/build.

Smoke test antes de liberar templates cloud #

Antes de permitir resize/deploy/alteração, um template LOW pode validar:

1
2
3
4
5
6
ansible --version
aws --version
oci --version
aws configure list-profiles
aws sts get-caller-identity --profile example
oci iam region list --profile EXAMPLE

Com profiles reais apenas no ambiente privado.

Isso separa:

1
executor quebrado

de:

1
playbook de mudança quebrado

O que a fonte sustenta #

O repositório privado comprova:

  • AWS CLI e OCI CLI instaladas no executor;
  • arquivos AWS/OCI montados no home do Semaphore como read-only;
  • paths informados por variáveis de ambiente;
  • Variable Group documentado para profiles do projeto;
  • validações de CLI/cloud documentadas;
  • regra explícita de não salvar secrets no Git;
  • .gitignore cobrindo diretórios cloud e chaves.

Identificadores reais foram deliberadamente omitidos do conteúdo público.

O principal aprendizado #

Para automação cloud, eu separo:

1
2
3
4
CLI → imagem
credencial/config → runtime privado
profile/contexto → projeto/template
parâmetro da execução → Survey

Quando essas quatro coisas se misturam no mesmo YAML ou repositório, a automação fica difícil de compartilhar e perigosa de publicar.

Separadas, a plataforma pode ser reproduzível sem transformar Git em cofre de credenciais.

TEM UM CENÁRIO PARECIDO?

Me chama.

Manda o contexto, os sintomas e o que já foi testado. Bora organizar as evidências antes de sair mexendo.

Falar com Castro →
Sem enrolação. Com evidência.