Appearance
AWS CDK - Cloud Developer Kit
En la plataforma de AWS (Amazon WebServices) es posible definir la infraesctructura usando código con un lenguaje de marcado como YAML, lo que se conoce como Infraestructura como Código (IaC - Infraestructure As Code). El componente tecnológico que permite esto se denomina CloudFormation. Es decir, con un archivo de estructura YAML se especifica un conjunto de servicios y como se aprovisionan en la plataforma de AWS de modo que puede ser replicable.
Luego, encontramos que también es posible usar un lenguaje de programación reconocido (tales como Javascript, Python, Java, C#, Go) para implementar IaC con un componente tecnológico que se denomina Cloud Developer Kit (CDK). Esto nos ofrece el uso de control de flujo con el lenguaje de programación y otras características para tener mayor control al definir nuestra IaC.
Como prerrequisitos de debe contar con un entorno Node.js instalado previamente, así como también contar con una cuenta configurada y la CLI (Command Line Interface) de AWS. A continuación veremos unos apuntes ágiles para iniciar con CDK.
Instalación de CDK
bash
npm install -g aws-cdkPuede comprobarse la instalación con el comando
npx cdk --version
Proyecto de inicio rápido
Para iniciar nuestro proyecto, nos ubicamos en una carpeta que se use como espacio de trabajo de proyectos y creamos nuestra subcarpeta para el proyecto. Luego inicializamos el proyecto, es decir, ejecutamos lo siguiente:
bash
mkdir cdk
cdk init app --language typescriptEn algunos casos puede ser necesario anteponer
npxal comandocdk
A continuación estableceremos un Construct, que es un componente de servicio base para crear recursos. En nuestro ejercicio incluiremos DynamoDB para crear una tabla, por lo que ejecutamos lo siguiente:
bash
npm install @aws-cdk/aws-dynamodbNos dirigimos a nuestro proyecto para modificar el archivo lib/cdk-stack.ts, de modo que quede con el siguiente contenido:
typescript
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
export class CdkStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new dynamodb.Table(this, "user", {
partitionKey: {
name: "userId",
type: dynamodb.AttributeType.STRING
},
sortKey: {
name: "email",
type: dynamodb.AttributeType.STRING
}
});
}
}Mediante el uso de
dynamodb.Tablese define nuestra tabla
CDK genera código de CloudFormation, así que para ver el resultado ejecutamos:
bash
cdk synthEn algunos casos puede ser necesario anteponer
npxal comandocdk
Procedemos a establecer o asociar la cuenta de AWS que usaremos con CDK ejecutando un comando como el siguiente:
bash
cdk bootstrap aws://000000000000/us-east-1dónde
000000000000se refiere al número asignado a nuestra cuenta yus-east-1a la región (la cual puede variar según corresponda).
es posible consultar la identidad de nuestra cuenta con el comando:aws sts get-caller-identity
Finalmente, para desplegar nuestra IaC ejecutamos:
bash
cdk deploy
cdk destroyelimina lo que desplegamos
Alternativa usando LocalStack con CDK
LocalStack provee un entorno local y simulado de AWS. Si se tiene LocalStack debidamente instalado y corriendo, es posible incorporar el uso del módulo cdklocal, el cual se instala ejecutando:
bash
npm install -g aws-cdk-localDebe tenerse instalado
aws-cdkcomo hicimos desde el principio.
En lugar de los comandos antes vistos, podríamos ejecutar entonces:
bash
npx cdklocal synth
npx cdk bootstrap
npx cdklocal deploy
npx cdklocal destroyCompletando nuestro ejercicio con una Lambda
Para acceder a la base de datos usaremos una Lambda, por lo que ejecutamos lo siguiente:
bash
npm install @aws-cdk/aws-lambdaEl código de ejemplo a continuación sustituye el contenido anterior, siendo actualizado así:
typescript
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import { Runtime, FunctionUrlAuthType } from 'aws-cdk-lib/aws-lambda';
import * as lambda from 'aws-cdk-lib/aws-lambda-nodejs';
import * as path from 'path';
export class CdkStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// dynamo
const table = new dynamodb.Table(this, "user", {
partitionKey: {
name: "userId",
type: dynamodb.AttributeType.STRING
},
sortKey: {
name: "email",
type: dynamodb.AttributeType.STRING
}
});
// lambda
const handler = new lambda.NodejsFunction(this, "userHandler", {
runtime: Runtime.NODEJS_18_X,
entry: path.join(__dirname, `/../run/lambda.ts`),
handler: "handler",
environment: {
USER_TABLE_NAME: table.tableName,
},
});
// prvileges
table.grantReadWriteData(handler);
const userUrl = handler.addFunctionUrl({
authType: FunctionUrlAuthType.NONE,
cors: {
allowedOrigins: ['*'],
}
});
new cdk.CfnOutput(this, 'userUrl', {
value: userUrl.url,
});
}
}Nótese que se hace referencia a una lambda en el archivo
run/lambda.ts(el cual contiene el código de la función y deberá implementarse)