Creación de recursos de Amazon ECS con AWS CDK - Amazon Elastic Container Service

Creación de recursos de Amazon ECS con AWS CDK

AWS Cloud Development Kit (AWS CDK) es un marco de infraestructura como código (IAC) que le permite definir la infraestructura de nube de AWS mediante un lenguaje de programación de su elección. Para definir su propia infraestructura de nube, primero escriba una aplicación (en uno de los lenguajes compatibles con CDK) que contenga una o más pilas. Luego, sintetícela en una plantilla de AWS CloudFormation e implemente sus recursos en suCuenta de AWS. Siga los pasos de este tema para implementar un servidor web en contenedores con Amazon Elastic Container Service (Amazon ECS) y el AWS CDK en Fargate.

La biblioteca de construcción de AWS, incluida con el CDK, ofrece módulos que puede usar para modelar los recursos proporcionados por Servicios de AWS. Para los servicios más populares, la biblioteca proporciona construcciones seleccionadas con valores predeterminados inteligentes y prácticas recomendadas. Uno de estos módulos, aws-ecs-patterns en particular, proporciona abstracciones de alto nivel que le permiten definir su servicio en contenedores y todos los recursos de soporte necesarios en solo unas pocas líneas de código.

Este tema emplea la construcción ApplicationLoadBalancedFargateService. Esta construcción implementa un servicio Amazon ECS en Fargate detrás de un equilibrador de carga de aplicación. El módulo aws-ecs-patterns también incluye construcciones que usan un equilibrador de carga de red y se ejecutan en Amazon EC2.

Antes de comenzar esta tarea, configure su entorno de desarrollo AWS CDK y ejecute el comando siguiente para instalar el AWS CDK. Para obtener instrucciones sobre cómo configurar su entorno de desarrollo AWS CDK, consulte Getting Started With the AWS CDK - Prerequisites (Primeros pasos con CDK: requisitos previos).

npm install -g aws-cdk
nota

En estas instrucciones, se presupone que está utilizando AWS CDK v2.

Paso 1: Configuración del proyecto AWS CDK

Cree un directorio para la nueva aplicación AWS CDK e inicialice el proyecto.

TypeScript
mkdir hello-ecs cd hello-ecs cdk init --language typescript
JavaScript
mkdir hello-ecs cd hello-ecs cdk init --language javascript
Python
mkdir hello-ecs cd hello-ecs cdk init --language python

Después de inicializar el proyecto, active el entorno virtual del proyecto e instale las dependencias de referencia de AWS CDK.

source .venv/bin/activate python -m pip install -r requirements.txt
Java
mkdir hello-ecs cd hello-ecs cdk init --language java

Importe este proyecto de Maven a su IDE de Java. Por ejemplo, en Eclipse, use Archivo > Importar > Maven > Proyectos de Maven existentes.

C#
mkdir hello-ecs cd hello-ecs cdk init --language csharp
Go
mkdir hello-ecs cd hello-ecs cdk init --language go
nota

La plantilla de la aplicación AWS CDK utiliza el nombre del directorio del proyecto para generar nombres para los archivos y las clases fuente. En este ejemplo, el directorio se llama hello-ecs. Si usa otro nombre de directorio de proyecto, la aplicación no coincidirá con estas instrucciones.

AWS CDK v2 incluye construcciones estables para todos los Servicios de AWS en un solo paquete denominado aws-cdk-lib. Este paquete se instala como dependencia cuando inicializa el proyecto. Al trabajar con ciertos lenguajes de programación, el paquete se instala al crear el proyecto por primera vez. Este tema abarca cómo usar una construcción Amazon ECS Patterns, la cual proporciona abstracciones de alto nivel para trabajar con Amazon ECS. Este módulo se basa en construcciones de Amazon ECS y en otras para aprovisionar los recursos necesarios para su aplicación Amazon ECS.

Los nombres que usa para importar estas bibliotecas a su aplicación CDK pueden diferir ligeramente según el lenguaje de programación que use. Como referencia, estos son los nombres usados en cada lenguaje de programación CDK compatible.

