在 Amazon EC2 上部署 Web 应用程序

入门指南

模块 1:创建您的基础设施

在此模块中,您将创建一个 AWS CDK 堆栈、一个具有入站访问权限的安全组和一个 IAM 实例配置文件。

简介

在我们部署 Web 应用程序之前,我们需要创建 Amazon EC2 实例和支持资源。在本模块中,我们将创建新的 AWS CDK 应用程序、安装资源的依赖项,并最终定义 Amazon EC2 实例、具有入站访问权限的安全组和 IAM 实例配置文件。我们还将在 CDK 的帮助下创建用于访问实例的密钥对。

您将学到的内容

  • 创建新的 AWS CDK 应用程序
  • 安装所需资源的依赖项
  • 在 CDK 应用程序中定义资源

 完成时间

10 分钟

 模块先决条件

  • 具有管理员级访问权限的 AWS 账户**
  • 推荐的浏览器:最新版 Chrome 或 Firefox

[**] 过去 24 小时内创建的账户可能尚不具有访问此教程所需服务的权限。

实施

创建 CDK 应用程序

首先,确保您已安装 CDK。如果您没有安装该应用程序,请遵照 AWS CDK 入门指南操作:

cdk --verison

现在,我们将 TypeScript 用作我们选择的语言,创建框架 CDK 应用程序:

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

这将输出以下内容:

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!

如果您看到以下消息,我们建议您使用提供的命令,然后运行 npm update 以升级 CDK 版本:

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

# npm install -g aws-cdk
# npm update

为资源堆栈创建代码

前往文件 /lib/cdk-ecs-infra-stack.ts,您将在该文件中为您即将创建的资源堆栈编写代码。

资源堆栈是一组云基础设施资源(在特定情况下,它们将为所有的 AWS 资源),将预置到特定账户中。这些资源预置所在的账户/地区可以在堆栈中配置。

在此资源堆栈中,您将创建以下资源:

  • IAM 角色:此角色将被分配至 EC2 实例,以允许它调用其他 AWS 服务。
  • EC2 实例:您将用于托管您的 Web 应用程序的虚拟机。
  • 安全组:允许对您的 Web 应用程序进行入站请求的虚拟防火墙。
  • EC2 SSH 密钥对:您可以用于通过 SSH 连接到实例以执行命令来设置所有内容的一组凭证。

创建 EC2 实例

要开始创建 EC2 实例和其他资源,您首选需要导入正确的模块:

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

然后,您将编辑 lib/cdk-eb-infra-stack.ts 文件以将依赖项添加到 @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

这些模块为您提供了对您部署 Web 应用程序所需的所有组件的访问权限。第一步是通过在行 // The code that defines your stack goes here(定义您的堆栈的代码在此)下添加代码来在您的账户中查找现有的默认 VPC:

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

使用 cdk-ec2-key-pair 软件包,您将创建一个 SSH 密钥对并将其存储在 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; 

您现在需要创建一个安全组,以通过添加 2 个规则允许从任何地方进行 SSH 和 HTTP 访问。请注意,在测试环境中,从任何地方进行 SSH 访问在短时间内都是可以接受的,但是它对于生产环境来说不安全。您还将为 EC2 实例创建一个 IAM 角色,以允许它调用其他 AWS 服务,并附加预构建的策略从 AWS Secrets Manager(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")
    );

您现在已准备好使用预构建的 Amazon Machine Image (AMI) 创建 EC2 实例,在此指南中,您会将 Amazon Linux 2 One 用于 X86_64 CPU 架构。您还会传递您创建的 IAM 角色、默认 VPC 和在其上运行的实例类型,在您的案例中,为具有 1 vCPU 和 1GB 内存的 t2.micro——您可以在此查看提供的所有不同的实例类型。

// 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,
    });

您现在已定义 AWS CDK 堆栈来创建 Amazon EC2 实例、具有入站访问权限的安全组以及 IAM 实例配置文件。在部署堆栈之前,您仍然需要在主机 OS 上安装软件包来运行应用程序,并且还需要复制应用程序代码到实例中。 

您 ec2-cdk-stack.ts 文件现在应如下所示:

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,
    });
  }
}

结论

在此模块中,您学习了如何创建 CDK 应用程序,以创建在 EC2 实例上部署您的 Web 应用程序所需的所有基础设施。在下一个模块中,您将了解如何通过安装所有的操作系统软件包、配置它们并将您的代码部署到实例上来在 EC2 实例启动时配置该实例。

下一步:自动配置

请就我们的表现提供反馈。