O blog da AWS

Acelere sua jornada em nuvem AWS através do uso da estrutura de múltiplas contas e Account Factory for Terraform (AFT)  – Parte 3

Por Lucas Leme Lopes, Arquiteto de Infraestrutura Cloud, AWS;

Rubens Macegossa Dias, Arquiteto de Infraestrutura Cloud, AWS;

e Victor Okuhama, Arquiteto de Aplicação Cloud, AWS.

Para trazer visibilidade das possibilidades que a ferramenta oferece, será apresentado um caso de onde o AFT foi fundamental para o seu sucesso.

Caso de uso real

Neste cenário de uso, consideramos um ambiente onde eram necessárias a criação de 4 contas AWS para cada projeto de negócio, cada uma destinada a um ambiente específico, além de uma conta adicional para ferramentas de desenvolvimento (DevTools). O processo de criação dessas contas era totalmente manual e envolvia etapas como:

  • Criação das contas;
  • Configuração de VPC e alocação de IPs, registrando essas informações em uma planilha;
  • Estabelecimento de Roles cross-account para integração com esteiras de CI/CD;
  • Implementação da estrutura de deploy e configuração das esteiras de CI/CD.

Esse procedimento consumia considerável quantidade de tempo para ser concluído (10 dias no último teste de referência) e carecia de padronização devido à natureza manual do processo.

Inteligência e Customizações – account-customizations

Para os desafios apresentados no caso de uso, foi escolhido o account-customizations para automatizar todas as tarefas que eram executadas de forma manual.

Contas Workload (desenvolvimento, homologação e produção)

As contas de workload terão de customização a criação da VPC seguindo as melhores práticas e com seu endereçamento IP gerenciado pelo CIDR MGMT.

Obtendo CIDR disponível para uso

Na pasta “aft-account-customizations / <tipo-da-conta> / api_helpers” há o script “pre-api-helpers.sh”, ele irá executar os seguintes passos:

  1. Checar se a conta já alocou algum IP no CIDR MGMT, consultando o AWS SSM Parameter Store com o nome “/<número-da-conta>/vpc/cidr
  2. Caso não houver CIDR alocado, será executado o Python “py” que fará a alocação do mesmo no CIDR MGMT e irá gravar o Parameter Store com o CIDR alocado.
has_parameter_store=`aws ssm get-parameter --name "/$accountnumber/vpc/cidr" --query Parameter.Value --output text`
if [[ -z "$has_parameter_store" ]]; then
echo "---------------------Executing ./get_cidr.py---------------------"
cidr=$(python3 ./get_cidr.py $accountnumber $accountName $regionCidr $ipamApiGtw $ipamLambda)
echo "---------------------Show CIDR before convertion---------------------"
echo $cidr
echo "---------------------Convert CIDR string---------------------"
IFS='""'
read -ra ARR <<< "$cidr"
cidr="${ARR[3]}"
echo "---------------------Show CIDR after convertion---------------------"
echo $cidr
echo "---------------------Change AWS_PROFILE=AFT-TARGET-admin---------------------"
export AWS_PROFILE=aft-target
echo "aws sts get-caller-identity"
aws sts get-caller-identity
echo "---------------------Creating CIDR parameter store---------------------"
aws ssm put-parameter --name "/$accountnumber/vpc/cidr" --value "$cidr" --type "String" --overwrite
echo "---------------------"
else
echo "SSM parameter store for CIDR already exists, no need for a new creation."
fi

Criando VPC

Na pasta “aft-account-customizations / <tipo-da-conta> / api_helpers / terraform” há o IAC de criação da VPC que fará:

  1. Consulta do Parameter Store para recuperar o CIDR alocado para aquela conta;
  2. Cria a VPC de acordo com o ambiente
    1. Produção → VPC com 3 subnets públicas e 3 subnets privadas com Nat Gateway em 3 AZs
    2. Homologação → VPC com 3 subnets públicas e 3 subnets privadas com Nat Gateway em 1 AZ
    3. Desenvolvimento → VPC com 3 subnets públicas e 3 subnets privadas com Nat Gateway em 1 AZ
data "aws_region" "current" {}
locals {
region = data.aws_region.current.name
cidr = data.aws_ssm_parameter.cidr.value
cidr_subnets = nonsensitive(cidrsubnets(local.cidr, 4, 4, 4, 4, 4, 4))
azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
}

Atualizando o CIDR MGMT com o ID da VPC