TypeScript
aws-cdk-lib/aws-ecs aws-cdk-lib/aws-ecs-patterns
JavaScript
aws-cdk-lib/aws-ecs aws-cdk-lib/aws-ecs-patterns
Python
aws_cdk.aws_ecs aws_cdk.aws_ecs_patterns
Java
software.amazon.awscdk.services.ecs software.amazon.awscdk.services.ecs.patterns
C#
Amazon.CDK.AWS.ECS Amazon.CDK.AWS.ECS.Patterns
Go
github.com/aws/aws-cdk-go/awscdk/v2/awsecs github.com/aws/aws-cdk-go/awscdk/v2/awsecspatterns

Paso 2: usar el AWS CDK para definir un servidor web en contenedores en Fargate

Usaremos la imagen del contenedor amazon-ecs-sample de DockerHub. Esta imagen contiene una aplicación web PHP que se ejecuta en Amazon Linux 2.

En el proyecto AWS CDK que ha creado, edite el archivo que contiene la definición de pila para que se parezca a uno de los siguientes ejemplos.

nota

Una pila es una unidad de implementación. Todos los recursos deben estar en una pila y todos los recursos que están en una pila se implementan al mismo tiempo. Si un recurso no se puede implementar, se restaurarán todos los otros recursos ya implementados. Una aplicación AWS CDK puede contener varias pilas y los recursos de una pila pueden hacer referencia a los recursos de otra.

TypeScript

Actualice lib/hello-ecs-stack.ts para que se parezca a lo siguiente.

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as ecs from 'aws-cdk-lib/aws-ecs'; import * as ecsp from 'aws-cdk-lib/aws-ecs-patterns'; export class HelloEcsStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); new ecsp.ApplicationLoadBalancedFargateService(this, 'MyWebServer', { taskImageOptions: { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), }, publicLoadBalancer: true }); } }
JavaScript

Actualice lib/hello-ecs-stack.js para que se parezca a lo siguiente.

const cdk = require('aws-cdk-lib'); const { Construct } = require('constructs'); const ecs = require('aws-cdk-lib/aws-ecs'); const ecsp = require('aws-cdk-lib/aws-ecs-patterns'); class HelloEcsStack extends cdk.Stack { constructor(scope = Construct, id = string, props = cdk.StackProps) { super(scope, id, props); new ecsp.ApplicationLoadBalancedFargateService(this, 'MyWebServer', { taskImageOptions: { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), }, publicLoadBalancer: true }); } } module.exports = { HelloEcsStack }
Python

Actualice hello-ecs/hello_ecs_stack.py para que se parezca a lo siguiente.

import aws_cdk as cdk from constructs import Construct import aws_cdk.aws_ecs as ecs import aws_cdk.aws_ecs_patterns as ecsp class HelloEcsStack(cdk.Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) ecsp.ApplicationLoadBalancedFargateService(self, "MyWebServer", task_image_options=ecsp.ApplicationLoadBalancedTaskImageOptions( image=ecs.ContainerImage.from_registry("amazon/amazon-ecs-sample")), public_load_balancer=True )
Java

Actualice src/main/java/com.myorg/HelloEcsStack.java para que se parezca a lo siguiente.

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.services.ecs.ContainerImage; import software.amazon.awscdk.services.ecs.patterns.ApplicationLoadBalancedFargateService; import software.amazon.awscdk.services.ecs.patterns.ApplicationLoadBalancedTaskImageOptions; public class HelloEcsStack extends Stack { public HelloEcsStack(final Construct scope, final String id) { this(scope, id, null); } public HelloEcsStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); ApplicationLoadBalancedFargateService.Builder.create(this, "MyWebServer") .taskImageOptions(ApplicationLoadBalancedTaskImageOptions.builder() .image(ContainerImage.fromRegistry("amazon/amazon-ecs-sample")) .build()) .publicLoadBalancer(true) .build(); } }
C#

