在 Amazon EC2 上部署应用程序 - Amazon CloudFormation
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

在 Amazon EC2 上部署应用程序

您可以使用 CloudFormation 在 Amazon EC2 实例上自动安装、配置和启动应用程序。这样能让您轻松复制部署和更新现有安装而无需直接连接到该实例,从而为您节省大量时间和工作量。

CloudFormation 包括一组基于 cloud-init 的帮助程序脚本(cfn-initcfn-signalcfn-get-metadatacfn-hup)。您可从 CloudFormation 模板中调用这些帮助程序脚本来在使用相同模板的 Amazon EC2 实例上安装、配置和更新应用程序。有关更多信息,请参阅《Amazon CloudFormation 模板参考指南》中的 CloudFormation 帮助程序脚本参考

入门教程中,您使用 UserData 和基础 bash 脚本创建了一个简单的 Web 服务器。虽然顺利创建了“Hello World”这样的简单页面,但实际应用程序通常需要更复杂的配置,包括:

  • 按照正确的顺序安装多个软件包。

  • 使用特定内容创建复杂的配置文件。

  • 启动服务并将其配置为自动运行。

  • 错误处理和验证设置过程。

UserData 中的基础 bash 脚本相比,CloudFormation 的帮助程序脚本提供了一种更稳健、更易于维护的方式来配置 EC2 实例。cfn-init 帮助程序脚本可以从模板的元数据中读取配置数据,并将其系统地应用于您的实例。

在本教程中,您将学习如何使用 cfn-init 帮助程序脚本以及如何监控引导过程。

注意

CloudFormation 使用免费,但您需要为自己创建的 Amazon EC2 资源付费。如果您不熟悉 Amazon,可以利用免费套餐来最大限度地降低或避免在学习过程产生费用。

先决条件

  • 您必须已完成 创建第一个堆栈 教程或具有 CloudFormation 基础知识的同等经验。

  • 您必须具有对 Amazon Web Services 账户的访问权限,且该账户需要拥有有权使用 Amazon EC2 和 CloudFormation 的 IAM 用户或角色,或者拥有管理用户访问权限。

  • 必须拥有可访问互联网的虚拟私有云(VPC)。本教程模板需要默认 VPC,新版本 Amazon Web Services 账户自动附带该默认 VPC。如果您没有默认 VPC,或者已将其删除,请参阅“创建第一个堆栈”教程中的疑难解答部分,了解其他解决方案。

了解引导的概念

在创建模板之前,我们先了解一下有助于引导顺利完成的关键概念。

cfn-init 帮助程序脚本

CloudFormation 提供 Python 帮助程序脚本,可用于在 Amazon EC2 实例中安装软件和启动服务。cfn-init 脚本可以从模板的元数据中读取配置数据,并将其应用于实例。

过程如下所述:

  1. 在 EC2 资源的 Metadata 部分中定义配置。

  2. UserData 脚本中调用 cfn-init

  3. cfn-init 读取元数据并应用配置。

  4. 根据规范配置实例。

元数据结构

该配置是在 EC2 实例中的特定结构中进行定义。

Resources: EC2Instance: Type: AWS::EC2::Instance Metadata: # Metadata section for the resource AWS::CloudFormation::Init: # Required key that cfn-init looks for config: # Configuration name (you can have multiple) packages: # Install packages files: # Create files commands: # Run commands services: # Start/stop services

cfn-init 脚本将以特定顺序处理这些部分:packages、groups、users、sources、files、commands,然后是 services。

从简单的引导示例开始

我们先从最简单的引导示例开始,该示例仅安装和启动 Apache。

Resources: EC2Instance: Type: AWS::EC2::Instance Metadata: AWS::CloudFormation::Init: config: packages: # Install Apache web server yum: httpd: [] services: # Start Apache and enable it to start on boot sysvinit: httpd: enabled: true ensureRunning: true Properties: ImageId: !Ref LatestAmiId InstanceType: !Ref InstanceType UserData: !Base64 # Script that runs when instance starts Fn::Sub: | #!/bin/bash yum install -y aws-cfn-bootstrap /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource EC2Instance --region ${AWS::Region}