Na pasta “aft-account-customizations / <tipo-da-conta> / api_helpers” há o script “post-api-helpers.sh”, ele irá executar os seguintes passos:

  1. Executará o Python “update_cidr.py” que fará a atualização do CIDR MGMT associando o VPC ID (criada no passo anterior) com o CIDR alocado
echo "---------------------Get path_store, cidr_block and current_VPC_ID variables---------------------"
path_store="/$accountnumber/vpc/cidr"
cidr_block=`aws ssm get-parameter --name $path_store --query Parameter.Value --output text`
current_VPC_ID=`aws ec2 describe-vpcs --query "Vpcs[?CidrBlock=='$cidr_block'].VpcId" --output text`
echo "path_store: $path_store"
echo "cidr_block: $cidr_block"
echo "current_VPC_ID: $current_VPC_ID"
echo "---------------------Change AWS_PROFILE=SHARED-management-admin---------------------"
export AWS_PROFILE=aft-management
echo "aws sts get-caller-identity"
aws sts get-caller-identity
echo "aws sts get-caller-identity"
echo "---------------------Executing ./update_cidr.py---------------------"
response=$(python3 ./update_cidr.py $current_VPC_ID $cidr_block $regionCidr $ipamApiGtw $ipamLambda)
echo "---------------------print python response!---------------------"
echo $response

Figura 1: Fluxo para alocação de novo IP

Contas Pipeline

As contas de Pipeline serão criadas com um repositório do AWS CodeCommit (para abrigar o IAC do ambiente), uma pipeline de infraestrutura para cada ambiente (dev, hml e prd) e roles cross-account para que a pipeline funcione corretamente.

Criando Roles cross-account

Para identificar as contas de workload que precisam ser associadas às roles cross-account, o sistema consulta o DynamoDB do AFT e extrai os IDs correspondentes das contas.

Na pasta “aft-account-customizations / PIPELINE / api_helpers” há o script “pre-api-helpers.sh”, ele irá executar os seguintes passos:

  1. Consulta a tabela aft-request do DynamoDB coletando os e-mails utilizados no momento da requisição de contas, utilizando como filtro o nome do Projeto.
  2. Com a lista de e-mails, é realizado uma consulta na tabela aft-request-metadata coletando os IDs de conta e o seu tipo
echo "---------------------Get project members account ---------------------"
field="{\":project\":{\"S\":\"project\\\":\\\"$projectName\"}}"
mails=$(aws dynamodb scan --table-name aft-request --filter-expression "contains(custom_fields,:project)" --expression-attribute-values $field | jq '.Items[].id.S')
for item in $mails; do
x="{\":email\":{\"S\":$item}}"
aws dynamodb scan --table-name aft-request-metadata --filter-expression " email = :email" --expression-attribute-values $x | jq -j '.Items[].id.S, ";" ,.Items[].account_customizations_name.S,"\n"' >> MembersAccounts.txt
done
mv MembersAccounts.txt $DEFAULT_PATH/$CUSTOMIZATION/terraform/MembersAccounts.txt
echo "---------------------Create roles In account workload ---------------------"
cat "$DEFAULT_PATH/$CUSTOMIZATION/terraform/MembersAccounts.txt"
file="$DEFAULT_PATH/$CUSTOMIZATION/terraform/MembersAccounts.txt"
while read -r line; do
workloadAccountId=$(echo $line | sed -r 's/\"//g' | cut -d';' -f1)
flavor="$(echo $line | sed -r 's/\"//g' |cut -d';' -f2)"
case $flavor in
("DEV") dev_account=$workloadAccountId ;;
("HML") hml_account=$workloadAccountId ;;
("PRODUCTION") prd_account=$workloadAccountId ;;
esac
done <$file
  1. Para cada conta de Workload:
    1. script entrará na conta de workload e alterará a trust policy da role “AWSAFTExecution” permitindo que a conta de pipeline possa assumir a mesma
