Funções e políticas para AWS com Serverless Framework

Funções e políticas para AWS com Serverless Framework

As políticas são um elemento da Amazon Web Services (AWS) associado a uma identidade, um serviço, etc., onde podemos configurar as ações que pode realizar em um ou mais recursos. Estas políticas não podem ser atribuídas diretamente a um serviço AWS (Lambda, EC3, Glue, etc.), mas requerem um intermediário que, neste caso, é a função.

As funções são uma parte fundamental da AWS, pois as usamos para controlar as ações que um usuário ou outro serviço pode realizar. As funções são criadas para uma conta e podem ser utilizadas em diferentes regiões (tendo em conta a estrutura dos recursos em cada política atribuída à função), sendo geridas através do portal Identity and Access Management (IAM).

Existem diferentes ações que nos permitem executar políticas e funções. Eles estão entre eles:

  • Delegação de permissão: As funções permitem atribuir permissões específicas a serviços ou usuários sem precisar compartilhar credenciais. Isto é especialmente útil em cenários onde é necessário conceder acesso temporário a recursos específicos.
  • Acesso a serviços: As funções podem ser assumidas por serviços e aplicativos em execução no ambiente AWS. Isso permite que os aplicativos acessem outros serviços sem a necessidade de armazenar credenciais diretamente no código.
  • Acesso Transitório: As funções podem ser usadas para fornecer acesso temporário a usuários ou serviços, gerando credenciais temporárias (tokens) que possuem um período de validade definido.
  • Confiança entre contas (Cross over account): As funções também podem ser usadas para estabelecer relações de confiança entre contas da AWS, permitindo que recursos de uma conta sejam acessíveis por entidades de outras contas.

Para obter mais informações sobre políticas e permissões no IAM, consulte a documentação oficial aqui.

Importante: Todos os serviços na AWS nascem sem permissões (políticas), portanto é possível definir uma função criada previamente e com as permissões necessárias para que funcione corretamente.

Exemplo 1: O usuário tem uma função associada que pode listar os buckets existentes no S3. Se o usuário quiser criar um novo bucket, o console AWS mostrará um aviso de que ele não tem as permissões necessárias para criar um bucket.

Como funciona a delegação de permissão (espanhol).


Exemplo 2: Temos um serviço (Lambda) que precisa criar e ler registros de um banco de dados no DynamoDB. Caso o Lambda tente atualizar ou excluir, você receberá um erro.

Como funciona a delegação de permissão (espanhol).


Uma das boas práticas na hora de criar funções e políticas é dar a permissão mínima, para que a nossa função só possa realizar as tarefas realmente necessárias para o bom funcionamento do nosso serviço, evitando uma escalada de ações que prejudiquem a segurança dos nossos serviços. AWS Well-Architect (“O bom arquiteto da AWS”) é um guia com diretrizes para que nosso ecossistema AWS tenha as melhores práticas em segurança e escalabilidade.

Criação de políticas

Diante do exposto, é hora de iniciar o processo onde criaremos uma política de acesso a um bucket S3 e outra que permita inserir e obter elementos do Dynamo. Ambos serão aplicados a um Lambda.

Usaremos o CloudFormation para criar nossas políticas e funções, evitando o uso do console AWS.

Estrutura de uma política

Nome da nossa política: Nomenclatura que nossa política terá dentro do nosso serverless e como nos referiremos a ela em outros arquivos.

Type: O tipo de recurso, como uma política gerenciada pelo AWS IAM, que será AWS::IAM::ManagedPolicy.

Properties: Nesta seção definiremos os atributos necessários para que nossa política possa ser criada.

ManagedPolicyName: O nome exclusivo da nossa política no IAM. Será aquele que veremos na função ao usar o console AWS. Da mesma forma, será o nome com o qual nosso ARN (Amazon Resource Name).

Description: Opcional, descreva o que e por que é uma política.

Path: Definimos o local onde nossa política será armazenada. Geralmente o caminho raiz.

PolicyDocument: Definiremos o documento de política que detalha as permissões concedidas, que se tornará o bloco de código JavaScript que vemos no console.

Version: A versão da estrutura política.

Statement: Define as permissões da política.

Effect: Definimos se a política permite ou proíbe uma ação.

Action: Especificaremos as ações permitidas ou proibidas.

Resource: Listamos os recursos aos quais esta política se aplica.

Política para acessar objetos em um bucket (arquivopolicies.yml)

Resources:

DemoListoProEdSantosHnPolicy:

Type: AWS::IAM::ManagedPolicy

Properties:

ManagedPolicyName: DemoListoProEdSantosHnPolicy

Description: Permite que nuestra lambda acceda a objetos en un bucket S3.

Path: "/"

PolicyDocument:

Version: "2012-10-17"

Statement:

- Effect: Allow

Action:

- s3:GetObject

Resource:

- arn:aws:s3:::nombre-de-nuestro-bucket/*

- arn:aws:s3:::nombre-de-nuestro-bucket

OBS: Com esta política, nosso papel poderá obter (get) objetos que estão dentro do nosso bucketnome-do-nosso-bucket”, mas você não poderá listar, fazer upload, excluir, atualizar objetos ou gerar uma url pré-assinada, etc.

Política para inserir e obter registros de uma tabela do Dynamo (arquivo policies.yml)

Resources:

DemoListoProEdSantosHnPolicy:

DemoListoProEdSantosHnDynamoPolicy:

Type: AWS::IAM::ManagedPolicy

Properties:

ManagedPolicyName: DemoListoProEdSantosHnDynamoPolicy

Description: Permite que nuestra lambda Inserte y obtenga registros de Dynamo.

Path: "/"

PolicyDocument:

Version: "2012-10-17"

Statement:

- Effect: Allow

Action:

- dynamodb:BatchGetItem

- dynamodb:GetItem

- dynamodb:Query

- dynamodb:Scan

- dynamodb:BatchWriteItem

- dynamodb:PutItem

Resource: "arn:aws:dynamodb:{region}:{account_id}:table/ListoProTable"

OBS: Com esta política, nossa função poderá obter um registro, um lote de registros (limitado pela nossa configuração do Dynamo), pesquisar registros, inserir um registro ou inserir vários registros. Na seção Resource devemos adicionar a região e o ID da nossa conta onde a tabela do Dynamo está localizada.

Se tivermos um ambiente de desenvolvimento em uma região e nosso ambiente de produção em outra e em ambas as regiões nosso recurso tiver o mesmo nome, devemos considerar não deixar a região explicitamente em nosso yml. Recomenda-se usar um * em vez da nossa região. Desta forma, a nossa política será aplicada a todas as regiões.

Resource: "arn:aws:dynamodb:*:{account_id}:table/ListoProTable"

Criação de função

Depois de criarmos as políticas que permitem que nosso Lambda acesse um bucket S3 e uma tabela Dynamo, podemos criar nossa função à qual nosso Lambda será atribuído.

Estrutura de uma função

Nome da nossa função: Corresponde ao nome que nossa função terá dentro do nosso serverless e como nos referiremos a ela em outros arquivos.

Type: O tipo de recurso como uma política gerenciada pelo AWS IAM, que será AWS::IAM::Role.

Properties: Nesta seção definiremos os atributos necessários para que nossa função possa ser criada.

RoleName: Nosso nome exclusivo no IAM será o nome que podemos pesquisar para atribuir a um serviço na AWS. Da mesma forma, o nome com o qual nosso RNA será composto.

MaxSessionDuration: Define a duração máxima de uma sessão assumida por esta função. Pelo menos é uma hora ou 3600 segundos.

AssumeRolePolicyDocument: Define o documento que controla quem pode assumir esta função.

Statement: Define as políticas dentro do documento.

Effect: Define se a política permite ou proíbe uma ação.

Principal: Especifica o principal que tem permissão para assumir essa função.

Action: Especificamos a ação permitida.

ManagedPolicyArns: Listamos os ARNs de política que a função terá.

Criação de função (roles.yml file)

Resources:

DemoListoProEdSantoHnRol:

Type: AWS::IAM::Role

Properties:

RoleName: DemoListoProEdSantoHnRol

MaxSessionDuration: 3600

AssumeRolePolicyDocument:

Statement:

- Effect: Allow

Principal:

Service: lambda.amazonaws.com

   Action:

- sts:AssumeRole

ManagedPolicyArns:

- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

- Ref: DemoListoProEdSantosHnPolicy

- Ref: DemoListoProEdSantosHnDynamoPolicy

Principal: Nosso papel pode ser assumido pelo serviço Lambda.

Action: Especificamos que um serviço (definido no principal) pode usar esta função.

ManagedPolicyArns: Especificamos as três políticas que usaremos:

  • AWSLambdaBasicExecutionRole: É uma política fornecida pela AWS que fornece permissões básicas para nosso Lambda gravar logs e outras permissões essenciais.
  • Ref: DemoListoProEdSantosHnPolicy: refere-se à nossa política definida anteriormente em policies.yml. O Serverless Framework converterá os arquivos individuais em um arquivo para ser enviado à AWS.
  • Ref: DemoListoProEdSantosHnDynamoPolicy: Semelhante ao anterior.

Para implantar nossas funções e permissões com o Serverless Framework, devemos criar nosso arquivo serverless.yml (semelhante ao arquivo que cria a seção abaixo).

Serverless.yml

service: nombre-de-proyecto-iam

provider:

name: aws

runtime: python3.8

stage: ${self:custom.stage, 'dev'}

region: ${self:custom.config.${self:custom.stage}.my-region}

custom:

stage: ${opt:stage, 'dev'}

config:

dev:

account_id: ''

my-region: ${opt:region, 'us-east-2'}

prd:

account_id: ''

my-region: ${opt:region, 'us-east-1'}

resources:

- ${file(policies.yml)}

- ${file(roles.yml)}

Para finalizar basta escrever o comando serverless deploy na pasta onde nosso arquivo serverless.yml está localizado. Com isso criamos as políticas e a função necessária para o nosso Lambda.

O código mostrado neste artigo pode ser baixado no seguinte repositório: https://github.com/edsantoshn/aws-posts


Em resumo, a criação de políticas e funções na AWS por meio do CloudFormation e do Serverless Framework oferece uma abordagem robusta e segura para gerenciar permissões.

Seguindo boas práticas de concessão de permissões mínimas, controle de acesso e confiança na documentação oficial, podemos garantir um ambiente de nuvem confiável e escalável.

💡
As opiniões e comentários expressos neste artigo são de propriedade exclusiva de seu autor e não representam necessariamente o ponto de vista da Revelo.

A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.