Ubuntuでcfn-initを利用する時の注意点

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、藤本です。

先日初めてUbuntuのEC2インスタンスに対して、CloudFormationヘルパースクリプトを利用した時にいくつかハマってしまったのでご紹介します。

前提知識

CloudFormationはEC2インスタンス構築時にOS内をカスタマイズするツールとして、CloudFormationヘルパースクリプトを用意しています。詳細はAWSのドキュメントや弊社の過去エントリをご参照ください。

環境

AMI : Ubuntu Server 14.04 LTS (HVM), SSD Volume Type - ami-a21529cc

easy_installよりもpipでインストールした方がいい

CloudFormationヘルパースクリプトはrpm、tar.gz、zip、msiで提供されています。Amazon Linuxであればデフォルトでインストールされていますし、CentOS、RHELであればrpmで簡単にインストールすることができます。

Ubuntuの場合はAWSドキュメントページを参照すると以下の2点が記載されています。

ただインストール方法がeasy_installか、pipかによって、cfn-hupのインストールパスが異なります。easy_installの場合、ヘルパースクリプトのバージョン情報が記載されるため、CloudFormationの使い回しを考慮する場合、バージョンによる影響を受けないpipを利用することを推奨します。

  • easy_installの場合
    • /usr/local/lib/python2.7/dist-packages/aws_cfn_bootstrap-1.4-py2.7.egg/init/ubuntu/cfn-hup
  • pipの場合
    • /usr/local/init/ubuntu/cfn-hup
  "Resources": {
    "Instance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
:
        "UserData": {"Fn::Base64": {"Fn::Join": ["", [
          "#!/bin/bash -xe\n",
          "apt-get update\n",
          "apt-get -y install python-pip\n",
          "pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
          "cp -a /usr/local/init/ubuntu/cfn-hup /etc/init.d/cfn-hup\n",
          "chmod u+x /etc/init.d/cfn-hup\n",

          "/usr/local/bin/cfn-init -v ",
          "         --stack ", {"Ref": "AWS::StackName"},
          "         --resource Instance ",
          "         --configsets setup ",
          "         --region ", {"Ref": "AWS::Region"}, "\n",

          "/usr/local/bin/cfn-signal -e $? ",
          "         --stack ", {"Ref": "AWS::StackName"},
          "         --resource Instance ",
          "         --region ", {"Ref": "AWS::Region"}, "\n"
        ] ]} }
      },
      "Metadata": {
        "AWS::CloudFormation::Init": {
:
          "initialize": {
            "files": {
              "/etc/cfn/cfn-hup.conf": {
                "content": {"Fn::Join": ["", [
                  "[main]\n",
                  "stack=", {"Ref": "AWS::StackId"}, "\n",
                  "region=", {"Ref": "AWS::Region"}, "\n"
                ]]},
                "mode"  : "000400",
                "owner": "root",
                "group": "root"
              },
              "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
                "content": {"Fn::Join": ["", [
                  "[cfn-auto-reloader-hook]\n",
                  "triggers=post.update\n",
                  "path=Resources.Instance.Metadata.AWS::CloudFormation::Init\n",
                  "action=/usr/local/bin/cfn-init -v ",
                  "         --stack ", {"Ref": "AWS::StackName"},
                  "         --resource Instance ",
                  "         --configsets setup ",
                  "         --region ", {"Ref": "AWS::Region"}, "\n"
                ]]},
                "mode"  : "000400",
                "owner": "root",
                "group": "root"
              }
            },
            "services": {
              "sysvinit": {
                "cfn-hup": {"enabled": "true", "ensureRunning": "true",
                              "files": ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]}
              }
            }
:

自動起動設定

cfn-initではServicesによりサービスの自動起動設定を管理することができます。

Ubuntu 14.04は自動起動の管理にinitctl/etc/rc*.d (update-rc.dinsserv)などいくつかの仕組みがあります。cfn-initのservicesキーではupdate-uc.dを利用します。そのため、initctlでサービスを管理したい場合、servicesキーでは実装することができません。filesキーやcommandsキーで実装する必要があります。

squidinitctlで管理されるため、以下のように記載をするとエラーとなる

:
  "Resources": {
    "Instance": {
      "Type": "AWS::EC2::Instance",
      "Metadata": {
        "AWS::CloudFormation::Init": {
:
          "setup": {
            "packages": {
              "apt" : {
                "squid": []
              }
            },
            "services": {
              "sysvinit": {
                "squid"  : { "enabled": "true", "ensureRunning": "true" }
              }
            }
          }
:

対話処理を求められる場合の回避方法

Ubuntuでパッケージのインストールや、パッケージのセットアップツールなどを実行する時に背景が紫色になって対話型の入力を求められるケースが多々あります。cfn-initのように人の手を介さず自動的に処理したい場合、対話処理を回避する必要があります。

そのような場合、環境変数DEBIAN_FRONTENDnoninteractiveをセットしてください。

:
  "Resources": {
    "Instance": {
      "Type": "AWS::EC2::Instance",
      "Metadata": {
        "AWS::CloudFormation::Init": {
:
          "command": {
              "command-noninteractive": {
                "command": "DEBIAN_FRONTEND=noninteractive apt-get -y install xxxxxxxx"
              }
            }
          }
        }
      },
:

まとめ

いかがでしたでしょうか?

Amazon Linuxと同じように使えると思っていたら何回もエラーとなって大変でした。。
同じようなことにハマった人の参考になれば幸いです。

参考URL