echo "---------------------Creating Trust Policy to Pipeline Account have access to Workloads accounts---------------------"
echo '{' > Role-Trust-Policy.json
echo ' "Version": "2012-10-17",' >> Role-Trust-Policy.json
echo ' "Statement": [' >> Role-Trust-Policy.json
echo ' {' >> Role-Trust-Policy.json
echo ' "Effect": "Allow",' >> Role-Trust-Policy.json
echo ' "Principal": {' >> Role-Trust-Policy.json
echo ' "AWS": [' >> Role-Trust-Policy.json
echo ' "arn:aws:sts::'$aftnumber':assumed-role/AWSAFTAdmin/AWSAFT-Session",' >> Role-Trust-Policy.json
echo ' "arn:aws:sts::'$accountnumber':assumed-role/AWSAFTExecution/AWSAFT-Session"' >> Role-Trust-Policy.json
echo ' ]' >> Role-Trust-Policy.json
echo ' },' >> Role-Trust-Policy.json
echo ' "Action": "sts:AssumeRole"' >> Role-Trust-Policy.json
echo ' }' >> Role-Trust-Policy.json
echo ' ]' >> Role-Trust-Policy.json
echo '}' >> Role-Trust-Policy.json

Repositório AWS CodeCommit

Na pasta “aft-account-customizations / PIPELINE / api_helpers / terraform” há o IAC de criação do repositório CodeCommit, onde será abrigado o IAC para criação do ambiente do projeto e por sua vez irá sensibilizar a pipeline.

Deploy da Pipeline de IAC

Na pasta “aft-account-customizations / PIPELINE / api_helpers” há o script “post-api-helpers.sh”, ele irá executar os seguintes passos:

  1. Para cada ambiente (dev, hml e prd):
  2. Irá preencher as variáveis de forma dinâmica do script de criação da pipeline utilizando a ferramenta Jinja
  3. Executará o script terraform para criação da pipeline de acordo com o ambiente. Nesse passo será vinculado o repositório do AWS CodeCommit (para pipeline fazer uso do mesmo) e o acesso cross-account anteriormente criado

.

echo "---------------------Ambiente DEV---------------------"
echo "---------------------Executando terraform application pipeline---------------------"
chmod +x $DEFAULT_PATH/$CUSTOMIZATION/api_helpers/application_script/terraform-deploy-dev.sh
$DEFAULT_PATH/$CUSTOMIZATION/api_helpers/application_script/terraform-deploy-dev.sh

echo "---------------------Ambiente HML---------------------"
echo "---------------------Executando terraform application pipeline---------------------"
chmod +x $DEFAULT_PATH/$CUSTOMIZATION/api_helpers/application_script/terraform-deploy-hml.sh
$DEFAULT_PATH/$CUSTOMIZATION/api_helpers/application_script/terraform-deploy-hml.sh
echo "---------------------Ambiente PRD---------------------"
echo "---------------------Executando terraform application pipeline---------------------"
chmod +x $DEFAULT_PATH/$CUSTOMIZATION/api_helpers/application_script/terraform-deploy-prd.sh
$DEFAULT_PATH/$CUSTOMIZATION/api_helpers/application_script/terraform-deploy-prd.sh

 

Resultado

Com essa inteligência criada no ambiente foi realizada uma nova coleta de benchmark, onde resultou em uma melhora expressiva saindo da casa dos 10 dias para apenas 1h40 minutos. Além disso, foi possível obter os seguintes benefícios:

  • Padronização na criação de novas contas;
  • Gerenciamento automático de endereçamento IP (antes feito manualmente);
  • Melhora na postura de segurança inicial das contas

Repositório com o código completo em https://github.com/aws-samples/aft-account-customizations-examples/tree/main

Relacionados:

Acelere sua jornada em nuvem AWS através do uso da estrutura de múltiplas contas e Account Factory for Terraform (AFT) – Parte 1

Acelere sua jornada em nuvem AWS através do uso da estrutura de múltiplas contas e Account Factory for Terraform (AFT) – Parte 2 


Sobre os autores

Lucas Leme Lopes é Arquiteto de Infraestrutura Cloud e atua no atendimento de clientes do setor público. Trabalha com soluções de Cloud há mais de 7 anos com o propósito de ajudar clientes a resolverem demandas através de tecnologia.

 

 

 

Rubens Macegossa Dias é Arquiteto de Infraestrutura Cloud na AWS e atua no time de Public Sector apoiando clientes em sua jornada para a nuvem. Possui mais de 17 anos de experiencia na área de T.I. onde atuou em multinacionais nos setores Alimentício, Industrial e de Tecnologia.

 

 

 

Victor Okuhama é Arquiteto de Aplicação Cloud e atua na área de Serviços Profissionais para o setor público. Seu conhecimento é em desenvolvimento de software e infraestrutura, antes de se juntar AWS, atuou como desenvolvedor backend na área de finanças.