【AWS】CloudFormationのお勉強_サンプルテンプレートから"Resource"を読 | 瀬戸内の雲のように

【AWS】CloudFormationのお勉強_サンプルテンプレートから"Resource"を読み解く

Posted: 2017-12-25


スポンサーリンク

目次

背景

今更ですが、CloudFormationのお勉強をしています。CloudFormationは使いこなせばすごく便利だと(想像で)考えているのですが、実際に触ると難しいので敬遠してました。
しかしそろそろ使えるようにならねば!と一念発起し勉強してみました。


(前提)CloudFormationとは

AWSが提供する機能の一つです。テンプレートと言う「リソースの集合体」を管理できる機能です。(リソースとは、EC2インスタンスであったりElasticIPであったりSecurityGroupであったり、AWSが提供するサービス一つ一つのことです)
こいつを使うと、自動デプロイが容易になったりオートスケールさせたりといい事ずくめなのですが、使うのが難しいです。


今回の内容

AWSが提供する「Ruby On Rails stuck」というサンプルテンプレートから、インスタンス構築に必要な"Resource"というパラメータを読み解いてみます

必要なパラメータ

まず1階層目のパラメータを読み解くと

$ cat template.json | jq ". | keys"
[
  "AWSTemplateFormatVersion",
  "Description",
  "Mappings",
  "Outputs",
  "Parameters",
  "Resources"
]

それぞれ、以下のような役割です。重要な順に説明します。

  • Resources: リソースの構築に必要なパラメータ(後述)
  • Parameters: 構築時に設定する可変パラメータ。入力できる項目はResourcesで定義
  • Outputs: 構築完了時に出力する内容(例: CF内で確保したElasticIPとか)
  • Mappings: 可変パラメータに対応して他のパラメータも設定する場合のリスト
  • Description: 説明
  • AWSTemplateFormatVersion: 書式のバージョン(ほぼ固定値と考えてOK)

では本題のResourcesに入ろうと思います。


Resources

管理するリソースを定義する部分。このテンプレートで言うとEC2インスタンスセキュリティグループの2つが出てきます。

$ cat template.json | jq ".Resources | keys"
[
  "WebServer",
  "WebServerSecurityGroup"
]

次にこのWebServerの中身を見ていきます。

$ cat template.json | jq ".Resources.WebServer | keys"
[
  "CreationPolicy",
  "Metadata",
  "Properties",
  "Type"
]

この4つが定義されています。この中身をみてみましょう。


CreationPolicy
このテンプレートではタイムアウト値が定義されています。

$ cat template.json | jq ".Resources.WebServer.CreationPolicy"
{
  "ResourceSignal": {
    "Timeout": "PT30M"
  }
}



Type
リソースのタイプが定義されています。なので、ここにはEC2インスタンスであることが書かれています。

$ cat template.json | jq ".Resources.WebServer.Type"
"AWS::EC2::Instance"



Properties
インスタンス作成に必要なパラメータが定義されています。

$ cat template.json | jq ".Resources.WebServer.Properties | keys"
[
  "ImageId",
  "InstanceType",
  "KeyName",
  "SecurityGroups",
  "UserData"
]

もう少し詳細に見てみましょう

$ cat template.json | jq ".Resources.WebServer.Properties "
{
  "ImageId": {
    "Fn::FindInMap": [
      "AWSRegionArch2AMI",
      {
        "Ref": "AWS::Region"
      },
      {
        "Fn::FindInMap": [
          "AWSInstanceType2Arch",
          {
            "Ref": "InstanceType"
          },
          "Arch"
        ]
      }
    ]
  },
  "InstanceType": {
    "Ref": "InstanceType"
  },
  "SecurityGroups": [
    {
      "Ref": "WebServerSecurityGroup"
    }
  ],
  "KeyName": {
    "Ref": "KeyName"
  },
  "UserData": {
    "Fn::Base64": {
      "Fn::Join": [
        "",
        [
          "#!/bin/bash -xe\n",
          "yum update -y aws-cfn-bootstrap\n",
          "/opt/aws/bin/cfn-init -v ",
          "         --stack ",
          {
            "Ref": "AWS::StackId"
          },
          "         --resource WebServer ",
          "         --configsets full_install ",
          "         --region ",
          {
            "Ref": "AWS::Region"
          },
          "\n",
          "/opt/aws/bin/cfn-signal -e $? ",
          "         --stack ",
          {
            "Ref": "AWS::StackId"
          },
          "         --resource WebServer ",
          "         --region ",
          {
            "Ref": "AWS::Region"
          },
          "\n"
        ]
      ]
    }
  }
}

インスタンスのイメージIDなどが定義されています。ここで定義された情報を元にインスタンスはデプロイされるということです。


metadata
ここには初期設定の内容が定義されています。

$ cat template.json | jq ".Resources.WebServer.Metadata | keys"
[
  "AWS::CloudFormation::Init"
]

$ cat template.json | jq '.Resources.WebServer.Metadata."AWS::CloudFormation::Init" | keys'
[
  "configSets",
  "configure_mysql",
  "install_application",
  "install_cfn",
  "install_mysql",
  "install_ruby_2_3_1"
]

このようになっています。このconfigSetsに設定作業一覧が定義されており、それ以降に具体的な作業内容(コマンド)が定義されています。
ここではDBのセットアップなどの作業が書かれています。

$ cat template.json | jq '.Resources.WebServer.Metadata."AWS::CloudFormation::Init".configSets'
{
  "full_install": [
    "install_cfn",
    "install_ruby_2_3_1",
    "install_mysql",
    "configure_mysql",
    "install_application"
  ]
}

$ cat template.json | jq '.Resources.WebServer.Metadata."AWS::CloudFormation::Init".configure_mysql'
{
  "commands": {
    "01_set_mysql_root_password": {
      "command": {
        "Fn::Join": [
          "",
          [
            "mysqladmin -u root password '",
            {
              "Ref": "DBRootPassword"
            },
            "'"
          ]
        ]
      },
      "test": {
        "Fn::Join": [
          "",
          [
            "$(mysql ",
            {
              "Ref": "DBName"
            },
            " -u root --password='",
            {
              "Ref": "DBRootPassword"
            },
            "' >/dev/null 2>&1 </dev/null); (( $? != 0 ))"
          ]
        ]
      }
    },
    "02_create_database": {
      "command": {
        "Fn::Join": [
          "",
          [
            "mysql -u root --password='",
            {
              "Ref": "DBRootPassword"
            },
            "' < /tmp/setup.mysql"
          ]
        ]
      },
      "test": {
        "Fn::Join": [
          "",
          [
            "$(mysql ",
            {
              "Ref": "DBName"
            },
            " -u root --password='",
            {
              "Ref": "DBRootPassword"
            },
            "' >/dev/null 2>&1 </dev/null); (( $? != 0 ))"
          ]
        ]
      }
    },
    "03_cleanup": {
      "command": "rm /tmp/setup.mysql"
    }
  }
}




こんな感じになります。
この内容は初歩の初歩ですが、これさえ理解すればとりあえずインスタンスを立てるということはできそうです。


スポンサーリンク




コメント一覧


コメントを投稿する


お名前


コメント内容





TOP back