Verificando IDs de AMIs da AWS no Terraform com Regula e Open Policy Agent
7 de outubro de 2021
0 minutos de leituraNota do editor
Este blog foi publicado originalmente em fugue.co. A Fugue se juntou à Snyk em 2022 e é um componente essencial do Snyk IaC.
Na semana passada, anunciamos o Fugue IaC, que permite às equipes de engenharia de nuvem proteger a infraestrutura como código (IaC) e o ambiente de execução na nuvem usando as mesmas políticas. Para executar verificações de IaC localmente, a Fugue desenvolveu o Regula, uma ferramenta de código aberto criada com base no Open Policy Agent (OPA).
O Regula pode ser usado com ou sem o Fugue. Ele vem com centenas de regras prontas para verificar infraestrutura como código (IaC) em Terraform e CloudFormation, além de manifestos do Kubernetes. Essas regras são mapeadas para os CIS Benchmarks e abrangem muitas vulnerabilidades de segurança.
Mas às vezes há políticas específicas da organização que você quer aplicar — por exemplo, exigir que instâncias do Amazon EC2 usem AMIs aprovadas. Nesses casos, você pode escrever uma regra personalizada usando a linguagem Rego do OPA, e o Regula vai aplicá-la à sua IaC. Assim, se a sua IaC declarar uma AMI não aprovada, a verificação do Regula falhará.
Nesta publicação:
Vamos escrever uma regra personalizada para verificar as AMIs do AWS EC2 declaradas no Terraform, explicando o código Rego linha por linha.
Vamos usar nossa ferramenta de código aberto Regula para testar a regra com um arquivo Terraform em não conformidade.
Vamos corrigir o Terraform em não conformidade.
Esta publicação usa o Regula para verificar HCL do Terraform, mas você também pode usar exatamente a mesma regra personalizada com o SaaS do Fugue para verificar recursos no ambiente de execução da nuvem. Isso é possível graças ao Unified Policy Engine do Fugue, que permite usar as mesmas regras na IaC e no ambiente de execução.
Você encontra todo o código neste gist do GitHub.
Vamos lá!
Primeiros passos
Baixe os arquivos de código
No nosso gist do GitHub, selecione o botão Download ZIP e extraia os arquivos. São dois arquivos:
approved_ami.rego – uma regra personalizada escrita em Rego
ami.tf – um arquivo HCL do Terraform que declara duas instâncias EC2: uma em conformidade e outra em não conformidade
Instale o Regula
O próximo passo é instalar o Regula, caso ainda não tenha feito isso. Se você usa o Homebrew, execute estes comandos no terminal:
Como alternativa, você pode instalar um binário pré-compilado para sua plataforma ou, se preferir, executar o Regula com o Docker.
Como escrever a regra personalizada
Primeiro, vamos decidir que tipo de regra escrever. O Regula oferece dois tipos de regra: simples e avançada. As regras simples são úteis quando você verifica um único tipo de recurso. As regras avançadas são mais indicadas para lógicas complexas que envolvem vários recursos ou verificam a ausência de recursos.
Vamos verificar apenas um tipo de recurso do Terraform, aws_instance, então escreveremos uma regra simples.
Declaração de pacote
Vamos começar pelo básico. Todas as regras do Regula precisam ter uma declaração de pacote que comece com rules. e termine com um identificador curto (linha 4):
Metadados
Podemos adicionar metadados opcionalmente (linhas 6 a 18):
Isso não é obrigatório, mas torna os relatórios do Regula ainda mais informativos.
Tipo de recurso
Em seguida, especificamos qual tipo de recurso do Terraform queremos verificar (linha 20):
Essa sintaxe indica que a entrada será uma única instância do AWS EC2. Quando o Regula aplicar a regra ao nosso Terraform, ele avaliará uma instância por vez.
Conjunto de AMIs aprovadas
Para simplificar, vamos supor que sua organização aprovou estes dois IDs de AMI:
ami-09e67e426f25ce0d7
ami-03d5c68bab01f3496
(Se tiver curiosidade, esses são os IDs do Ubuntu Server 20.04 LTS HVM, tipo de volume SSD, nas regiões us-east-1 e us-west-2, respectivamente.)
Agora, vamos criar um conjunto com os IDs das AMIs aprovadas. Vamos chamá-lo de approved_amis (linhas 22 a 26):
A regra deny
Por fim, vamos escrever uma regra deny. É nela que fica a lógica principal! A regra deny define as condições em que um recurso deve falhar na verificação.
Vamos caprichar um pouco e retornar uma mensagem de erro personalizada que informa o ID da AMI não aprovada quando uma instância falha na verificação do Regula.
Nossa regra deny deve verificar se o ID da AMI da instância que está sendo avaliada pertence ao conjunto de AMIs aprovadas. Se não pertencer, deny deve retornar uma mensagem de erro para esse recurso (ou seja, gerar um resultado de regra com falha). deny é definido nas linhas 28 a 31:
Vamos analisar a lógica mais de perto:
input.ami representa o atributo ami de cada instância EC2 no documento de entrada (seu arquivo HCL do Terraform — ou, mais especificamente, uma representação JSON dele, transformada pelo Regula nos bastidores).
not approved_amis[input.ami] será avaliado como true se o atributo ami da instância atual não pertencer ao conjunto.
Juntando tudo, a regra deny diz: “Se input.ami não estiver em approved_amis, a verificação do Regula deverá falhar e retornar uma mensagem de erro.”
Definimos a mensagem de erro nesta linha:
Aqui usamos a função integrada sprintf do Rego para exibir a ami do recurso que está sendo avaliado.
E essa é a nossa regra personalizada! Veja o código completo. Agora, vamos colocar o Regula à prova!
Executando a regra personalizada com o Regula
Agora, vamos testar a regra em um arquivo simples do Terraform. O HCL do Terraform no nosso gist do GitHub define duas instâncias EC2: uma instância “boa”, com o ID de AMI aprovado ami-09e67e426f25ce0d7, e uma instância “ruim”, com o ID de AMI nada suspeito ami-totallylegitamiid.
Execute o Regula
No terminal, use cd para acessar o diretório que contém os arquivos de código e execute este comando:
Este comando executa nossa regra personalizada no arquivo Terraform. A flag --user-only indica que somente a regra personalizada deve ser aplicada; para esta publicação, não vamos usar a biblioteca de regras integradas do Regula. (Ainda assim, é recomendável usar as regras integradas, incluídas por padrão quando você executa regula run.)
O resultado é:

