DEV Community

Cover image for GitHub Actions autenticando na AWS via OIDC
Mateus Miranda
Mateus Miranda

Posted on • Edited on

GitHub Actions autenticando na AWS via OIDC

O GitHub recentemente lançou uma funcionalidade para fazer autenticação via OIDC na AWS de dentro dos workflows, dando a oportunidade de se livrar de uma vez por todas do gerenciamento de um usuário específico para isso.

Basicamente, a autenticação agora ocorre via OIDC e a única coisa que você precisa para isso é informar qual a role vai ser utilizada.

Neste artigo, iremos realizar toda a configuração necessária na AWS via Terraform, e claro, ver como isso funciona.

Terraform

A configuração via Terraform é relativamente simples e não exige muito conhecimento avançado.

Vamos começar criando o nosso oidc provider:

resource "aws_iam_openid_connect_provider" "github" { url = "https://token.actions.githubusercontent.com" client_id_list = ["sts.amazonaws.com"] thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"] } 
Enter fullscreen mode Exit fullscreen mode

Tanto a informação de url quanto client_id_list são fornecidas pelo GitHub na própria documentação deles, que você pode ler aqui.

Já o thumbprint_list foi mais chato de entender pois ele é gerado baseado na chave ssl do certificado da configuração do openid do GitHub. O que importa aqui é: esse valor é baseado na url, então ele é estático e você pode apenas copiar e colar sem medo.

Mas caso você queira ir fundo nesse tópico, leia um pouco Como Obter a impressão digital da CA raiz para um provedor de identidade OpenID Connect e também este Changelog.

O próximo passo é criar o nosso policy document, dando permissão para os repositórios fazerem assume role:

data "aws_iam_policy_document" "github_actions_assume_role" { statement { actions = ["sts:AssumeRoleWithWebIdentity"] principals { type = "Federated" identifiers = [aws_iam_openid_connect_provider.github.arn] } condition { test = "StringEquals" variable = "token.actions.githubusercontent.com:aud" values = ["sts.amazonaws.com"] } condition { test = "StringLike" variable = "token.actions.githubusercontent.com:sub" values = [ "repo:org1/*:*", "repo:org2/*:*" ] } } 
Enter fullscreen mode Exit fullscreen mode

No exemplo acima, qualquer repositório da org1 ou org2 terão permissão sts:AssumeRoleWithWebIdentity e consequentemente, assumir a nossa role que vamos criar.

É possível restringir essa permissão para alguns repositórios (e até mesmo branches específicos), para isso basta alterar a sua condition para:

 condition { test = "StringLike" variable = "token.actions.githubusercontent.com:sub" values = [ "repo:org/meu-repositorio:*", ] } 
Enter fullscreen mode Exit fullscreen mode

Seguindo no nosso tutorial, agora precisamos criar a nossa role de fato e associá-la ao documento previamente criado:

resource "aws_iam_role" "github_actions" { name = "github-actions" assume_role_policy = data.aws_iam_policy_document.github_actions_assume_role.json } 
Enter fullscreen mode Exit fullscreen mode

Agora precisamos criar um outro documento de policy, dessa vez com as permissões que a nossa role terá.

Neste caso, iremos ter permissão para realizar algumas operações no nosso ECR, respeitando a única regra de que esse repositório tenha uma tag permit-github-action=true

data "aws_iam_policy_document" "github_actions" { statement { actions = [ "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability", "ecr:CompleteLayerUpload", "ecr:GetDownloadUrlForLayer", "ecr:InitiateLayerUpload", "ecr:PutImage", "ecr:UploadLayerPart", ] resources = ["*"] condition { test = "StringEquals" variable = "aws:ResourceTag/permit-github-action" values = ["true"] } } 
Enter fullscreen mode Exit fullscreen mode

Reparem que no nosso exemplo estamos utilizando apenas ECR, mas nada impede que você conceda permissão para outros serviços dentro da AWS: S3, SQS, etc.

E por fim, precisamos criar a nossa policy baseada no documento que criamos e depois anexar ela à nossa role:

resource "aws_iam_policy" "github_actions" { name = "github-actions" description = "Grant Github Actions the ability to push to ECR" policy = data.aws_iam_policy_document.github_actions.json } resource "aws_iam_role_policy_attachment" "github_actions" { role = aws_iam_role.github_actions.name policy_arn = aws_iam_policy.github_actions.arn } 
Enter fullscreen mode Exit fullscreen mode

Para finalizar o nosso exemplo, vamos criar um repositório e colocar uma tag nele:

resource "aws_ecr_repository" "repo" { name = "meu/repositorio" image_tag_mutability = "IMMUTABLE" image_scanning_configuration { scan_on_push = true } tag = { "permit-github-action" = true } } 
Enter fullscreen mode Exit fullscreen mode

Github Actions

Basicamente, a configuração do lado do Github Actions é bem simples e não demanda muita mudança se você já está usando via access key e secret key

A primeira coisa que você precisa configurar, segundo a própria documentação do GitHub são as permissões:

 permissions: id-token: write contents: read 
Enter fullscreen mode Exit fullscreen mode

E depois, na actions para configurar as credenciais, informar qual a role vai ser utilizada (a que criamos anteriormente via terraform)

 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@master with: role-to-assume: arn:aws:iam::XXXXXXXXXXXX:role/github-actions aws-region: eu-west-1 - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 
Enter fullscreen mode Exit fullscreen mode

Aqui você pode ver o conteúdo final do arquivo YAML.

name: Continuous Delivery on: [push, pull_request] jobs: build-and-push: runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@master with: role-to-assume: arn:aws:iam::XXXXXXXXXXXX:role/github-actions aws-region: eu-west-1 - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: Checkout uses: actions/checkout@v2 - name: Build, tag, and push image to Amazon ECR env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} ECR_REPOSITORY: meu/repositorio IMAGE_TAG: ${{ github.sha }} run: | docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG 
Enter fullscreen mode Exit fullscreen mode

Espero que tenham curtido! :)

Top comments (3)

Collapse
 
rasouza profile image
Rodrigo Souza

Ótimos insights em volta do tema. Congrats!

Collapse
 
pehesi97 profile image
Pedro Silva

Por que você usou o sts.amazonaws.com em vez do que foi passado na documentação do GitHub? Fiquei curioso.

Collapse
 
mmiranda profile image
Mateus Miranda

Esse é o valor da "audiencia" que é setado no configure-aws-credentials actions (github.com/aws-actions/configure-a...)

A própria documentação do Github foi atualizada para esse novo valor, vou atualizar e retirar esse trecho do artigo visto que ele não é mais válido :)