Actualice src/HelloEcs/HelloEcsStack.cs para que se parezca a lo siguiente.

using Amazon.CDK; using Constructs; using Amazon.CDK.AWS.ECS; using Amazon.CDK.AWS.ECS.Patterns; namespace HelloEcs { public class HelloEcsStack : Stack { internal HelloEcsStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { new ApplicationLoadBalancedFargateService(this, "MyWebServer", new ApplicationLoadBalancedFargateServiceProps { TaskImageOptions = new ApplicationLoadBalancedTaskImageOptions { Image = ContainerImage.FromRegistry("amazon/amazon-ecs-sample") }, PublicLoadBalancer = true }); } } }
Go

Actualice hello-ecs.go para que se parezca a lo siguiente.

package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" // "github.com/aws/aws-cdk-go/awscdk/v2/awssqs" "github.com/aws/aws-cdk-go/awscdk/v2/awsecs" "github.com/aws/aws-cdk-go/awscdk/v2/awsecspatterns" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) type HelloEcsStackProps struct { awscdk.StackProps } func NewHelloEcsStack(scope constructs.Construct, id string, props *HelloEcsStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // The code that defines your stack goes here // example resource // queue := awssqs.NewQueue(stack, jsii.String("HelloEcsQueue"), &awssqs.QueueProps{ // VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)), // }) res := awsecspatterns.NewApplicationLoadBalancedFargateService(stack, jsii.String("MyWebServer"), &awsecspatterns.ApplicationLoadBalancedFargateServiceProps{ TaskImageOptions: &awsecspatterns.ApplicationLoadBalancedTaskImageOptions{ Image: awsecs.ContainerImage_FromRegistry(jsii.String("amazon/amazon-ecs-sample"), &awsecs.RepositoryImageProps{}), }, }, ) awscdk.NewCfnOutput(stack, jsii.String("LoadBalancerDNS"), &awscdk.CfnOutputProps{Value: res.LoadBalancer().LoadBalancerDnsName()}) return stack } func main() { defer jsii.Close() app := awscdk.NewApp(nil) NewHelloEcsStack(app, "HelloEcsStack", &HelloEcsStackProps{ awscdk.StackProps{ Env: env(), }, }) app.Synth(nil) } // env determines the AWS environment (account+region) in which our stack is to // be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html func env() *awscdk.Environment { // If unspecified, this stack will be "environment-agnostic". // Account/Region-dependent features and context lookups will not work, but a // single synthesized template can be deployed anywhere. //--------------------------------------------------------------------------- return nil // Uncomment if you know exactly what account and region you want to deploy // the stack to. This is the recommendation for production stacks. //--------------------------------------------------------------------------- // return &awscdk.Environment{ // Account: jsii.String("123456789012"), // Region: jsii.String("us-east-1"), // } // Uncomment to specialize this stack for the AWS Account and Region that are // implied by the current CLI configuration. This is recommended for dev // stacks. //--------------------------------------------------------------------------- // return &awscdk.Environment{ // Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")), // Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")), // } }

El fragmento breve anterior incluye lo siguiente:

  • El nombre lógico del servicio: MyWebServer.

  • La imagen del contenedor obtenida de DockerHub: amazon/amazon-ecs-sample.

  • Otra información relevante, como el hecho de que el equilibrador de carga tiene una dirección pública y se puede acceder a él desde Internet.

La AWS CDK creará todos los recursos necesarios para implementar el servidor web, incluidos los siguientes recursos. Estos recursos se omitieron en este ejemplo.

  • Clúster de Amazon ECS

  • Instancias de Amazon VPC y Amazon EC2

  • Grupo de escalado automático

  • Equilibrador de carga de aplicación

  • Roles y políticas de IAM

Algunos recursos aprovisionados automáticamente se compartirán con todos los servicios de Amazon ECS definidos en la pila.