这个简单的示例演示了核心概念:

  • packages 部分使用 yum 安装 httpd 软件包。这也适用于 Amazon Linux 和其他使用 yum 的 Linux 发行版。

  • services 部分用于确保 httpd 自动启动和运行。

  • UserData 会安装最新的引导工具并调用 cfn-init

添加文件和命令

现在,我们来改进示例,在 EC2 实例的 /var/log 目录中添加自定义网页和日志文件。

创建文件

files 部分可让您在实例上创建包含特定内容的文件。直竖线 (|) 允许您将文字文本块(HTML 代码)作为文件内容 (/var/www/html/index.html) 传递。

files: /var/www/html/index.html: content: | <body> <h1>Congratulations, you have successfully launched the AWS CloudFormation sample.</h1> </body>

运行命令

commands 部分可让您在引导过程中运行 shell 命令。此命令会在 EC2 实例的 /var/log/welcome.txt 位置创建日志文件。要查看该文件,您需要 Amazon EC2 密钥对以进行 SSH 访问,以及 IP 地址范围以便以 SSH 方式连接实例(此处未介绍)。

commands: createWelcomeLog: command: "echo 'cfn-init ran successfully!' > /var/log/welcome.txt"

增强网络安全

由于我们正在设置 Web 服务器,因此需要允许 Web 流量(HTTP)传输到 EC2 实例。为此,我们将创建一个安全组,以便来自您的 IP 地址的入站流量通过端口 80。EC2 实例还需要将流量发送到互联网,以便实现软件包更新安装等目的。默认情况下,安全组会允许所有出站流量。然后,我们使用 SecurityGroupIds 属性将此安全组与 EC2 实例关联。

WebServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow HTTP access from my IP address SecurityGroupIngress: - IpProtocol: tcp Description: HTTP FromPort: 80 ToPort: 80 CidrIp: !Ref MyIP

完整的引导模板

现在,我们把所有部分合在一起。这就是之前介绍的所有概念整合而成的完整模板。

AWSTemplateFormatVersion: 2010-09-09 Description: Bootstrap an EC2 instance with Apache web server using cfn-init Parameters: LatestAmiId: Description: The latest Amazon Linux 2 AMI from the Parameter Store Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>' Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2' InstanceType: Description: EC2 instance type Type: String Default: t2.micro AllowedValues: - t3.micro - t2.micro ConstraintDescription: must be a valid EC2 instance type. MyIP: Description: Your IP address in CIDR format (e.g. 203.0.113.1/32) Type: String MinLength: 9 MaxLength: 18 Default: 0.0.0.0/0 AllowedPattern: '^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$' ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Resources: WebServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow HTTP access from my IP address SecurityGroupIngress: - IpProtocol: tcp Description: HTTP FromPort: 80 ToPort: 80 CidrIp: !Ref MyIP WebServer: Type: AWS::EC2::Instance Metadata: AWS::CloudFormation::Init: config: packages: yum: httpd: [] files: /var/www/html/index.html: content: | <body> <h1>Congratulations, you have successfully launched the AWS CloudFormation sample.</h1> </body> commands: createWelcomeLog: command: "echo 'cfn-init ran successfully!' > /var/log/welcome.txt" services: sysvinit: httpd: enabled: true ensureRunning: true Properties: ImageId: !Ref LatestAmiId InstanceType: !Ref InstanceType SecurityGroupIds: - !Ref WebServerSecurityGroup UserData: !Base64 Fn::Sub: | #!/bin/bash yum install -y aws-cfn-bootstrap /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServer --region ${AWS::Region} Tags: - Key: Name Value: Bootstrap Tutorial Web Server Outputs: WebsiteURL: Value: !Sub 'http://${WebServer.PublicDnsName}' Description: EC2 instance public DNS name

使用控制台创建堆栈。

以下过程涉及从文件上传示例堆栈模板。在本地计算机上打开文本编辑器并添加模板。使用文件名 samplelinux2stack.template 保存该文件。

