AWS CloudFormation
User Guide (API Version 2010-05-15)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。请点击 Amazon AWS 入门,可查看中国地区的具体差异

AWS::CloudFormation::Init

使用类型 AWS::CloudFormation::Init 来将 Amazon EC2 实例上的元数据置入 cfn-init 帮助程序脚本。如果您的模板调用 cfn-init 脚本,该脚本会查询来源于AWS::CloudFormation::Init 元数据密钥内的资源元数据。有关 cfn-init 的详细信息,请参阅 cfn-init

cfn-init 支持 Linux 系统的所有元数据类型。在满足下面部分中说明的条件时,它还支持 Windows 的元数据类型。

有关使用 AWS::CloudFormation::Init 和 cfn-init 帮助程序脚本的示例,请参阅 使用 AWS CloudFormation 在 Amazon EC2 上部署应用程序

有关说明如何使用 cfn-init 创建 Windows 堆栈的示例,请参阅启动 AWS CloudFormation Windows 堆栈

语法

配置过程分为几个部分。以下模板代码段演示如何在模板内将 cfn-init 的元数据附加到 Amazon EC2 实例资源。

元数据分成数个配置密钥,您可以将它们分成几个 configset。当您在模板中调用 cfn-init 时,可以指定 configset。如果您不指定 configset,cfn-init 会查找名为 config 的配置密钥。

注意

该 cfn-init 帮助程序脚本以下列顺序处理这些配置节:packages、groups、users、sources、files、commands,然后是 services。如果您需要以不同顺序处理,请将各节分为不同的配置键,然后使用配置集指定处理这些配置键应采用的顺序。

JSON

