Implementar una aplicación web en Amazon EC2

GUÍA DE INTRODUCCIÓN

Módulo 1: Crear la infraestructura

En este módulo creará una pila de AWS CDK, un grupo de seguridad con acceso de entrada y un perfil de instancias IAM.

Introducción

Para poder implementar la aplicación web, debemos crear una instancia de Amazon EC2 y los recursos necesarios. En este módulo, crearemos la nueva aplicación de AWS CDK, instalaremos las dependencias de los recursos y, por último, definiremos una instancia de Amazon EC2, un grupo de seguridad con acceso de entrada y un perfil de instancias IAM. También crearemos, con la ayuda de CDK, un par de claves que se utilizarán para acceder a la instancia.

Lo que aprenderá

  • Crear una nueva aplicación de AWS CDK
  • Instalar las dependencias de los recursos necesarios
  • Definir los recursos en la aplicación de CDK

 Tiempo de realización

10 minutos

 Requisitos previos del módulo

  • Una cuenta de AWS con acceso de administrador**
  • Navegador recomendado: la última versión de Chrome o Firefox

[**] Es posible que las cuentas creadas en las últimas 24 horas aún no tengan acceso a los servicios necesarios para este tutorial.

Implementación

Crear la aplicación de CDK

En primer lugar, asegúrese de que tiene CDK instalado. Si no lo tiene instalado, siga la guía Introducción a AWS CDK:

cdk --verison

A continuación crearemos la aplicación de CDK de esqueleto utilizando TypeScript como lenguaje:

mkdir ec2-cdk
cd ec2-cdk
cdk init app --language typescript

De este modo obtendremos lo siguiente:

Applying project template app for typescript
# Welcome to your CDK TypeScript project!

This is a blank project for TypeScript development with CDK.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## Useful commands

 * `npm run build`   compile typescript to js
 * `npm run watch`   watch for changes and compile
 * `npm run test`    perform the jest unit tests
 * `cdk deploy`      deploy this stack to your default AWS account/region
 * `cdk diff`        compare deployed stack with current state
 * `cdk synth`       emits the synthesized CloudFormation template

Executing npm install...
✅ All done!

Si se muestra el siguiente mensaje, le recomendamos que actualice la versión de CDK utilizando el comando proporcionado y, a continuación, ejecutando npm update:

****************************************************
*** Newer version of CDK is available [1.122.0]  ***
*** Upgrade recommended (npm install -g aws-cdk) ***
****************************************************

# npm install -g aws-cdk
# npm update

Crear el código para la pila de recursos

Vaya al archivo /lib/cdk-ecs-infra-stack.ts; allí escribirá el código para la pila de recursos que va a crear.

Una pila de recursos es un conjunto de recursos de infraestructura de la nube (en su caso particular, todos serán recursos de AWS), los cuales se aprovisionarán a una cuenta específica. La cuenta/región donde se aprovisionan estos recursos se puede configurar en la pila.

En esta pila de recursos va a crear los siguientes recursos:

  • Rol de IAM: este rol se asignará a la instancia EC2 para permitirle llamar a otros servicios de AWS.
  • Instancia EC2: la máquina virtual que utilizará para alojar la aplicación web.
  • Grupo de seguridad: el firewall virtual para permitir solicitudes entrantes a su aplicación web.
  • Par de llaves SSH de EC2: un conjunto de credenciales que puede utilizar para SSH en la instancia para ejecutar comandos durante la configuración.

Crear la instancia EC2

Para empezar a crear la instancia EC2 y otros recursos, primero debe importar los módulos correctos:

npm i @aws-cdk/aws-ec2 @aws-cdk/aws-iam @aws-cdk/aws-s3-assets cdk-ec2-key-pair

A continuación, editará el archivo lib/cdk-eb-infra-stack.ts para añadir la dependencia en la parte superior del archivo, debajo de la importación existente de @aws-cdk/core:

import * as ec2 from "@aws-cdk/aws-ec2";            // Allows working with EC2 and VPC resources
import * as iam from "@aws-cdk/aws-iam";            // Allows working with IAM resources
import * as s3assets from "@aws-cdk/aws-s3-assets"; // Allows managing files with S3
import * as keypair from "cdk-ec2-key-pair";        // Helper to create EC2 SSH keypairs
import * as path from "path";                       // Helper for working with file paths

Estos módulos proporcionan acceso a todos los componentes necesarios para implementar la aplicación web. El primer paso es localizar la VPC predeterminada existente en su cuenta añadiendo el siguiente código debajo de la línea // The code that defines your stack goes here:

// The code that defines your stack goes here
      
      // Look up the default VPC
      const vpc = ec2.Vpc.fromLookup(this, "VPC", {
        isDefault: true
      });

Utilizando el paquete cdk-ec2-key-pair, creará un par de claves SSH y las almacenará en AWS Secrets Manager.

 // Create a key pair to be used with this EC2 Instance
    const key = new keypair.KeyPair(this, "KeyPair", {
      name: "cdk-keypair",
      description: "Key Pair created with CDK Deployment",
    });
    key.grantReadOnPublicKey; 