启动堆栈模板
  1. 登录到 Amazon Web Services Management Console 并打开 Amazon CloudFormation 控制台 https://console.aws.amazon.com/cloudformation

  2. 依次选择创建堆栈使用新资源(标准)

  3. 指定模板下,选择上传模板文件,然后选择选择文件,上传 samplelinux2stack.template 文件。

  4. 选择下一步

  5. 指定堆栈详细信息页面上,将堆栈命名为 BootstrapTutorialStack

  6. 参数下,执行以下操作。

    • LatestAmiId:保留默认值。

    • InstanceType:选择 t2.microt3.micro 作为 EC2 实例类型。

    • MyIP:输入带 /32 后缀的公有 IP 地址。

  7. 选择两次下一步,然后选择提交即可创建堆栈。

监控引导过程

引导过程比简单的 EC2 启动需要更长的时间,因为引导过程中需要安装和配置其他软件。

监控引导进度
  1. 在 CloudFormation 控制台中,选择堆栈并打开事件选项卡。

  2. 注意 WebServer CREATE_IN_PROGRESS 事件。引导过程在实例启动后开始。

  3. 引导过程通常需要花费几分钟的时间。完成时,您可以看到 WebServer CREATE_COMPLETE

如果想知道引导过程中发生了什么,可以查看实例日志。

查看引导日志(可选)
  1. 打开 EC2 控制台,找到您的实例。

  2. 选择实例,然后依次选择操作监控和故障排除获取系统日志,即可查看引导过程。

  3. 如果日志没有即刻出现,请稍等片刻,然后刷新页面。

测试引导的 Web 服务器

当堆栈显示 CREATE_COMPLETE 时,请测试 Web 服务器。

测试 Web 服务器
  1. 在 CloudFormation 控制台中,转到您堆栈的输出选项卡。

  2. 单击 WebsiteURL 值,在新选项卡中打开 Web 服务器。

  3. 您应看到自定义网页和消息 Congratulations, you have successfully launched the AWS CloudFormation sample

注意

如果页面没有立即加载,请稍等片刻,然后重试。即使堆栈已显示 CREATE_COMPLETE,引导过程可能仍在完成。

引导问题排查

如果引导过程失败或您的 Web 服务器无法运行,以下是常见问题和解决方案。

常见问题

  • 堆栈创建失败:查看事件选项卡以获取相应的错误消息。

  • 无法访问 Web 服务器:验证 MyIP 参数中您的 IP 地址是否正确。别忘了在末尾加上 /32

  • 引导过程失败:实例可能会启动但 cfn-init 失败。按照“监控”章节所述查看系统日志。

清理资源

为了避免持续产生费用,您可以删除堆栈及其资源来进行清除。

想要删除堆栈和它的资源
  1. 打开 CloudFormation 控制台

  2. 堆栈页面上,选择您创建的堆栈名称旁的选项(BootstrapTutorialStack),然后选择删除

  3. 当系统提示进行确认时,选择 Delete(删除)

  4. 事件选项卡上监控堆栈删除过程的进度。BootstrapTutorialStack 的状态更改为 DELETE_IN_PROGRESS。当 CloudFormation 完成删除堆栈后,它会将从列表中移堆栈除。

后续步骤

恭喜您!现在您已经成功地学会如何使用 CloudFormation 引导 EC2 实例。您现在已经知道:

  • 如何使用 cfn-init 帮助程序脚本

  • 如何构建用于引导的元数据

  • 如何安装软件包、创建文件、运行命令和管理服务

  • 如何监控引导问题

继续学习:

  • 了解如何引导 Windows 堆栈。有关更多信息,请参阅 引导基于 Windows 的 CloudFormation 堆栈

  • 使用多个配置集探索更复杂的引导情境。有关更多信息,请参阅《Amazon CloudFormation 模板参考指南》中的 cfn-initAWS::CloudFormation::Init

  • 了解如何使用 cfn-signal 报告引导完成状态。有关更多信息,请参阅《Amazon CloudFormation 模板参考指南》中的 cfn-signal