"Resources": { "MyInstance": { "Type": "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { "packages" : { : }, "groups" : { : }, "users" : { : }, "sources" : { : }, "files" : { : }, "commands" : { : }, "services" : { : } } } }, "Properties": { : } } }

YAML

Resources: MyInstance: Type: "AWS::EC2::Instance" Metadata: AWS::CloudFormation::Init: config: packages: : groups: : users: : sources: : files: : commands: : services: : Properties: :

Configset

如果您创建多个配置密钥并使 cfn-init 以特定的顺序处理这些密钥,则可创建一个 configset,其中包含以特定顺序排列的多个配置密钥。

单个 Configset

以下模板代码段创建名为 ascendingdescending 的两个 configset,每个各包含 2 个配置密钥。

JSON

"AWS::CloudFormation::Init" : { "configSets" : { "ascending" : [ "config1" , "config2" ], "descending" : [ "config2" , "config1" ] }, "config1" : { "commands" : { "test" : { "command" : "echo \"$CFNTEST\" > test.txt", "env" : { "CFNTEST" : "I come from config1." }, "cwd" : "~" } } }, "config2" : { "commands" : { "test" : { "command" : "echo \"$CFNTEST\" > test.txt", "env" : { "CFNTEST" : "I come from config2" }, "cwd" : "~" } } } }

YAML

AWS::CloudFormation::Init: configSets: ascending: - "config1" - "config2" descending: - "config2" - "config1" config1: commands: test: command: "echo \"$CFNTEST\" > test.txt" env: CFNTEST: "I come from config1." cwd: "~" config2: commands: test: command: "echo \"$CFNTEST\" > test.txt" env: CFNTEST: "I come from config2" cwd: "~"

相关的 cfn-init 调用

下面的示例 cfn-init 调用适用于前述示例 configset。为清晰起见,示例调用采用的是缩写形式,请参阅 cfn-init 了解完整语法。

  • 如果对 cfn-init 调用指定了 ascending configset:

    cfn-init -c ascending

    脚本会先处理 config1,然后再处理 config2,而 test.txt 文件将包含文本 I come from config2

  • 如果对 cfn-init 调用指定了 descending configset:

    cfn-init -c descending

    脚本会先处理 config2,然后再处理 config1,而 test.txt 文件将包含文本 I come from config1

多个 Configset

您可以创建多个 configset,并使用 cfn-init 脚本对它们进行一连串调用。每个 configset 都包含配置密钥列表或对其他 configset 的引用的列表。例如,以下模板代码段可创建三个 configset。第一个 configset test1 包含一个名为 1 的配置密钥。第二个 configset test2 包含对 test1 configset 的引用和一个名为 2 的配置密钥。在默认情况下,第三个 configset 包含对 configset test2 的引用。

JSON

"AWS::CloudFormation::Init" : { "configSets" : { "test1" : [ "1" ], "test2" : [ { "ConfigSet" : "test1" }, "2" ], "default" : [ { "ConfigSet" : "test2" } ] }, "1" : { "commands" : { "test" : { "command" : "echo \"$MAGIC\" > test.txt", "env" : { "MAGIC" : "I come from the environment!" }, "cwd" : "~" } } }, "2" : { "commands" : { "test" : { "command" : "echo \"$MAGIC\" >> test.txt", "env" : { "MAGIC" : "I am test 2!" }, "cwd" : "~" } } } }

YAML

AWS::CloudFormation::Init: 1: commands: test: command: "echo \"$MAGIC\" > test.txt" env: MAGIC: "I come from the environment!" cwd: "~" 2: commands: test: command: "echo \"$MAGIC\" >> test.txt" env: MAGIC: "I am test 2!" cwd: "~" configSets: test1: - "1" test2: - ConfigSet: "test1" - "2" default: - ConfigSet: "test2"

相关的 cfn-init 调用

以下 cfn-init 调用适用于前述模板代码段中声明的 configSet。为清楚起见,对示例调用进行了简略;有关完整语法,请参阅 cfn-init

  • 如果您仅指定 test1

    cfn-init -c test1

    cfn-init 仅处理配置密钥 1

  • 如果您仅指定 test2

    cfn-init -c test2

    cfn-init 会先处理配置密钥 1,然后再处理配置密钥 2

  • 如果您指定 default configset(或根本没有 configsets):

    cfn-init -c default

    如果您指定 test2,则将获得相同的特性。

命令

您可以使用命令密钥在 EC2 实例上执行命令。其执行顺序即为命令名称的字母顺序。

说明

命令

必需。指定要运行的命令的数组或字符串。如果使用数组,那么不需要转义空格字符,或者在命令参数周围使用引号。请勿使用数组指定多个命令。

env

可选。设置该命令的环境变量。这个属性会覆盖而不是追加到现有的环境。

cwd

可选。工作目录

测试

可选。用于确定 cfn-init 是否运行在命令密钥中指定的命令的测试命令。如果测试通过,则 cfn-init 将运行命令。cfn-init 脚本在命令解释器(如 Bash 或 cmd.exe)中运行测试。测试能否通过取决于解释器返回的退出代码。

对于 Linux,测试命令必须返回退出代码 0,才表示测试通过。对于 Windows,测试命令必须返回 %ERRORLEVEL% 0

ignoreErrors

可选。一个布尔值,用于确定在命令密钥中包含的命令失败时(返回非零值)cfn-init 是否继续运行。如果您希望即使命令失败 cfn-init 也能继续运行,则请设置为 true。如果您希望命令失败时 cfn-init 停止运行,则请设置为 false。默认值为 false

waitAfterCompletion

可选。仅限于 Windows 系统。指定命令执行结束后,在该命令引起重启的情况下需要等待的时间长短(以秒为单位)。默认值是 60 秒,而值“forever”会使 cfn-init 退出,并且仅在重启完成后继续。如果您不想等待每条命令,请将此值设置为 0

示例

下面的示例代码段在 ~/test.txt 文件不存在时调用 echo 命令。

JSON

"commands" : { "test" : { "command" : "echo \"$MAGIC\" > test.txt", "env" : { "MAGIC" : "I come from the environment!" }, "cwd" : "~", "test" : "test ! -e ~/test.txt", "ignoreErrors" : "false" }, "test2" : { "command" : "echo \"$MAGIC2\" > test2.txt", "env" : { "MAGIC2" : "I come from the environment!" }, "cwd" : "~", "test" : "test ! -e ~/test2.txt", "ignoreErrors" : "false" } }

YAML

commands: test: command: "echo \"$MAGIC\" > test.txt" env: MAGIC: "I come from the environment!" cwd: "~" test: "test ! -e ~/test.txt" ignoreErrors: "false" test2: command: "echo \"$MAGIC2\" > test2.txt" env: MAGIC2: "I come from the environment!" cwd: "~" test: "test ! -e ~/test2.txt" ignoreErrors: "false"

文件

您可以使用 files 密钥在 EC2 实例上创建文件。其内容既可以来自模板,也可以从 URL 抽取。这些文件会按词典顺序写入磁盘。下表列出了支持的密钥。

说明

内容

字符串或格式正确的 JSON 数据元。如果您将 JSON 数据元用作内容,则 JSON 将被写到磁盘上的文件中。您必须在 JSON 对象写入磁盘之前,评估所有固有函数,如 Fn::GetAtt 或 Ref。在创建符号链接时,将符号链接目标指定为内容。

注意

如果创建符号链接,帮助程序脚本会修改目标文件的权限。目前,您无法在不修改目标文件的权限的情况下创建符号链接。

来源

用于加载文件的 URL。不能使用内容密钥指定该选项。

编码

编码格式。仅限在内容为字符串时使用。如果使用的是源,则不会应用编码。

有效值:plain | base64

拥有这个文件的组的名称。在 Windows 系统中不受支持。

owner

拥有这个文件的用户的名称。在 Windows 系统中不受支持。

模式

是一个六位数的八进制值,表示这个文件的模式。在 Windows 系统中不受支持。将前三位数用于符号链接,将后三位数用于设置权限。要创建符号链接,请指定 120xxx,其中 xxx 定义目标文件的权限。要指定文件的权限,请使用最后三位,例如 000644

身份验证

要使用的身份验证方法的名称。这会覆盖任何默认的身份验证。您可以使用此属性选择通过 AWS::CloudFormation::Authentication 资源定义的身份验证方法。

context

指定需要作为 Mustache 模板处理的文件的上下文。若要使用此密钥,必须已安装 aws-cfn-bootstrap 1.3-11 或更高版本以及 pystache

示例

下面的示例代码段将文件 setup.mysql 创建为大型安装的一部分。

例 JSON

"files" : { "/tmp/setup.mysql" : { "content" : { "Fn::Join" : ["", [ "CREATE DATABASE ", { "Ref" : "DBName" }, ";\n", "CREATE USER '", { "Ref" : "DBUsername" }, "'@'localhost' IDENTIFIED BY '", { "Ref" : "DBPassword" }, "';\n", "GRANT ALL ON ", { "Ref" : "DBName" }, ".* TO '", { "Ref" : "DBUsername" }, "'@'localhost';\n", "FLUSH PRIVILEGES;\n" ]]}, "mode" : "000644", "owner" : "root", "group" : "root" } }

例 YAML

files: /tmp/setup.mysql: content: !Sub | CREATE DATABASE ${DBName}; CREATE USER '${DBUsername}'@'localhost' IDENTIFIED BY '${DBPassword}'; GRANT ALL ON ${DBName}.* TO '${DBUsername}'@'localhost'; FLUSH PRIVILEGES; mode: "000644" owner: "root" group: "root"

可在此获取完整的模板:https://s3.amazonaws.com/cloudformation-templates-us-east-1/Drupal_Single_Instance.template

下面的示例代码段创建指向现有文件 /tmp/myfile1.txt 的符号链接 /tmp/myfile2.txt。目标文件 /tmp/myfile1.txt 的权限由模式值 644 定义。

例 JSON

"files" : { "/tmp/myfile2.txt" : { "content" : "/tmp/myfile1.txt", "mode" : "120644" } }

例 YAML

files: /tmp/myfile2.txt: content: "/tmp/myfile1.txt" mode: "120644"

Mustache 模板主要用于创建配置文件。例如,您可以将配置文件存储在一个 S3 存储桶中,并从模板插入 Refs 和 GetAtts,而不是使用 Fn::Join。下面的示例代码段将“Content for test9”输出到 /tmp/test9.txt

例 JSON

"files" : { "/tmp/test9.txt" : { "content" : "Content for {{name}}", "context" : { "name" : "test9" } } }

例 YAML

files: /tmp/test9.txt: content: "Content for {{name}}" context: name: "test9"

在使用 Mustache 模板时,请注意以下几点:

  • 必须存在用于要处理的文件的上下文密钥。

  • 上下文密钥必须是密钥值映射,但可以嵌套。

  • 您可以使用内容密钥来处理含有内联内容的文件,并使用源密钥来处理远程文件。

  • Mustache 支持取决于 pystache 版本。版本 0.5.2 支持 Mustache 1.1.2 规范

您可以使用组密钥创建 Linux/UNIX 组,并分配组 ID。该组密钥在 Windows 系统中不受支持。

要创建组,请添加新的密钥值对,将新的组名映射到可选组 ID。组密钥可以包含一个或多个组名。下表列出了可用的密钥。

说明

gid

组 ID 编号。

如果指定了组 ID,且存在该名称的组,那么创建组将失败。如果其他组已使用指定的 ID,则操作系统可能会拒绝创建该组。

示例:{ "gid" : "23" }

示例代码段

以下代码段指定两个组,其中一个名为 groupOne 但没有分配组 ID,另一个组名为 groupTwo,指定的相应组 ID 值为 45

JSON

"groups" : { "groupOne" : {}, "groupTwo" : { "gid" : "45" } }

YAML

groups: groupOne: {} groupTwo: gid: "45"

软件包

您可以使用包密钥下载和安装各种预包装的应用程序和组件。在 Windows 系统上,软件包密钥仅支持 MSI 安装程序。

支持的软件包格式

cfn-init 脚本目前支持以下软件包格式:apt、msi、python、rpm、rubygems 和 yum。软件包的处理顺序如下:先是 rpm、yum/apt,然后是 rubygems 和 python。rubygems 和 python 之间没有处理顺序,且不保证以任何顺序安装每个包管理器内的包。

指定版本

在每个包管理器内,会使用包名和一系列版本对每个包进行指定。版本可以是字符串、一系列版本、空字符串或者空列表。空字符串或者空列表表示您需要最新的版本。对于 rpm 管理器,版本是以磁盘或 URL 上的文件的路径的方式指定的。

如果您指定软件包的版本,cfn-init 将尝试安装该版本,即使已在实例上安装该软件包的更新版本。一些包管理器支持多个版本,但其他的包管理器可能不支持。有关更多信息,请查看相关的包管理器文档。如果您不指定版本且已安装某版本的软件包,则 cfn-init 脚本将不安装新版本,因为它假定您要沿用现有版本。

示例代码段

RPM、yum 和 Rubygems

下面的代码段为 rpm 指定版本 URL,从 yum 请求最新版本并从 rubygems 请求 chef 的版本 0.10.2:

JSON
"rpm" : { "epel" : "http://download.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm" }, "yum" : { "httpd" : [], "php" : [], "wordpress" : [] }, "rubygems" : { "chef" : [ "0.10.2" ] }
YAML
rpm: epel: "http://download.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm" yum: httpd: [] php: [] wordpress: [] rubygems: chef: - "0.10.2"

MSI 包

下面的代码段为 MSI 包指定 URL:

JSON
"msi" : { "awscli" : "https://s3.amazonaws.com/aws-cli/AWSCLI64.msi" }
YAML
msi: awscli: "https://s3.amazonaws.com/aws-cli/AWSCLI64.msi"

服务

您可以使用此服务密钥来定义实例启动后应启用或禁用哪些服务。在 Linux 系统上,将通过使用 sysvinit 来支持此密钥。在 Windows 系统上,将通过使用 Windows 服务管理器来支持此密钥。

服务密钥还支持您指定源、软件包和文件之间的相关性,这样如果由于安装文件导致重启时,cfn-init 会处理服务重启部分。例如,如果您下载 Apache HTTP Server 软件包,则在堆栈创建过程中,软件包安装将自动启动 Apache HTTP Server。然而,如果 Apache HTTP Server 配置在堆栈创建过程的后期被更新,则要等到重启 Apache 服务器之后,更新才会生效。您可以使用服务密钥来确保 Apache HTTP 服务启动。

下表列出了支持的密钥。

说明

ensureRunning

设为 true 可确保 cfn-init 结束后服务仍保持运行。

设为 false 可确保 cfn-init 结束后服务不再运行。

忽略该密钥,将不更改服务状态。

已启用

设为 true 可确保启动时自动启动服务。

设为 false 可确保启动时不会自动启动服务。

忽略该密钥,将不更改这个属性。

files

一系列文件。如果 cfn-init 直接通过文件块更改其中一个文件,则该服务将重启。

来源

一系列目录。如果 cfn-init 将存档扩展到这些目录之一,则此服务将重启。

软件包

软件包管理器映射至软件包名称列表。如果 cfn-init 安装或更新其中一个软件包,则此服务将重启。

命令

一系列命令名称。如果 cfn-init 运行指定的命令,则此服务将重启。

示例

Linux

下面的 Linux 代码段配置服务如下:

  • 如果 cfn-init 修改了 /etc/nginx/nginx.conf 或 /var/www/html,则 nginx 服务会重启。

  • 如果使用 yum 安装或更新 php 或 spawn-fcgi,则 php-fastcgi 服务将重启。

  • 发送邮件服务不会停止和停用。

JSON
"services" : { "sysvinit" : { "nginx" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["/etc/nginx/nginx.conf"], "sources" : ["/var/www/html"] }, "php-fastcgi" : { "enabled" : "true", "ensureRunning" : "true", "packages" : { "yum" : ["php", "spawn-fcgi"] } }, "sendmail" : { "enabled" : "false", "ensureRunning" : "false" } } }
YAML
services: sysvinit: nginx: enabled: "true" ensureRunning: "true" files: - "/etc/nginx/nginx.conf" sources: - "/var/www/html" php-fastcgi: enabled: "true" ensureRunning: "true" packages: yum: - "php" - "spawn-fcgi" sendmail: enabled: "false" ensureRunning: "false"

Windows

下面的 Windows 代码段启动 cfn-hup 服务,将其设置为自动,并在 cfn-init 修改指定配置文件的情况下重新启动该服务:

JSON
"services" : { "windows" : { "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["c:\\cfn\\cfn-hup.conf", "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf"] } } }
YAML
services: windows: cfn-hup: enabled: "true" ensureRunning: "true" files: - "c:\\cfn\\cfn-hup.conf" - "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf"

您可以使用此资源密钥来下载存档文件并在 EC2 实例上的目标目录中取出文件。此密钥在 Linux 和 Windows 系统中完全受支持。

支持的格式

支持的格式包括 tar、tar+gzip、tar+bz2 以及 zip。

示例

GitHub

如果您将 GitHub 用作源控制系统,则可以使用 cfn-init 和源打包机制来提取特定的应用程序版本。GitHub 允许您通过 URL 从特定版本创建 zip 或 tar,如下所示:

https://github.com/<your directory>/(zipball|tarball)/<version>

例如,下面的代码段会将版本 master 作为一个 .tar 文件拉取。

JSON
"sources" : { "/etc/puppet" : "https://github.com/user1/cfn-demo/tarball/master" }
YAML
sources: /etc/puppet: "https://github.com/user1/cfn-demo/tarball/master"

S3Bucket

下面的示例会从 Amazon S3 存储段下载 ZIP 文件,并将其解包到 /etc/myapp 中:

注意

您可以对来源使用身份验证凭证,但不能将身份验证密钥放在源数据块中。相反,您可以将存储段密钥包含在 S3AccessCreds 数据块中。有关示例,请参阅示例模板有关 Amazon S3 身份验证凭证的更多信息,请参阅 AWS::CloudFormation::Authentication

JSON
"sources" : { "/etc/myapp" : "https://s3.amazonaws.com/mybucket/myapp.tar.gz" }
YAML
sources: /etc/myapp: "https://s3.amazonaws.com/mybucket/myapp.tar.gz"

用户

您可以使用用户密钥在 EC2 实例上创建 Linux/UNIX 用户。该用户密钥在 Windows 系统中不受支持。

下表列出了支持的密钥。

说明

uid

用户 ID。如果用户名还有另一个用户 ID,那么此创建过程会失败。如果该用户 ID 已分配给现有用户,则操作系统可能会拒绝创建请求。

一系列组名。该用户将被添加到列表的每个组中。

homeDir

用户的主目录。

示例

创建的用户属于非交互式系统用户,带有 /sbin/nologin 外壳。这是特意设计的,无法修改。

JSON

"users" : { "myUser" : { "groups" : ["groupOne", "groupTwo"], "uid" : "50", "homeDir" : "/tmp" } }

YAML

users: myUser: groups: - "groupOne" - "groupTwo" uid: "50" homeDir: "/tmp"