Como você pode ver, nosso arquivo Terraform falhou na regra com a mensagem ami-totallylegitamiid is not an approved AMI ID. Ótimo: isso significa que nossa regra personalizada funcionou! O Regula mostrou que a instância aws_instance.bad (linha 13, coluna 1) não tinha um ID de AMI aprovado.
Veja um relatório mais detalhado
Para ver mais detalhes, vamos conferir o relatório completo, formatado como JSON:
Aqui vemos o resultado completo, incluindo todos os resultados das regras. Observe abaixo que aws_instance.bad aparece novamente com resultado FAIL, enquanto aws_instance.good tem resultado PASS:
Você também pode conferir os outros metadados que definimos anteriormente na regra.
Corrija o Terraform
Para deixar o Terraform em conformidade, edite ami.tf e substitua ami-totallylegitamiid por ami-09e67e426f25ce0d7. Em seguida, execute o Regula novamente. Desta vez, vamos usar o formato de texto padrão:
E o resultado é:
Sucesso! Protegemos nossa IaC no Terraform usando apenas AMIs aprovadas, como comprova o Regula.
Para saber mais
Nesta publicação, escrevemos uma regra personalizada em Rego, usamos o Regula para verificá-la em um arquivo HCL do Terraform e deixamos o Terraform em conformidade.
Para saber mais sobre o Regula, acesse o site da documentação do Regula. Estes recursos também podem ser úteis:
Segurança de IaC pensada para quem desenvolve
A Snyk protege sua infraestrutura como código do ciclo de vida do desenvolvimento de software até a execução na nuvem, com um mecanismo unificado de políticas como código para que todas as equipes possam desenvolver, implantar e operar com segurança.
