share facebook facebook2 twitter menu hatena pocket slack

2014.08.27 WED

【米俵餅の AWS 記念日(2)】たくさんのインスタンスを起動したいから、今日は CloudFormation 記念日(2)〜いい日 kumogata 〜

川原 洋平

WRITTEN BY川原 洋平

どうも、作家でエッセイストの米俵餅こと #かっぱ (@inokara)です。タイトルの「〜いい日 kumogata 〜」は先輩のガミさん案から拝借致しました。

CloudFormation についてはだいたい解りましたが…

前回で CloudFormation についてはだいたい解ったつもりですが、いかんせん JSON が可読性が良いと言っても生で JSON とイチャイチャするのは個人的には敷居が高いということで、CloudFormation マスターの Y 氏に kumogata なる CloudFormation のラッパーを教えて頂きましたのでそれを使ってインスタンスを起動するところまでを試してみたいと思います。

詳しいことは README をご覧くださいませ。

kuwagata ではなく kumogata

kumogata の特徴としては

  • CloudFormation の JSON が Ruby DSL で記述出来る

ではないでしょうか(他にもあるかもしれませんが…)。例えば、インスタンスを起動する場合には kumogata で書くと以下のように書けます。

ec2.rb

myEC2Instance do
  Type "AWS::EC2::Instance"
  Properties do
    ImageId "ami-XXXXXXXX"
    InstanceType { Ref "InstanceType" }
    KeyName "your_key_name"
  end
end

これが JSON に展開されると以下のようになるようです。

ec2.json

{
  "Resources": {
    "myEC2Instance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "ImageId": "ami-XXXXXXXX",
        "InstanceType": {
          "Ref": "InstanceType"
        },
        "KeyName": "your_key_name"
      }
    }
  }
}

ほうほう。どっちが親しみ易いかというと個人的には前者です。Chef をちょっと触ったことがあるという薄っぺらいアドバンテージのもとで doend ブロック内で AMI の ID を指定しているんだなとか CloudFormation の定義がそのまま Ruby 内に展開出来るんだなとかが解ります。

まあ、何はともあれ kumogata してみる

構築する環境

  • 1VPC
  • 6 subnet
  • 各 subnet に 1 台ずつのインスタンスを構築
  • インスタンスの IP は決め打ち
  • 既に Apache が導入されている AMI から起動して OS 起動時に index.html を生成して Apache を起動する
  • インスタンス起動時に任意のタグを指定

ハンドパワー(手でマネジメントコンソール)で行えば一時間位は掛かってしまいそうな作業も、CloudFomation + kumogata の手に掛かれば…

firstkumogata.rb

firstkumogata.rb 以下のように作成しました。kumogata の README 冒頭に書かれていた内容を丸っとコピーしてちょっと要件に合うように調整いたしました。

firstkumogata.rb

AWSTemplateFormatVersion "2010-09-09"

Description (<<-EOS).undent
  Kumogata Sample Template
  You can use Here document!
EOS

Parameters do
  InstanceType do
    Default "t2.micro"
    Description "Instance Type"
    Type "String"
  end
  SubnetId do
    Default ""
    Description "Subnet ID"
    Type "String"
  end
  SecurityGroupIds do
    Default  "sg-xxxxxxx"
    Description "Security Group ID"
    Type "String"
  end
  PrivateIpAddress do
    Default  ""
    Description "Security Group ID"
    Type "String"
  end
  NameValue do
    Default  ""
    Description "Tag Name Value"
    Type "String"
  end
end

Resources do
  myEC2Instance do
    Type "AWS::EC2::Instance"
    Properties do
      ImageId "ami-xxxxxxxx"
      InstanceType { Ref  "InstanceType" }
      KeyName "xxxxxxxxx"
      SecurityGroupIds [_{Ref "SecurityGroupIds"}]
      IamInstanceProfile "xxxxxxxxx"
      SubnetId { Ref "SubnetId" }
      PrivateIpAddress { Ref  "PrivateIpAddress" }

      Tags [
        "Key" => "Name",
        "Value" =>  _{Ref  "NameValue"}
      ]

      UserData do
        Fn__Base64 (<<-EOS).undent
          #!/bin/bash
          hostname > /var/www/html/index.html
          sleep 5
          service httpd start
        EOS
      end
    end
  end
end

Outputs do
  AZ do
    Value do
      Fn__GetAtt "myEC2Instance", "AvailabilityZone"
    end
  end
end

以下のように実行するとインスタンスが起動します。(事前にクレデンシャルな設定はしておきましょう)

kumogata create firstkumogata.rb -p "PrivateIpAddress=192.168.1.10,SubnetId=subnet-xxxxxxxx,NameValue=ahoaho"

大きな工夫とかありませんが…

  • 動的な変わりそうなパラメータに関して -p で実行時に渡せるようにしている
  • 尚、-p で指定出来るのは Parameters で指定している部分だけのようなので注意が必要
  • SecurityGroupIds はハッシュで値を持たせる必要があるのでちょっと特殊な定義([_{Ref "SecurityGroupIds"}])になっている
  • Parameters で指定出来るパラメータは CloudFormation の各リソース定義やオリジナルの定義を指定可能
  • 例えば SubnetId は CloudFormation の定義、NameValue はオリジナルの定義

上記を実行すると…

AWS CloudFormation kumogata 実行結果

暫くすると指定したパラメータでインスタンスが起動してくれちゃいますがな。

この方法で 6 台をセットアップするのに 10 分。トイレに行ってお茶のんでゴルフの素振りを 5 回すればインスタンスは起動して Apache も起動しているのでブラウザから動作確認出来ます!

こ、これは…

CloudFormation + kumogata こ、これはまさに 2014 年ベストオヴインフラツールの一つにノミネートされそうな勢いです。

元記事はこちらです。
【米俵餅の AWS 記念日(2)】たくさんのインスタンスを起動したいから、今日は CloudFormation 記念日(2)〜いい日 kumogata 〜