Creación de roles y políticas para AWS con Serverless Framework

Creación de roles y políticas para AWS con Serverless Framework

Las políticas son un elemento dentro de Amazon Web Services (AWS) asociado a una identidad, un servicio, etc., donde podemos configurar las acciones que ésta podrá realizar sobre uno o varios recursos. Dichas políticas no pueden ser asignadas directamente sobre un servicio (Lambda, EC3, Glue, etc.) de AWS directamente, sino que necesitan un intermediario que, en este caso, es el rol.

Los roles son una parte fundamental de AWS, ya que los utilizamos para controlar las acciones que un usuario u otro servicio puede realizar. Los roles son creados para una cuenta y se pueden utilizar en diferentes regiones (teniendo en cuenta la estructura de los recursos en cada política asignada al rol), siendo administrados a través del portal de Administración de Acceso e Identidad (IAM, por sus siglas en inglés).

Existen diferentes acciones que nos permiten realizar las políticas y roles. Entre ellas están:

  • Delegación de permisos: Los roles permiten asignar permisos específicos a servicios o usuarios sin tener que compartir credenciales. Esto es especialmente útil en escenarios donde es necesario otorgar acceso temporal a recursos específicos.
  • Acceso a Servicios: Los roles pueden ser asumidos por servicios y aplicaciones que se ejecutan en el entorno de AWS. Esto permite que las aplicaciones accedan a otros servicios sin la necesidad de almacenar credenciales directamente en el código.
  • Acceso Transitorio: Los roles pueden ser utilizados para proporcionar acceso temporal a usuarios o servicios mediante la generación de credenciales temporales (tokens) que tienen un período de validez definido.
  • Confianza entre cuentas (Cross over account): Los roles también se pueden utilizar para establecer relaciones de confianza entre cuentas de AWS, lo que permite que los recursos de una cuenta sean accesibles por entidades en otras cuentas.

Para más información sobre políticas y permisos en IAM, consulta la documentación oficial aquí.

Importante: Todos los servicios en AWS nacen sin permisos (políticas), por lo que es posible definir un rol creado anteriormente y con los permisos necesarios para que éste funcione de manera adecuada.

Ejemplo 1: El usuario tiene un rol asociado que puede listar los buckets existentes en S3. Si el usuario desea crear un nuevo bucket, la consola de AWS les mostrará una advertencia por no contar con los permisos necesarios para crear un bucket.

Forma en que trabaja la delegación de permisos. 


Ejemplo 2: Tenemos un servicio (Lambda) que necesita crear y leer registros de una base de datos en DynamoDB. En caso de que la Lambda trate de actualizar o eliminar, obtendrá un error.

Forma en que trabaja el acceso a servicios.


Una de las buenas prácticas cuando se crean los roles y políticas es dar el permiso mínimo, para que nuestro rol solo pueda hacer las tareas realmente necesarias para el buen funcionamiento de nuestro servicio, previniendo una escalada de acciones que perjudiquen la seguridad de nuestros servicios. AWS Well-Architect (“El buen arquitecto de AWS”) es una guía con pautas para que nuestro ecosistema AWS tenga las mejores prácticas en seguridad y escalabilidad.

Creación de Políticas

Considerando lo anterior, es hora de iniciar con el proceso donde crearemos una política para acceder a un bucket de S3 y otra que permita insertar y obtener elementos de Dynamo. Ambas serán aplicadas a una Lambda.

Utilizaremos CloudFormation para crear nuestras políticas y roles, evitando el uso de la consola de AWS.

Estructura de una política

Nombre de nuestra política: Nomenclatura que tendrá nuestra política dentro de nuestro serverless y cómo nos referiremos a ella en otros archivos.

Type: El tipo de recurso como una política administrada por AWS IAM el cual será AWS::IAM::ManagedPolicy.

Properties: en esta sección definiremos los atributos necesarios para que nuestra política pueda ser creada.

ManagedPolicyName: El nombre único de nuestra política en IAM. Será el que nosotros miraremos dentro del rol al momento de usar la consola de AWS. Asimismo, será el nombre con el cual estará compuesto nuestro ARN (Amazon Resource Name).

Description: Opcional, describe qué y para qué es una política.

Path: definimos la ubicación donde se almacenará nuestra política. Por lo general, la ruta raíz.

PolicyDocument: Definiremos el documento de la política que detalla los permisos que se otorgan, el cual  se convertirá en el bloque de código JavaScript que vemos en la consola.

