AWS CloudFormation テンプレートリファレンス – AWS::CloudFormation::Init
- Template Reference - AWS CloudFormation
- CloudFormation | 特集カテゴリー | Developers.IO
- AWS CloudFormationテンプレートリファレンス | シリーズ | Developers.IO
下記エントリではヘルパースクリプトとして『cfn-init』を紹介しましたが、そのスクリプトと密接に関係しているこちらのテンプレートについても併せてご紹介したいと思います。
cfn-initのヘルパースクリプトを使ったAmazon EC2インスタンスの構築にメタデータを含める為には、AWS::CloudFormation::Initを使用します。テンプレートがcfn-initを呼び出した場合、スクリプトはAWS::CloudFormation::Initメタデータのキーに基づいたリソースメタデータを探します。詳細については、cfn-initをご参照ください。
メタデータは、configsetsにてグループ化する事が出来る設定キー(config key)で構成されています。テンプレート内でcfn-initを呼ぶ際に、それらを指定する事が出来ます。もしconfigsetを指定しない場合、cfn-initはconfigという名前の単一の設定を探します。
設定は複数のセクションに分かれています。以下のテンプレートのスニペットは、テンプレート内のAmazon EC2インスタンスリソースにcfn-initのメタデータを添付する方法をを示しています。
"Resources": { "MyInstance": { "Type": "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { "packages" : { : }, "sources" : { : }, "commands" : { : }, "files" : { : }, "services" : { : }, "users" : { : }, "groups" : { : } } } }, "Properties": { : } } }
cfn-initはLinuxシステムの全てのメタデータタイプがサポートされています。また、以下のセクションで説明された条件を使用する事で、Windowsのメタデータ・タイプもサポートします。AWS::CloudFormation::Initとcfn-initのヘルパースクリプトを使用する例については、Deploying Applications with AWS CloudFormationをご参照ください。
目次
Configsets
複数のconfigキーを作成し、それらを特定の順序でcfn-initプロセスを持たせたい場合は、希望する順番でconfigキーを含むconfigsetを作成します。例えば、以下テンプレートのスニペットは、それぞれ2つのconfigキーを含むascendingとdescendingと名付けられたconfigsetを作成しています。
"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が前述のconfigsetsを呼び出しているものです。呼び出しは分り易くする為に省略されています。完全な構文については、cfn-initをご参照ください。
cfn-initでascendingのconfigsetを指定したい場合は以下の様にして呼び出します。スクリプトはconfig1→config2の順番に処理を行い、test.txtファイルにはI come from config2が含まれる形になるでしょう。
cfn-init -c ascending
cfn-initでdescendingのconfigsetを指定したい場合は以下の様にして呼び出します。スクリプトはconfig2→config1の順番に処理を行い、test.txtファイルにはI come from config1が含まれる形になるでしょう。
cfn-init -c descending
複数のconfigsetsを作成し、cfn-initスクリプトを使用してそれら一連の処理を呼び出す事が出来ます。それぞれのconfigsetは、configキーのリストや他のconfigsetsへの参照を含める事が出来ます。例えば、以下テンプレートのスニペットは、3つのconfigsetsを作成しています。
- 最初のconfigset,test1は、1という名前のconfigキーが含まれています。
- 2つ目のconfigset,test2には、test1のconfigsetへの参照と、2という名前のconfigキーが含まれています。
- 3つ目のconfigset,defaultには、test2 のconfigsetへの参照が含まれています。
"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" : "~" } } } }
以下configsetsを参照する為のcfn-initの呼び出しは、前述のテンプレートスニペット内で宣言されています。例は分り易くするために省略されています。完全な構文についてはcfn-initをご参照ください。
test1のみ指定する場合は以下の様に実行。configキー1の処理のみ行います。
cfn-init -c test1
test2のみ指定する場合は以下の様に実行。configキー1を処理し、次いでconfigキー2の処理を行います。
cfn-init -c test2
defaultを指定(または指定無しの場合)、以下の様に実行。test2を指定した場合と同じ挙動となります。
test1のみ指定する場合は以下の様に実行。configキー1の処理のみ行います。
cfn-init -c default
Commands
EC2インスタンス上でコマンドを実行する為に、commandsキーを使う事が出来ます。コマンドは、名前のアルファベット順に処理されます。
キー | 必須 | 詳細 |
---|---|---|
command | ◯ | 配列または実行するコマンドを指定する文字列のいずれかを設定。配列を指定する場合は、空白文字をエスケープor引用符でコマンドパラメータを囲む必要はありません。 |
env | ー | コマンドの環境変数を設定。このプロパティは、追加というよりむしろ既存環境の情報を上書きします。 |
cwd | ー | 作業ディレクトリを指定。 |
test | ー | コマンドキーに含まれるコマンドを処理する為にcfn-initが真の値を返す必要があるコマンドを検証。 |
ignoreErrors | ー | コマンドキーに含まれているコマンドがが失敗した(0以外の値が返ってくる)場合にcfn-initが実行を続けるかどうかをBoolean値で設定。コマンドが失敗しても実行を継続させたい場合はtrueを設定します。失敗時に実行を停止させたい場合はfalseを設定します。デフォルト値はfalseです。 |
waitAfterCompletion | ー | Windowsシステムの場合のみ有効。コマンドが再起動を引き起こすような場合、コマンド終了後、どの位の時間待機するかを指定します。デフォルト値は60秒で、値:foreverを指定した場合は、cfn-initに終了後再起動が完了した後にのみ再開するように指示します。 |
以下実行例ではechoコマンドを実行しています。
"commands" : { "test" : { "command" : "echo \"$MAGIC\" > test.txt", "env" : { "MAGIC" : "I come from the environment!" }, "cwd" : "~", "test" : "test ! -e ~/test.txt", "ignoreErrors" : "false" } }
Files
EC2インスタンスのファイルを作成する為にfilesキーを使う事が出来ます。コンテンツはテンプレート上にインラインで記入するか、若しくはURLから取得する事が出来ます。ファイルは辞書式順序でディスクに書き込まれます。以下表はサポートされているキーの一覧です。
キー | 詳細 |
---|---|
content | 文字列、又は適切にフォーマットされたJSONオブジェクトのいずれか。もしJSONオブジェクトをコンテンツとして使う場合、JSONはディスク上のファイルに書き込まれます。JSONオブジェクトがディスクに書き込まれる前に、Fn:GetAttやRefのような任意の組み込み関数は事前に評価されます。 |
source | URLからファイルをロードします。このオプションはコンテンツキーで指定する事は出来ません。 |
encoding | エンコード形式。内容が文字列である場合にのみ使用可能。ソースを使用している場合は符号化は適用されません。 有効な形式: 平文 | base64 |
group | このファイル所有グループの名前。(Windowsシステムではサポートされません) |
owner | このファイルを所有するユーザーの名前。(Windowsシステムではサポートされません) |
mode | このファイルモードを表す6桁の8進数値。(Windowsシステムではサポートされません) |
authentication | 使用する認証方式の名前。デフォルトの認証方式を上書きします。AWS::CloudFormation::Authenticationリソースを選択すると、このプロパティを使用出来ます。 |
context | Mustacheテンプレートとして処理されるファイルのコンテキストを指定します。このキーを使うには、pystache同様にaws-cfn-bootstrap1.3.11以上をインストールしておく必要があります。 |
以下スニペットでは大規模インストールの一部としてsetup.mysqlというファイルを作成しています。
"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" } },
完全なテンプレートは以下URLで利用出来ます。:https://s3.amazonaws.com/cloudformation-templates-us-east-1/Drupal_Single_Instance.template
Mustacheテンプレートは、設定ファイルを作成する為に主に使われています。例えば、Fn::Joinを使う代わりにテンプレートからRefやGetAttsで補間を行い、設定ファイルをS3バケットに保存する事が出来ます。以下スニペットの例では、/tmp/test9.txtに"Content for test9"を出力しています。
"files" : { "/tmp/test9.txt" : { "content" : "Content for {{name}}", "context" : { "name" : "test9" } } }
Mustacheテンプレートを使用する場合は、以下の点に注意してください。
- contextキーは作成されるファイルに存在している必要があります。
- contextキーはキーと値のマップでなければなりませんが、入れ子にする事が出来ます。
- contentキーを使ってインラインコンテンツを処理する事が出来、そしてsourceキーを使ってリモートファイルを処理する事が出来ます。
- Mustacheサポートはpystacheのバージョンに依存します。Version0.5.2はMustache1.1.2をサポートしています。
Groups
Linux/Unixグループを作成し、グループIDを割り当てるキーグループを使用する事が出来ます。(※Windowsシステムではサポートされません)
グループを作成するには、オプションのグループIDに新しいグループ名をマップし、新しいキーと値のペアを追加します。グループキーは、1つまたは複数のグループ名を含むことが出来ます。以下表に使用可能なキーの一覧を示します。
キー | 詳細 |
---|---|
gid | グループIDの数値。 グループIDを指定した際に既に同じグループ名が存在する場合は失敗します。もし他のグループが指定グループIDを有していた場合もまた、OSが作成を拒否するでしょう。 例: { "gid" : "23" } |
記述例
以下スニペットは、グループIDを割り当てずにgroupOneという名前のグループを指定している例と、グループID値:45を指定してgroupTwoという名前のグループを指定している例です。
"groups" : { "groupOne" : {}, "groupTwo" : { "gid" : "45" } }
Packages
予めパッケージ化されたアプリケーションやコンポーネントをダウンロード&インストールするためにpackagesキーを使用する事が出来ます。Windowsシステムでは、packagesキーはMSIインストーラのみをサポートしています。
サポートしているパッケージフォーマット
cfn-initは現在、以下のパッケージをサポートしています:apt、yum、rubygems、python、rpm。
また、packagesは、以下の順番で処理を行います:rpm、yum/apt、rubygems&python。
rubygemsとpython、またはそれぞれのパッケージマネージャ内でのパッケージは導入順序は保証されていません。
バージョンの指定
パッケージマネージャ内では、各パッケージはパッケージ名とバージョンのリストとして指定されます。バージョンは文字列、バージョンのリスト、または空文字列orリストで指定出来ます。空の文字列またはリストを指定した場合は最新バージョンとみなされます。rpmマネージャーの場合、バージョンはディスク又はURL上のファイルへのパスとして指定されます。
記述例
以下スニペットは、rpmのバージョンURLを指定しています。yumで最新バージョンを、rubygemsでversion0.10.2を要求しています。
"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" ] }
Services
インスタンスの起動時にサービスを有効にするか無効にするかを定義する為に、servicesキーを使用する事が出来ます。Linuxシステムでは、このキーはsysvinitを使用する事でサポートされています。Windowsシステムでは、Windowsサービスマネージャを使用する事でサポートされます。
servicesキーはまた、再起動がインストールされるファイルの為に必要となる場合、cfn-initが再起動の世話を行えるようにソースパッケージとファイルの依存関係を指定することが出来ます。例えば、Apache HTTP Serverのパッケージをダウンロードする場合、パッケージのインストールは自動的にスタック作成プロセス中にApache HTTP Serverを開始します。しかし、Apache HTTP Serverの設定がスタック作成プロセスの後で更新された場合、Apacheサーバが再起動されない限りその更新は有効になりません。Apache HTTPサービスが再起動される事を保証する為に、servicesキーを使用する事が出来ます。
以下表はサポートされているキーの一覧です。
キー | 詳細 |
---|---|
ensureRunning | cfn-init終了後、サービスが稼働している事を確認する場合、trueを設定。終了後に実行されていない事を確認するにはfalseを設定。サービス状態に変更を加えない為に、このキーは省略します。 |
enabled | サービスが起動時に自動的に始動される事を確実にする為にはtrue。起動されない事を確実にするにはfalseを設定。プロパティに変更を加えない為に、このキーは省略します。 |
files | ファイルのリスト。cfn-initがファイルブロックを経由して直接変更が加わった場合、このサービスは再起動します。 |
sources | ディレクトリのリスト。cfn-initがこれらのいずれかのディレクトリにアーカイブを展開する場合、このサービスは再起動されます。 |
packages | パッケージ名のリストに対するパッケージマネージャのマップ。cfn-initがこれらのパッケージをインストール又は更新する場合、このサービスは再起動されます。 |
commands | コマンド名のリスト。cfn-initが指定されたコマンドを実行している場合、このサービスは再起動されます。 |
以下例のコードでは、以下の様なサービスを構成します。
- /etc/nginx/nginx.confまたは/var/www/htmlがcfn-initによって変更された場合、nginxのサービスが再起動されます。
- cfn-initがphpまたはspawn-fcgiをyumを使ってインストール・更新した場合、php-fastcgiのサービスが再起動されます。
- sendmailのサービスは停止又は無効化されます
"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" } } }
Sources
アーカイブファイルをダウンロードして、EC2インスタンス上のターゲットディレクトリに回答するsourceキーを使用出来ます。このキーは、LinuxとWindowsシステムの両方でサポートされています。
サポートされる形式
tar, tar+gzip, tar+bz2、zip。
GitHub
ソース管理システムとしてGitHubを使用している場合、アプリケーションの特定バージョンをpullしてcfn-initとソースパッケージのメカニズムを使用する事が出来ます。GitHubでは、以下の様にURLを経由して特定のバージョンからのzip/tarを作成する事が出来ます。
https://github.com/<your directory>/(zipball|tarball)/<version>
例えば、以下スニペットでは.tarファイルとしてマスターバージョンをpull downしています。
"sources" : { "/etc/puppet" : https://github.com/user1/cfn-demo/tarball/master }
記述例
以下例は、Amazon S3バケットからzipファイルをダウンロードし、/etc/myappに解凍しています。
"sources" : { "/etc/myapp" : "https://s3.amazonaws.com/mybucket/myapp.tar.gz" }
ソースに対して、認証情報を使う事が出来ます。ただし、ソースブロックに認証キーを置く事は出来ません。その代わりにS3AccessCredsブロック内にバケットキーが含まれています。例えば、以下テンプレートをご参照ください。Amazon S3の認証情報に関する詳細については、AWS::CloudFormation::Authenticationをご参照ください。
Users
EC2インスタンス上のLinux/Unixユーザーを作成する為に、usersキーを使用する事が出来ます。(※Windowsシステムではサポートされていません)
以下はサポートされているキーの一覧です。
キー | 詳細 |
---|---|
uid | ユーザーID。ユーザー名が異なるユーザーIDで存在する場合、作成プロセスは失敗します。ユーザーIDが既に既存ユーザーに割り当てられいる場合も、OSが作成を拒否します。 |
groups | グループ名のリスト。ユーザーはリスト内の各グループに追加されます。 |
homeDir | ユーザーのホームディレクトリ。 |
ユーザーは/sbin/nologinシェルの非対話システムユーザーとして作成されます。これは仕様であり、変更する事は出来ません。
"users" : { "myUser" : { "groups" : ["groupOne", "groupTwo"], "uid" : "50", "homeDir" : "/tmp" } }