Blog de Amazon Web Services (AWS)
CDK Pipelines: Despliegue y Entrega continua de aplicaciones con AWS CDK
Por Rico Huijbers, Senior Software Dev Engineer.
El AWS Cloud Development Kit (AWS CDK) es un framework de código abierto para definir infraestructura en la nube con lenguajes de programación familiares y, aprovisionarla a través de AWS CloudFormation. El AWS CDK consta de tres componentes principales:
- Un framework básico para modelar componentes de infraestructura re-utilizables
- Una interfaz de linea de comandos (CLI) para desplegar aplicaciones CDK
- La AWS Construct Library, es un conjunto de componentes de alto nivel que abstraen los recursos de la nube y los encapsulan predeterminados probado
El AWS CDK facilita la implementación de una aplicación en la nube de AWS desde su estación de trabajo simplemente ejecutando cdk deploy. Esto es genial cuando estás iniciando el desarrollo y las pruebas, sin embargo, en el caso de cargas de trabajo de producción se deben considerar canalizaciones más confiables y automatizadas.
Siempre ha sido posible configurar sistemas en modelos de Integración Continua / Entrega Continua (CI/CD por sus siglas en inglés) para el despliegue de aplicaciones con el CDK; sin embargo, los usuarios finales coinciden en que el proceso se simplifique, buscando una solución tipo llave en mano. Esto hace sentido: uno de los principales principios del CDK siempre ha sido simplificar el desarrollo de aplicaciones en la nube tanto como sea posible, para que usted pueda enfocarse en las partes que le sean relevantes.
El día de hoy nos complace anunciar el lanzamiento de Developer Preview de CDK Pipelines, una biblioteca de construcción de alto nivel que facilita la configuración de un Pipeline de entrega continua para sus aplicaciones CDK, impulsada por AWS CodePipeline. En esta publicación revisaremos como implementar un endpoint de Amazon API Gateway, con tecnología AWS Lambda,en dos cuentas diferentes, mediante CDK Pipelines.
Pre requisitos
El siguiente tutorial utiliza TypeScript y requiere la versión 1.51.0 o posterior del AWS CDK.
Para seguir este tutorial, se necesita una cuenta activa de GitHub y haber creado un repositorio como contenedor del código fuente. Las referencias OWNER y REPO, en esta publicación, es necesario reemplazarlas por el propietario y nombre del repositorio bifurcado de GitHub.
Para que AWS CodePipeline pueda leer desde este repositorio de GitHub, también necesita tener un token de acceso personal de GitHub, almacenado como un secreto en texto plano (no un secreto JSON) en AWS Secrets Manager bajo el nombre github-token. Para obtener instrucciones, consulte Tutorial: Creating and Retrieving a Secret. El token debe tener los scopes repo y admin:repo_hook.
Con CDK Pipelines es tan sencillo realizar despliegues en una cuenta y región diferentes, como lo es desplegar en la misma cuenta. Para seguir completamente este tutorial, debe tener acceso de administrador a, al menos una cuenta, pero, preferentemente dos cuentas de AWS, a las que llamamos ACCOUNT1 y ACCOUNT2. Para crear varias cuentas de AWS, puede utilizar AWS Control Tower; para obtener instrucciones al respecto, consulte AWS Control Tower — Set up & Govern a Multi-Account AWS Environment. Este tutorial asume que tiene credenciales para las cuentas configuradas en los perfiles account1—profile y account2—profile con el AWS Command Line Interface (AWS CLI) .
Conceptos
CDK Pipelines es una biblioteca de construcción de nivel superior a las que se encuentran en la AWS Construct Library. Esta biblioteca es capaz de tomar algunas decisiones a nombre del usuario, reduciendo la interacción con el sistema.
El elemento constructor más importante de la biblioteca es CDKPipeline, que configura un Pipeline, mediante CodePipeline, para que usted despliegue su aplicación con el CDK. Una canalización consta de varias etapas, que se representan en fases lógicas del despliegue. Cada etapa contiene una o más acciones que describen qué hacer en esa etapa en particular. El CDK Pipeline comienza con varias etapas y acciones predefinidas, pero se pueden agrega más etapas y acciones para adaptarlo a las necesidades de la aplicación.
El Pipeline creado por el CDKPipeline muta de manera automática. Esto significa que solo se necesita ejecutar cdk deploy una sola vez para que inicie el pipeline. Después de eso, el pipeline se actualiza automáticamente si se agregan nuevas aplicaciones o etapas CDK en el código fuente.
El siguiente diagrama ilustra las etapas de CDK Pipeline.
- Source — Esta etapa probablemente le sea la mas familiar. Se obtiene el código fuente de la aplicación CDK desde el repositorio bifurcado de GitHub, cada vez que se empuja (push) de nuevos commits sobre el repositorio, estos desencadenan el pipeline.
- Build — En esta etapa el proceso de pipeline compila el código (si es necesario) y el siguiente comando synth cdk. El producto de la ejecución de este paso, cloud assembly, es el que se utiliza para realizar todas las acciones en el resto del pipeline.
- UpdatePipeline — Esta etapa modifica el pipeline en caso necesario. Por ejemplo, si se actualiza el código para agregar una nueva etapa de despliegue al pipeline, o se agrega un nuevo activo a la aplicación, la canalización se actualiza automáticamente para reflejar los cambios realizados.
- PublishAssets — En esta etapa se preparan y publican todos los activos de archivos que está utilizando la aplicación a Amazon Simple Storage Service (Amazon S3) y todas las imágenes de Docker a Amazon Elastic Container Registry (Amazon ECR) en cada cuenta y Región desde la que se consume, para que puedan utilizarse durante el despliegue subsecuente.
Todas las etapas posteriores, que se despliegan desde el CDK application, se realizaran en la cuenta y región que especifique el código fuente.
Las combinaciones de cuenta y región en las que se desea desplegar realizan un proceso inicial de bootstrapped, lo que significa que se aprovisionará alguna infraestructura mínima en la cuenta para que el CDK pueda acceder a ella. También hay que agregar una relación de confianza a la cuenta que contiene el pipeline. Se abordará el proceso para cumplir con este requerimiento más adelante en este post.
Caso de uso
El caso de uso que abordamos en este documento despliega una aplicación simple, la cual consiste en una función Lambda que devuelve una respuesta fija a un frontend desplegado por un API Gateway accesible desde internet.
Como primer paso, es necesaria la creación de la aplicación e instalat las dependencias necesarias mediante los siguientes comandos:
mkdir cdkpipelines-demo && cd cdkpipelines-demo npx cdk init --language=typescript # Install dependencies for the CDK application npm install @aws-cdk/aws-apigateway @aws-cdk/aws-lambda \ @aws-cdk/aws-codepipeline @aws-cdk/aws-codepipeline-actions \ @types/aws-lambda # Install CDK pipelines npm install @aws-cdk/pipelines Substituir lib/cdkpipelines-demo-stack.ts el cual define la infraestructura de la aplicación. La versión final debe ser similar al siguiente ejemplo: import * as apigw from '@aws-cdk/aws-apigateway'; import * as lambda from '@aws-cdk/aws-lambda'; import { CfnOutput, Construct, Stack, StackProps } from '@aws-cdk/core'; import * as path from 'path'; /** * A stack for our simple Lambda-powered web service */ export class CdkpipelinesDemoStack extends Stack { /** * The URL of the API Gateway endpoint, for use in the integ tests */ public readonly urlOutput: CfnOutput; constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); // The Lambda function that contains the functionality const handler = new lambda.Function(this, 'Lambda', { runtime: lambda.Runtime.NODEJS_12_X, handler: 'handler.handler', code: lambda.Code.fromAsset(path.resolve(__dirname, 'lambda')), }); // An API Gateway to make the Lambda web-accessible const gw = new apigw.LambdaRestApi(this, 'Gateway', { description: 'Endpoint for a simple Lambda-powered web service', handler, }); this.urlOutput = new CfnOutput(this, 'Url', { value: gw.url, }); } } Es necesario incluir en el archivo lib/lambda/handler.ts el siguiente código el cual define un handler simple para la función AWS Lambda: import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda'; export async function handler(event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> { return { body: 'Hello from a Lambda Function', statusCode: 200, }; }
Definición de un Pipeline vacío
Después de definir el stack que compone la aplicación, es posible implementarla mediante un Pipeline.
El primer paso es definir una subclase de Stage propia, la cual describe una única unidad lógica implementable y cohesiva de su aplicación. Esto es similar a cómo se definen subclases personalizadas de Stack para describir las pilas de CloudFormation. La diferencia es que un Stack puede contener uno o más Stacks, por lo que le da la flexibilidad para hacer múltiples copias de la aplicación potencialmente compleja a través de la canalización. Para el caso de uso actual, la etapa consiste de una sola pila.
Es necesario crear el siguiente archivo lib/cdkducines-demo-stage.ts el cual contiene el siguiente código:
import { CfnOutput, Construct, Stage, StageProps } from '@aws-cdk/core'; import { CdkpipelinesDemoStack } from './cdkpipelines-demo-stack'; /** * Deployable unit of web service app */ export class CdkpipelinesDemoStage extends Stage { public readonly urlOutput: CfnOutput; constructor(scope: Construct, id: string, props?: StageProps) { super(scope, id, props); const service = new CdkpipelinesDemoStack(this, 'WebService'); // Expose CdkpipelinesDemoStack's output one level higher this.urlOutput = service.urlOutput; } } Para mantener un orden y simplificar el desarrollo, se recomienda la definición del Pipeline en el archivo de Stack, lib/cdkpipeline ines-demo-pipeline stack.ts (tener en cuenta reemplazar PROPIETARIO y REPO en el siguiente código): import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as codepipeline_actions from '@aws-cdk/aws-codepipeline-actions'; import { Construct, SecretValue, Stack, StackProps } from '@aws-cdk/core'; import { CdkPipeline, SimpleSynthAction } from "@aws-cdk/pipelines"; /** * The stack that defines the application pipeline */ export class CdkpipelinesDemoPipelineStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const sourceArtifact = new codepipeline.Artifact(); const cloudAssemblyArtifact = new codepipeline.Artifact(); const pipeline = new CdkPipeline(this, 'Pipeline', { // The pipeline name pipelineName: 'MyServicePipeline', cloudAssemblyArtifact, // Where the source can be found sourceAction: new codepipeline_actions.GitHubSourceAction({ actionName: 'GitHub', output: sourceArtifact, oauthToken: SecretValue.secretsManager('github-token'), owner: 'OWNER', repo: 'REPO', }), // How it will be built and synthesized synthAction: SimpleSynthAction.standardNpmSynth({ sourceArtifact, cloudAssemblyArtifact, // We need a build step to compile the TypeScript Lambda buildCommand: 'npm run build' }), }); // This is where we add the application stages // ... } }
El código anterior define las siguientes propiedades básicas:
- Nombre del Pipeline.
- Ubicación del Código Fuente. Es necesario ajustar la referencia para que coincida con el nombre del repositorio de GitHub.
- Instrucciones para el proceso de Build y Synthesis. Para este caso de uso, se utiliza una compilación estándar NPM build (este tipo de compilación ejecuta npm run build seguido de npx cdk synth).
Así mismo, es necesario instanciar CDKPipelinesDemoPipelinestack con la cuenta y región donde desea desplegar el Pipeline. El siguiente código debe ser adjuntado en bin/cdkducines-demo.ts (reemplazar la ACCOUNT1 y la región, si aplica):
#!/usr/bin/env node import { App } from '@aws-cdk/core'; import { CdkpipelinesDemoPipelineStack } from '../lib/cdkpipelines-demo-pipeline-stack'; const app = new App(); new CdkpipelinesDemoPipelineStack(app, 'CdkpipelinesDemoPipelineStack', { env: { account: 'ACCOUNT1', region: 'us-east-2' }, }); app.synth();
CDK Pipelines utiliza algunas nuevas características del framework CDK que se requieren activar explícitamente. El siguiente código puede ser integrado en cdk.json :
{ ... "context": { "@aws-cdk/core:newStyleStackSynthesis": true } }
Bootstrapping
Este es uno de los finales antes del despliegue del Pipeline. En primer lugar, es necesario asegurarse el entorno en el que esta planeando realizar el despliegue, específicamente con la versión más reciente del bootstrapping stack, porque los recursos del CDK bootstrapping han cambiado en la versión 1.46.0 para acomodar la nueva experiencia del CDK Pipelines.
Se requiere crear el proceso de inicio (bootstrap) en cada entorno en el que se planea desplegar una aplicación CDK. En particular, este tutorial solicita:
- Donde se desea aprovisionar el Pipeline?
- Donde se planea desplegar aplicaciones con el uso del Pipeline?
Esto se realiza una única vez, por entorno en el que se desea implementar aplicaciones CDK. Si no existe la certeza de que nuestro entorno ya ha pasado el proceso de bootstrapp, es posible volver a ejecutar el comando.
Debemos asegurar que las credenciales para ACCOUNT1 en un perfil llamado account1-profile. Para obtener más información, se puede consultar la siguiente referencia: Named Profiles. Se requiere ejecutar el siguiente comando en el directorio donde existe el archivo cdk.json:
npx cdk bootstrap \ --profile account1-profile \ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \ aws://ACCOUNT1/us-east-2
Dos cosas son importantes en este comando:
- Debido a que la ejecución de este comando se realiza en el directorio, donde json contiene la clave de contexto «@aws-CDK/Core:NewStyleStacksynthesis», el CLI cambia a los nuevos recursos de bootstrapping (post-1.46.0), los cuales son necesarios para que CDK Pipelines funcione. Esta nueva pila de bootstrapping crea un bucket en Amazon S3, y varios Roles de usuario en la cuenta de AWS, necesario para que el CLI CDK y el CDK Pipeline utilizan para desplegar el aplicativo. En el futuro, los nuevos recursos de bootstrapping se convertirán en predeterminados, sin embargo, a partir de esta escritura, aun se encuentra en estado de opt-in.
- –cloudformation-ejecuecution-policies controla los permisos que el rol de despliegue tiene para la cuenta de AWS. En el pasado, el CLI CDK tenía los mismos permisos que el usuario que estaba ejecutando la herramienta. Con los nuevos recursos de bootstrapping, el usuario que realiza el bootstrap en la cuenta controla los permisos de despliegue que el CDK tiene en la cuenta. Se require optar explícitamente para que el CDK tenga control total sobre la cuenta, y, se cuenta con la opción de cambiar por una política diferente (o conjunto de políticas), si se considera relevante.
Después de iniciado el entorno, es momento de aprovisionar el Pipeline.
Aprovisionamiento del pipeline
Tan pronto como se crea el Pipeline, este se va a ejecutar; es imperativo asegurar que la versión del código en el repositorio GitHub sea la correcta, ya que el Pipeline se actualizará basándose en él . Por lo tanto, es muy importante que el código que encuentra en GitHub sea el último validado. El primer paso es realizar el commit y el push, de todos los cambios realizados. Los siguientes comandos ejecutan dicho proceso:
Bash git add -A . git commit -m 'Initial deployment of our empty pipeline' git push
Como operación de una sola ocasión, se desplegara el stack del Pipeline:
npx cdk deploy \
–profile account1-profile \
CdkpipelinesDemoPipelineStack
Este proceso toma algunos minutos, y al final, se localiza el Pipeline en la consola de AWS dentro del servicio de CodePipeline, como se muestra en la siguiente imágen.
Sugerencia para la solución de problemas: En caso de encontrar un mensaje de “Internal Failure error” mientras se está creando el Pipeline, validar que exista un secreto de Secrets Manager con el nombre correcto configurado con el token de GitHub necesario.
Agregando la primera etapa
Hasta el momento, se ha aprovisionado un Pipeline, pero este Pipeline aún no está desplegando la aplicación. Esto se puede hacer agregando instancias de MyServiceStage al Pipeline.
Se requiere agregar una nueva importación en la parte superior de lib/cdkpipelines-demo-pipeline-stack.ts e insertar las líneas de código despues de: // This is where we add the application stages. Como en todo el proceso descrito, es necesario reemplazar ACCOUNT1 con el número de cuenta real y reemplazar us-east-2 con la región preferida:
import { CdkpipelinesDemoStage } from './cdkpipelines-demo-stage'; // ... // This is where we add the application stages pipeline.addApplicationStage(new CdkpipelinesDemoStage(this, 'PreProd', { env: { account: 'ACCOUNT1', region: 'us-east-2' } }));
Solo resta realizar un commit, acompañado de un push con estos cambios y el Pipeline se reconfigura automáticamente para agregar la nueva etapa y desplegarla. Los siguientes comandos especifican como realizar este proceso:
# 'npm run build' first to make sure there are no typos npm run build git commit -am 'Add PreProd stage' git push
Después de que finalice el Pipeline, se puede confirmar que el servicio está en funcionamiento. Dentro de la consola de CloudFormation, seleccione el Stack de PreProd-WebService, seleccione la pestaña de Outputs y en el GatewayEndpoint URL se encontrará un mensaje con la siguiente linea: ‘Hola de una Función Lambda’.
Es posible que la etapa UpdatePipeline se muestra como fallida cuando se actualiza a sí misma. Esto es algo esperado y no representa algo de qué preocuparse. El Pipeline se reinicia automáticamente y procede a desplegarse a las nuevas etapas.
Lo mismo sucede si se agrega una nuevo Stack a CDKPipelinesDemoStage: El Pipeline se actualiza automáticamente para desplegar estae nuevo Stack en todas las etapas y, si hay dependencias entre los Stacks, las despliega automáticamente en el orden correcto. Este tutorial no incluye este proceso, sin embargo !siéntete libre de probarlo!
Despliegue a una cuenta y región diferentes
Es igual de fácil desplegar etapas adicionales en una cuenta adicional. Se ajusta la configuración de arranque (bootstrapping) en ambas cuentas y regiones en las que se quiere desplegar, ademas de asegurar que existe una relación de confianza agregada a la cuenta de donde se encuentra el Pipeline.
Con credenciales para ACCOUNT2 disponibles en un perfil llamado account2-profile, se ejecuta el siguiente comando:
npx cdk bootstrap \ --profile account2-profile \ --trust ACCOUNT1 \ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \ aws://ACCOUNT2/us-west-2
El código anterior agrega –trust ACCOUNT1 lo que permitie que ACCOUNT1 se despliegue en ACCOUNT2. Ahora se utiliza esta indicación, para permitir que la canalización se despliegue en ACCOUNT2, pero es posible usar el mismo mecanismo para permitir que los desarrolladores implementen en una cuenta diferente usando la CDK CLI con solo las credenciales de su cuenta propia.
Después de realizar la configuración inicial(bootstrapping) ACCOUNT2 en region us-west-2, agregue la nueva etapa. Para efectos de este post, se denomina Prod. Agregar el siguiente código a lib/cdkpipelines-demo-pipeline-stack.ts:
pipeline.addApplicationStage(new CdkpipelinesDemoStage(this, 'Prod', { env: { account: 'ACCOUNT2', region: 'us-west-2' } })); Nuevamente, se ejecuta el comando commit y push para que el Pipeline se despliegue a una región y cuenta diferentes. # 'npm run build' first to make sure there are no typos npm run build git commit -am 'Add Prod stage' git push
Agregando validaciones
El Pipeline que se acaba de construir, se está empujando automáticamente a producción. Obviamente, a este ducto le falta algo! Un verdadero Piepline de entrega continua (CD) necesita ejecutar pruebas para asegurarse de que el nuevo código funcione.
En este tutorial se integró una prueba que utiliza curl para realizar una solicitud web contra el endpoint que se acaba de implementar, que se ejecuta en AWS CodeBuild. En un escenario del mundo real, seria ideal conectar con una suite de pruebas de integración más elaborada en este paso.
El test necesita conocer la URL del endpoint HTTP del servicio, pero ese endpoint es una API Gateway con un nombre generado aleatoriamente. Afortunadamente, se ha integrado una salida de AWS CloudFormation que contiene la dirección del servicio. Lo unico que se requiere es obtener la salida de la pila y enviarla como parámetro a la prueba. Es necesario realizar ajustes al archivo cdkpipelines-demo-pipeline-stack.ts con los datos del código que agrega la etapa PreProd para que contenga lo siguiente:
import { ShellScriptAction } from '@aws-cdk/pipelines'; // ... const preprod = new CdkpipelinesDemoStage(this, 'PreProd', { env: { account: 'ACCOUNT1', region: 'us-east-2' } }); const preprodStage = pipeline.addApplicationStage(preprod); preprodStage.addActions(new ShellScriptAction({ actionName: 'TestService', useOutputs: { // Get the stack Output from the Stage and make it available in // the shell script as $ENDPOINT_URL. ENDPOINT_URL: pipeline.stackOutput(preprod.urlOutput), }, commands: [ // Use 'curl' to GET the given URL and fail if it returns an error 'curl -Ssf $ENDPOINT_URL', ], })); Ejecutar los siguientes comandos: # 'npm run build' first to make sure there are no typos npm run build git commit -am 'Add tests to PreProd stage' git push
En la siguiente captura de pantalla, se puede ver la prueba que se está agregando al final de la etapa de PreProd.
Stacks de desarrollo
Aunque el Pipeline despliega los stacks de pruebas y producción, sigue siendo muy útil para los desarrolladores tener sus propias copias privadas de los stacks de sus aplicaciones en sus cuentas de desarrollador de AWS para iterar mientras están trabajando.
cdk deploy es un excelentemente aliado para este caso de uso. Se agrega otra instancia de CDKPipelinesDemoStage y se define el env para utilizar las variables de entorno que indican la configuración actual del CLI. Para obtener más información, consulte Environments.
Agregar el siguiente código abin/cdkpipelines-demo.ts :
import { CdkpipelinesDemoStage } from '../lib/cdkpipelines-demo-stage'; // ... new CdkpipelinesDemoStage(app, 'Dev', { env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION }, }); Todo desarrollador del equipo debe asegurarse de que su cuenta de desarrollador y región hayan realizado la configuración inicial (bootstrapped) ejecutando el siguiente comando: npx cdk bootstrap \ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \ aws://DEVELOPER_ACCOUNT/us-east-1
Ahora se puede desplegar una copia personal de la aplicación para probar, dentro de la cuenta propia, (determinada por las credenciales actuales de la CLI), ejecutando los siguientes comandos:
bash npx cdk synth npx cdk -a cdk.out/assembly-Dev deploy
Limitaciones del Preview para el desarrollador
CDK Pipelines se encuentra actualmente en Preview para el desarrollador. AWS está trabajando para solventar algunas limitaciones, y se debe tener en cuenta lo siguiente:
- No hay consultas de contexto (No context queries) — Las consultas de contexto no son compatibles. Eso significa que FromLookup() y otras funciones como ésta no funcionan.
Limpieza
Para limpiar el ambiente después de este tutorial: dentro de la consola de AWS de las diferentes cuentas utilizadas, ingrese a la consola AWS CloudFormation de las regiones donde se implemento la solución, seleccione y haga clic en Eliminar(Delete) en las siguientes pilas: CDKPipelinesDemoPipelinesStack, WebService, CDKToolKit.
El stack de pipeline (CDKPipelinesDemoPipelineStack) y la pila de bootstrapping (CDKToolKit) contienen, cada uno, la clave de AWS Key Management Service por la que se realiza un cobro de $1 USD al mes, en caso de no eliminarlas.
Conclusión
Estamos muy emocionados de que sea aún más rápido y fácil para los usuarios desarrollar e implementar sus aplicaciones de AWS utilizando el CDK. Para obtener más información sobre CDK Pipelines y todas las formas en que se puede utilizar, consulte la documentación de referencia de CDK Pipelines. Puede obtener más información sobre cómo los equipos de desarrollo de Amazon definen la infraestructura de aplicaciones en código e implementarla por etapas a través de varias cuentas y regiones de AWS, en los siguientes artículos de la Biblioteca de Amazon Builders’, Automatizar implementaciones seguras y de manos fuera. Si desea ver una demostración de la biblioteca en acción, consulte el Tech Talk Enhanced CI/CD con AWS CDK.
Esperamos haber hecho el proceso lo más sencillo y agradable posible. En caso de haber probado esta solución, y sobre todo, si consideras que nos hemos olvidado de algo o tienes un caso de uso que no se ha cubierto, ¡nos encantaría conocerlo! Haznos saber del avance en nuestra página del proyecto GitHub.
Sobre el autor
Rico Huijbers es Senior Software Development Engineer en AWS.
Sobre los traductores
Edgar Barba Perez es Arquitecto de Soluciones Sr. para Amazon Web Services en Sector Público. Edgar colabora con Dependencias de Gobierno, Instituciones Educativas y Organizaciones sin fines de lucro en México, apoyándolos en su camino a la innovación y adopción tecnológica.
José Lorenzo Cuéncar Garza es Arquitecto de Soluciones Sr. para Amazon Web Services en Sector Público. José colabora con Dependencias de Gobierno, Instituciones Educativas y Organizaciones sin fines de lucro en México, apoyándolos en su camino a la innovación y adopción tecnológica.
Manuel Cuellar es Arquitecto de Soluciones para Amazon Web Services en Sector Público. Manuel colabora con Dependencias de Gobierno, Instituciones Educativas y Organizaciones sin fines de lucro en el territorio de CentroAmérica y Caribe, apoyándolos en su camino a la innovación y adopción