A continuación, debe crear un grupo de seguridad, permitiendo el acceso SSH y HTTP desde cualquier lugar añadiendo 2 reglas. Tenga en cuenta que el acceso SSH desde cualquier lugar es aceptable por un corto tiempo en un entorno de prueba, pero no es seguro para entornos de producción. También creará un rol de IAM para que la instancia EC2 le permita llamar a otros servicios de AWS y adjuntar la política preincorporada para leer configuraciones de AWS Secrets Manager (donde se almacenará la clave pública SSH):

// Security group for the EC2 instance
    const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", {
      vpc,
      description: "Allow SSH (TCP port 22) and HTTP (TCP port 80) in",
      allowAllOutbound: true,
    });

    // Allow SSH access on port tcp/22
    securityGroup.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(22),
      "Allow SSH Access"
    );

    // Allow HTTP access on port tcp/80
    securityGroup.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(80),
      "Allow HTTP Access"
    );

    // IAM role to allow access to other AWS services
    const role = new iam.Role(this, "ec2Role", {
      assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"),
    });

    // IAM policy attachment to allow access to 
    role.addManagedPolicy(
      iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore")
    );

Ya está todo listo para crear la instancia EC2 mediante el uso de una Amazon Machine Image (AMI) preincorporada; en esta guía utilizará la de Amazon Linux 2 para arquitectura de CPU X86_64. También pasará el rol de IAM que ha creado, el VPC predeterminado y el tipo de instancia en la que se ejecutará (en su caso, un t2.micro que tiene 1 vCPU y 1 GB de memoria). Puede ver los diferentes tipos de instancias que están disponibles aquí.

// Look up the AMI Id for the Amazon Linux 2 Image with CPU Type X86_64
    const ami = new ec2.AmazonLinuxImage({
      generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
      cpuType: ec2.AmazonLinuxCpuType.X86_64,
    });
// Create the EC2 instance using the Security Group, AMI, and KeyPair defined.
    const ec2Instance = new ec2.Instance(this, "Instance", {
      vpc,
      instanceType: ec2.InstanceType.of(
        ec2.InstanceClass.T2,
        ec2.InstanceSize.MICRO
      ),
      machineImage: ami,
      securityGroup: securityGroup,
      keyName: key.keyPairName,
      role: role,
    });

Ya ha definido la pila de AWS CDK para crear una instancia de Amazon EC2, un grupo de seguridad con acceso de entrada y un perfil de instancias IAM. Antes de implementar la pila, debe instalar aún los paquetes en el SO anfitrión para ejecutar la aplicación y también copiar el código de la aplicación en la instancia. 

El archivo ec2-cdk-stack.ts ahora debería tener el siguiente aspecto:

import * as cdk from '@aws-cdk/core';
import * as ec2 from "@aws-cdk/aws-ec2"; // Allows working with EC2 and VPC resources
import * as iam from "@aws-cdk/aws-iam"; // Allows working with IAM resources
import * as s3assets from "@aws-cdk/aws-s3-assets"; // Allows managing files with S3
import * as keypair from "cdk-ec2-key-pair"; // Helper to create EC2 SSH keypairs
import * as path from "path"; // Helper for working with file paths

export class Ec2CdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here
          
    // Look up the default VPC
    const vpc = ec2.Vpc.fromLookup(this, "VPC", {
      isDefault: true
    });

    // Create a key pair to be used with this EC2 Instance
    const key = new keypair.KeyPair(this, "KeyPair", {
      name: "cdk-keypair",
      description: "Key Pair created with CDK Deployment",
    });
    key.grantReadOnPublicKey; 

    // Security group for the EC2 instance
    const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", {
      vpc,
      description: "Allow SSH (TCP port 22) and HTTP (TCP port 80) in",
      allowAllOutbound: true,
    });

    // Allow SSH access on port tcp/22
    securityGroup.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(22),
      "Allow SSH Access"
    );

    // Allow HTTP access on port tcp/80
    securityGroup.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(80),
      "Allow HTTP Access"
    );

    // IAM role to allow access to other AWS services
    const role = new iam.Role(this, "ec2Role", {
      assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"),
    });

    // IAM policy attachment to allow access to 
    role.addManagedPolicy(
      iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore")
    );

    // Look up the AMI Id for the Amazon Linux 2 Image with CPU Type X86_64
    const ami = new ec2.AmazonLinuxImage({
      generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
      cpuType: ec2.AmazonLinuxCpuType.X86_64,
    });

    // Create the EC2 instance using the Security Group, AMI, and KeyPair defined.
    const ec2Instance = new ec2.Instance(this, "Instance", {
      vpc,
      instanceType: ec2.InstanceType.of(
        ec2.InstanceClass.T2,
        ec2.InstanceSize.MICRO
      ),
      machineImage: ami,
      securityGroup: securityGroup,
      keyName: key.keyPairName,
      role: role,
    });
  }
}

Conclusión

En este módulo aprendió a crear una aplicación de CDK para crear toda la infraestructura necesaria para implementar su aplicación web en una instancia EC2. En el siguiente módulo aprenderá a configurar la instancia EC2 durante el arranque instalando todos los paquetes de SO, configurándolos e implementando el código en la instancia.

Siguiente: Configuración automática

Háganos saber su opinión.