【初心者向け】CloudFormationのテンプレート作成で困った時の解決法

2014.08.19

こんにちは、虎塚です。

今日は、CloudFormationのテンプレートを書き始めた初心者が一度はハマると思われるポイントについて、解決法を共有したいと思います。特に、AWSをManagement Consoleからしか操作したことがない人がつい引っかかる地味な罠をまとめてみます。

はじめに

CloudFormationのテンプレートを書くための導入資料としては、当ブログのCloudFormationタグの記事がオススメです。私が特に重宝している記事は、次の3本です。

なお、3本目の記事の内容をすべて理解している方は、CloudFormationの達人とお見受けします。よかったら師匠になってください!

ハマるポイントとその解決法

インスタンスと仮想化タイプの組み合わせ

スタックを作ろうとした際に、次のようなエラーが出ることがあります。

{Resource要素名} Non-Windows instances with a virtualization type of 'hvm' are currently not supported for this instance type.

上のエラーは、起動しようとしたインスタンスタイプと、仮想化タイプが合わないAMIを間違って選んだときに発生します。AWSには、hvmとpvという仮想化タイプがあり(これについての説明は、こちらの記事をご覧ください。 PV->HVM変換ツール pv2hvm.rbを試してみた | Developers.IO)、インスタンスを起動する時には、インスタンスタイプに適した仮想化タイプのAMIを指定しなければなりません。

インスタンスと仮想化タイプの組み合わせは、次の公式ドキュメントで確認します。

たとえば、インスタンスタイプt1.microは、この記事を書いている時点ではhvm形式がサポートされていないことが分かります。

ルートのブロックデバイス名の確認方法

EC2インスタンスに取り付けるEBSのサイズを変更する設定を、テンプレートに書きたい時があります。

たとえば、Windowsインスタンスm1.smallのルートブロックデバイスのサイズ(デフォルトで30GB)を50GBに拡張するには、Resourcesの値として、次のように書きます。

    "WinServer" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "BlockDeviceMappings" : [
           {
              "DeviceName" : "/dev/sda1",
              "Ebs" : { "VolumeSize" : "50" }
           }
        ],
        "InstanceType" : "m1.small",
        "ImageId" : "ami-01510000",
        # ...(略)...
      }
    }

このとき、「/dev/sda1」というルートのブロックデバイス名は、次のドキュメントの「Specifying a Block Device Mapping」の表を参照して、適切な名前を指定します。インスタンスタイプごとに、ルートのブロックデバイスとして予約されている名前が決まっています。

なお、Linux / Unix (HVM)のように、上の表だけではルートデバイスの名前を一意に特定できないインスタンスタイプもあります。その場合、ec2-describe-images API を利用してAMIを調べることで、ルートデバイスの名前を確認できます。次の例では、AWS CLIを使って、ami-29dc9228を調べています。

  $ aws ec2 describe-images --image-ids ami-29dc9228 | grep RootDeviceName
   "RootDeviceName": "/dev/xvda",

このAMIは、hvm形式のLinuxなので、ルートデバイスは /dev/sda1 あるいは /dev/xvda のどちらかです。describe-imagesコマンドで確認することで、/dev/xvda だと分かりました。

RDSのDBエンジン

Management ConsoleからRDSを作るときは、最初にタブが出てきてDBエンジンを直感的に選べます。しかし、CliudFormationのテンプレートを書くには、文字列で「MySQL」などのDBエンジンを指定する必要があります。

しかし、「MySQL」が指定できるなら大丈夫だろうと思って「Oracle」などと雑に指定すると、スタック作成時にエラーになります。

Invalid DB engine: Oracle

指定できるDBエンジンは、次のドキュメントで確認します。

-e (--engine) オプションの説明に「Valid values」という項目があり、DBエンジンとして指定できる文字列が挙げられています。たとえば、Oracle RDSとして指定可能なエンジンは、この記事を書いている時点で「oracle-se1 | oracle-se | oracle-ee」の3種類です。

RDSのDBエンジンバージョン

起動するRDSのDBエンジンを決めたら、次にバージョンを指定する必要があります。

しかし、上記でリンクしたrds-create-db-instanceのドキュメントで -v (--engine-version) オプションの説明を見ると、サンプルの値しか載っていません。

ここでは、describe-db-engine-versions コマンドを使って、指定できるエンジンバージョンを取得します。たとえば、Oracle SE1のエンジンに指定できるバージョンを知るには、次のようにします。--engine オプションで、エンジンをフィルタリングできます。

% aws rds describe-db-engine-versions --engine oracle-se1
------------------------------------------------------------------------------
|                          DescribeDBEngineVersions                          |
+----------------------------------------------------------------------------+
||                             DBEngineVersions                             ||
|+-------------------------------+------------------------------------------+|
||  DBEngineDescription          |  Oracle Database Standard Edition One    ||
||  DBEngineVersionDescription   |  Oracle 11.2.0.2.v3                      ||
||  DBParameterGroupFamily       |  oracle-se1-11.2                         ||
||  Engine                       |  oracle-se1                              ||
||  EngineVersion                |  11.2.0.2.v3                             ||
|+-------------------------------+------------------------------------------+|
|||                           DefaultCharacterSet                          |||
||+--------------------------+---------------------------------------------+||
|||  CharacterSetDescription |  Unicode 5.0 UTF-8 Universal character set  |||
|||  CharacterSetName        |  AL32UTF8                                   |||
# ...(略)...
||+--------------------------+---------------------------------------------+||
||                             DBEngineVersions                             ||
|+-------------------------------+------------------------------------------+|
||  DBEngineDescription          |  Oracle Database Standard Edition One    ||
||  DBEngineVersionDescription   |  Oracle 11.2.0.4.v1                      ||
||  DBParameterGroupFamily       |  oracle-se1-11.2                         ||
||  Engine                       |  oracle-se1                              ||
||  EngineVersion                |  11.2.0.4.v1                             ||
|+-------------------------------+------------------------------------------+|
|||                           DefaultCharacterSet                          |||
||+--------------------------+---------------------------------------------+||
|||  CharacterSetDescription |  Unicode 5.0 UTF-8 Universal character set  |||
|||  CharacterSetName        |  AL32UTF8                                   |||
||+--------------------------+---------------------------------------------+||

たとえば、上記の中で最新の Oracle 11.2.0.4.v1 を利用するなら、バージョンに「11.2.0.4.v1」を指定します。

リソースへのタグ付与

CloudFormationのスタックを作成する際に、オプションで複数のタグを指定できます。

この時に指定したタグは、テンプレートに定義したリソースに同じキーがタグとして与えられていない限り、個々のリソースすべてに対して付与されます。リソースへ個別に与えたタグと同じキーでタグを指定した場合は、個別のタグが優先されます。

たとえば、EC2に個別に「Name」をキーとするタグを与えるのを忘れた状態で、スタック作成時に「Name」タグを指定した場合、次のようになります。

個別リソースにタグを付け忘れないようにする

スタック作成時に指定した「Name」タグが、すべてのEC2に付与されてしまいます。

「Name」タグは、Management Consoleでデフォルト表示されるので、個々のリソースに分かりやすい値をつけておくと便利です。

おわりに

いかがでしたでしょうか。また地味な話題が出てきたら共有させてください。

JSONの魔術師への道のりはまだ始まったばかりですが、楽しくいきたいと思います。

それでは、また。

浴衣姿のくらめそちゃん

非公式キャラクター・くらめそちゃん