Version: La versión de la estructura de políticas.

Statement: Define los permisos de la política.

Effect: Definimos si la política permite o prohíbe una acción.

Action: Especificaremos la o las acciones permitidas o prohibidas.

Resource: Enlistamos los recursos en los cuales aplica esta política.

Política para Acceder a objetos de un bucket (policies.yml file)

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

Nota: Con esta política, nuestro rol podrá obtener (get) objetos que estén dentro de nuestro bucket “nombre-de-nuestro-bucket”, pero no podrá listar, subir, eliminar, actualizar objetos u generar una url prefirmada, etc.

Política para Insertar y Obtener registros de una tabla de Dynamo (policies.yml file)

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"

Nota: Con esta política, nuestro rol podrá obtener un registro, un batch de registros (limitados por la configuración de nuestro Dynamo), buscar registros, insertar un registro, o insertar multiples registros. En la sección de Resource (recurso) debemos agregar región y nuestro id de cuenta donde se encuentra la tabla de Dynamo.

Si tenemos un ambiente de desarrollo en una región y en otra nuestro ambiente productivo y en ambas regiones nuestro recurso se llama igual, debemos considerar no dejar la región de forma explícita en nuestro yml. Lo recomendado es utilizar un * en lugar de nuestra región. De esta forma, nuestra política aplicará para todas las regiones.

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

Creación de Roles

Una vez creadas las políticas que permitan que nuestra Lambda acceda a un bucket de S3 y a una tabla de Dynamo, podemos crear nuestro rol que tendrá asignada nuestra Lambda.

Estructura de un Rol

Nombre de nuestro rol: Corresponde al nombre que tendrá nuestro rol dentro de nuestro serverless y cómo nos referiremos a él en otros archivos.

Type: El tipo de recurso como una política administrada por AWS IAM, el cual será AWS::IAM::Role.

Properties: En esta sección, definiremos los atributos necesarios para que nuestro rol pueda ser creado.

RoleName: El nombre único de nuestro en IAM este será el nombre que nosotros podremos buscar para asignarlo a un servicio en AWS. Asimismo, el nombre con el cual estará compuesto nuestro ARN.

MaxSessionDuration: Define la duración máxima de una sesión asumida por este rol. Como mínimo es una hora o 3600 segundos.

AssumeRolePolicyDocument: Define el documento que controla quién puede asumir este rol.

Statement: Define las políticas dentro del documento.

Effect: Define si la política permite o prohíbe una acción.

Principal: Especifica el principal que tiene permitido asumir este rol.

Action: Especificamos la acción permitida.

ManagedPolicyArns: Enlistamos los ARN de políticas que tendrá el rol.

Creación del Rol (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: Nuestro rol podrá ser asumido por el servicio de Lambda.

Action: Especificamos que un servicio (definido en principal) pueda utilizar este rol.

ManagedPolicyArns: Especificamos las tres políticas que estaremos utilizando:

  • AWSLambdaBasicExecutionRole: Es una política proporcionada por AWS que brinda los permisos básicos para que nuestra Lambda pueda escribir registros y otros permisos esenciales.
  • Ref: DemoListoProEdSantosHnPolicy: hace referencia a nuestra política anteriormente definida en policies.yml. Serverless Framework convertirá los archivos individuales en un archivo para ser enviado a AWS.
  • Ref: DemoListoProEdSantosHnDynamoPolicy: Similar al anterior.

Para desplegar nuestros roles y permisos con Serverless Framework, debemos crear nuestro archivo serverless.yml  (similar al archivo creando el apartado de infra).

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, solo debemos escribir el comando serverless deploy en la carpeta donde está ubicado nuestro archivo serverless.yml. Con esto hemos creado las políticas y el rol necesario para nuestra Lambda.

El código mostrado en este artículo podrá ser descargado en el siguiente repositorio: https://github.com/edsantoshn/aws-posts

En resumen, la creación de políticas y roles en AWS a través de CloudFormation y el Serverless Framework ofrece un enfoque robusto y seguro para gestionar permisos.

Siguiendo las buenas prácticas de otorgar permisos mínimos, controlar el acceso y confiar en la documentación oficial, podemos garantizar un entorno confiable y escalable en la nube.

💡
Las opiniones y comentarios emitidos en este artículo son propiedad única de su autor y no necesariamente representan el punto de vista de Listopro.

Listopro Community da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.