Guarde el archivo fuente y a continuación ejecute el comando cdk synth en el directorio principal de la aplicación. El AWS CDK ejecuta la aplicación, sintetiza una plantilla de AWS CloudFormation a partir de ella y luego muestra la plantilla. La plantilla es un archivo YAML de aproximadamente 600 líneas. Aquí se muestra el principio del archivo. Su plantilla puede diferir de este ejemplo.

Resources: MyWebServerLB3B5FD3AB: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: LoadBalancerAttributes: - Key: deletion_protection.enabled Value: "false" Scheme: internet-facing SecurityGroups: - Fn::GetAtt: - MyWebServerLBSecurityGroup01B285AA - GroupId Subnets: - Ref: EcsDefaultClusterMnL3mNNYNVpcPublicSubnet1Subnet3C273B99 - Ref: EcsDefaultClusterMnL3mNNYNVpcPublicSubnet2Subnet95FF715A Type: application DependsOn: - EcsDefaultClusterMnL3mNNYNVpcPublicSubnet1DefaultRouteFF4E2178 - EcsDefaultClusterMnL3mNNYNVpcPublicSubnet2DefaultRouteB1375520 Metadata: aws:cdk:path: HelloEcsStack/MyWebServer/LB/Resource MyWebServerLBSecurityGroup01B285AA: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Automatically created Security Group for ELB HelloEcsStackMyWebServerLB06757F57 SecurityGroupIngress: - CidrIp: 0.0.0.0/0 Description: Allow from anyone on port 80 FromPort: 80 IpProtocol: tcp ToPort: 80 VpcId: Ref: EcsDefaultClusterMnL3mNNYNVpc7788A521 Metadata: aws:cdk:path: HelloEcsStack/MyWebServer/LB/SecurityGroup/Resource # and so on for another few hundred lines

Para implementar el servicio en su Cuenta de AWS, ejecute el comando cdk deploy en el directorio principal de la aplicación. Se le pedirá que apruebe las políticas de IAM que ha generado el AWS CDK.

La implementación lleva varios minutos, durante los cuales el AWS CDK crea varios recursos. Las últimas líneas del resultado de la implementación incluyen el nombre de host público del equilibrador de carga y la dirección URL de su nuevo servidor web. Son los siguientes:

Outputs: HelloEcsStack.MyWebServerLoadBalancerDNSXXXXXXX = Hello-MyWeb-ZZZZZZZZZZZZZ-ZZZZZZZZZZ.us-west-2.elb.amazonaws.com HelloEcsStack.MyWebServerServiceURLYYYYYYYY = http://Hello-MyWeb-ZZZZZZZZZZZZZ-ZZZZZZZZZZ.us-west-2.elb.amazonaws.com

Paso 3: probar el servidor web

Copie la dirección URL del resultado de la implementación y péguela en el navegador web. Se muestra el siguiente mensaje de bienvenida del servidor web.

Captura de pantalla de la aplicación de ejemplo de Amazon ECS. La salida indica que "Your application is now running on Amazon ECS" (Su aplicación se ejecuta ahora en Amazon ECS).

Paso 4: Limpiar

Cuando haya terminado con el servidor web, finalice el servicio mediante la CDK. Para ello, ejecute el comando cdk destroy en el directorio principal de la aplicación. Esto evita que incurra en cargos imprevistos en el futuro.

Siguientes pasos

Para obtener más información sobre cómo desarrollar la infraestructura de AWS mediante AWS CDK, consulte la Guía para desarrolladores de AWS CDK.

Para obtener información sobre cómo escribir aplicaciones de AWS CDK en el lenguaje de su elección, consulte:

TypeScript

Utilización del AWS CDK en TypeScript

JavaScript

Utilización del AWS CDK en JavaScript

Python

Utilización del AWS CDK en Python

Java

Utilización del AWS CDK en Java

C#

Utilización del AWS CDK en C#

Go

Uso del AWS CDK en Go

Para obtener más información sobre los módulos de la biblioteca de construcción de AWS que se usan en este tema, consulte la siguiente información general de la Referencia de la API de AWS CDK.