在 Amazon EC2 上部署应用程序
您可以使用 CloudFormation 在 Amazon EC2 实例上自动安装、配置和启动应用程序。这样能让您轻松复制部署和更新现有安装而无需直接连接到该实例,从而为您节省大量时间和工作量。
CloudFormation 包括一组基于 cloud-init
的帮助程序脚本(cfn-init
、cfn-signal
、cfn-get-metadata
和 cfn-hup
)。您可从 CloudFormation 模板中调用这些帮助程序脚本来在使用相同模板的 Amazon EC2 实例上安装、配置和更新应用程序。有关更多信息,请参阅《Amazon CloudFormation 模板参考指南》中的 CloudFormation 帮助程序脚本参考。
在入门教程中,您使用 UserData
和基础 bash 脚本创建了一个简单的 Web 服务器。虽然顺利创建了“Hello World”这样的简单页面,但实际应用程序通常需要更复杂的配置,包括:
-
按照正确的顺序安装多个软件包。
-
使用特定内容创建复杂的配置文件。
-
启动服务并将其配置为自动运行。
-
错误处理和验证设置过程。
与 UserData
中的基础 bash 脚本相比,CloudFormation 的帮助程序脚本提供了一种更稳健、更易于维护的方式来配置 EC2 实例。cfn-init
帮助程序脚本可以从模板的元数据中读取配置数据,并将其系统地应用于您的实例。
在本教程中,您将学习如何使用 cfn-init
帮助程序脚本以及如何监控引导过程。
注意
CloudFormation 使用免费,但您需要为自己创建的 Amazon EC2 资源付费。如果您不熟悉 Amazon,可以利用免费套餐
先决条件
了解引导的概念
在创建模板之前,我们先了解一下有助于引导顺利完成的关键概念。
cfn-init
帮助程序脚本
CloudFormation 提供 Python 帮助程序脚本,可用于在 Amazon EC2 实例中安装软件和启动服务。cfn-init
脚本可以从模板的元数据中读取配置数据,并将其应用于实例。
过程如下所述:
-
在 EC2 资源的
Metadata
部分中定义配置。 -
从
UserData
脚本中调用cfn-init
。 -
cfn-init
读取元数据并应用配置。 -
根据规范配置实例。
元数据结构
该配置是在 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
保存该文件。
启动堆栈模板
-
登录到 Amazon Web Services Management Console 并打开 Amazon CloudFormation 控制台 https://console.aws.amazon.com/cloudformation
。 -
依次选择创建堆栈和使用新资源(标准)。
-
在指定模板下,选择上传模板文件,然后选择选择文件,上传
samplelinux2stack.template
文件。 -
选择下一步。
-
在指定堆栈详细信息页面上,将堆栈命名为
BootstrapTutorialStack
。 -
在参数下,执行以下操作。
-
LatestAmiId:保留默认值。
-
InstanceType:选择 t2.micro 或 t3.micro 作为 EC2 实例类型。
-
MyIP:输入带
/32
后缀的公有 IP 地址。
-
-
选择两次下一步,然后选择提交即可创建堆栈。
监控引导过程
引导过程比简单的 EC2 启动需要更长的时间,因为引导过程中需要安装和配置其他软件。
监控引导进度
-
在 CloudFormation 控制台中,选择堆栈并打开事件选项卡。
-
注意
WebServer CREATE_IN_PROGRESS
事件。引导过程在实例启动后开始。 -
引导过程通常需要花费几分钟的时间。完成时,您可以看到
WebServer CREATE_COMPLETE
。
如果想知道引导过程中发生了什么,可以查看实例日志。
查看引导日志(可选)
-
打开 EC2 控制台
,找到您的实例。 -
选择实例,然后依次选择操作、监控和故障排除、获取系统日志,即可查看引导过程。
-
如果日志没有即刻出现,请稍等片刻,然后刷新页面。
测试引导的 Web 服务器
当堆栈显示 CREATE_COMPLETE
时,请测试 Web 服务器。
测试 Web 服务器
-
在 CloudFormation 控制台中,转到您堆栈的输出选项卡。
-
单击 WebsiteURL 值,在新选项卡中打开 Web 服务器。
-
您应看到自定义网页和消息
Congratulations, you have successfully launched the AWS CloudFormation sample
。
注意
如果页面没有立即加载,请稍等片刻,然后重试。即使堆栈已显示 CREATE_COMPLETE
,引导过程可能仍在完成。
引导问题排查
如果引导过程失败或您的 Web 服务器无法运行,以下是常见问题和解决方案。
常见问题
-
堆栈创建失败:查看事件选项卡以获取相应的错误消息。
-
无法访问 Web 服务器:验证
MyIP
参数中您的 IP 地址是否正确。别忘了在末尾加上/32
。 -
引导过程失败:实例可能会启动但
cfn-init
失败。按照“监控”章节所述查看系统日志。
清理资源
为了避免持续产生费用,您可以删除堆栈及其资源来进行清除。
想要删除堆栈和它的资源
-
在堆栈页面上,选择您创建的堆栈名称旁的选项(
BootstrapTutorialStack
),然后选择删除。 -
当系统提示进行确认时,选择 Delete(删除)。
-
在事件选项卡上监控堆栈删除过程的进度。
BootstrapTutorialStack
的状态更改为DELETE_IN_PROGRESS
。当 CloudFormation 完成删除堆栈后,它会将从列表中移堆栈除。
后续步骤
恭喜您!现在您已经成功地学会如何使用 CloudFormation 引导 EC2 实例。您现在已经知道:
-
如何使用
cfn-init
帮助程序脚本 -
如何构建用于引导的元数据
-
如何安装软件包、创建文件、运行命令和管理服务
-
如何监控引导问题
继续学习:
-
了解如何引导 Windows 堆栈。有关更多信息,请参阅 引导基于 Windows 的 CloudFormation 堆栈。
-
使用多个配置集探索更复杂的引导情境。有关更多信息,请参阅《Amazon CloudFormation 模板参考指南》中的 cfn-init 和 AWS::CloudFormation::Init。
-
了解如何使用
cfn-signal
报告引导完成状态。有关更多信息,请参阅《Amazon CloudFormation 模板参考指南》中的 cfn-signal。