ちょっと話題の記事

Amazon Linuxのcloud-init Tips集

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

はじめに

皆さん、User-Dataを使っていますか?複数のEC2に同様の設定を適用してLaunchしたい時には便利な機能です。

このUser-Dataにはシェルスクリプトを直接書くか、あるいはcloud-init形式で記載することが出来ます。これは1行目が"#!"で始まっていればシェルスクリプト、"#cloud-config"で始まっていればcloud-init形式として処理されます。なおAmazon Linuxに導入されているcloud-initは元々のcloud-initをカスタマイズしたものであり、独自拡張がされていたり、一部のディレクティブが使えなかったりするので注意が必要です。

今回、このcloud-initを使った初期設定を色々と調べたので、まとめてみました。

Tips

設定及びログの確認

User-Dataで設定した内容は、/var/lib/cloud/instance/user-data.txtに書き込まれます。

$ sudo cat /var/lib/cloud/instance/user-data.txt
#cloud-config
repo_update: true
repo_upgrade: all
...

また、実行されたログは/var/log/cloud-init.logに書き込まれます。

$ sudo cat /var/log/cloud-init.log
Aug 21 07:32:35 cloud-init[1486]: util.py[DEBUG]: Cloud-init v. 0.7.2 running 'init-local' at Thu, 21 Aug 2014 07:32:35 +0000. Up 23.25 seconds.
Aug 21 07:32:35 cloud-init[1486]: util.py[DEBUG]: Writing to /var/log/cloud-init.log - ab: [420] 0 bytes
...

repo_update, repo_upgrade

repo_updateによってローカルにキャッシュされているパッケージリストがリポジトリと同期され最新の状態になり、repo_upgradeによって実際にパッケージの更新が行われます。repo_upgradeの引数は以下のとおりです。

  • all ... 全てのパッケージを更新します。
  • security ... Security Updateが適用されます。
  • none ... 更新しません。
repo_update: true
repo_upgrade: all

更新の結果は/var/log/yum.logで確認できます。

$ sudo cat /var/log/yum.log
Aug 21 07:32:59 Updated: libuuid-2.23.2-16.22.amzn1.x86_64
Aug 21 07:32:59 Updated: 1:openssl-1.0.1i-1.78.amzn1.x86_64
Aug 21 07:32:59 Updated: nspr-4.10.4-1.22.amzn1.x86_64
...

yum_repos

yumリポジトリを追加します。以下の例だとepel testingを追加しています。enabledfalseなので無効の状態で追加されますが、最初から有効にしたい場合はtrueとして下さい。

yum_repos:
    epel:
        baseurl: http://download.fedoraproject.org/pub/epel/testing/6/$basearch
        enabled: false
        failovermethod: priority
        gpgcheck: true
        name: Extra Packages for Enterprise Linux 6 - $basearch - testing

yumリポジトリを追加すると/etc/yum.repos.d/下にリポジトリファイルが追加されます。yum repolist allコマンドでリポジトリが追加されていることが確認できます。

$ yum repolist all

読み込んだプラグイン:priorities, update-motd, upgrade-helper
リポジトリー ID                                  リポジトリー名                                                                        状態
amzn-main/latest                                 amzn-main-Base                                                                        有効: 4,801
amzn-main-debuginfo/latest                       amzn-main-debuginfo                                                                   無効
amzn-nosrc/latest                                amzn-nosrc-Base                                                                       無効
amzn-preview/latest                              amzn-preview-Base                                                                     無効
amzn-preview-debuginfo/latest                    amzn-preview-debuginfo                                                                無効
amzn-updates/latest                              amzn-updates-Base                                                                     有効: 1,361
amzn-updates-debuginfo/latest                    amzn-updates-debuginfo                                                                無効
epel/x86_64                                      Extra Packages for Enterprise Linux 6 - x86_64                                        無効
epel-debuginfo/x86_64                            Extra Packages for Enterprise Linux 6 - x86_64 - Debug                                無効
epel-source/x86_64                               Extra Packages for Enterprise Linux 6 - x86_64 - Source                               無効
epel-testing/x86_64                              Extra Packages for Enterprise Linux 6 - Testing - x86_64                              無効
epel-testing-debuginfo/x86_64                    Extra Packages for Enterprise Linux 6 - Testing - x86_64 - Debug                      無効
epel-testing-source/x86_64                       Extra Packages for Enterprise Linux 6 - Testing - x86_64 - Source                     無効
repolist: 6,162

packages

指定したパッケージをインストールします。

packages:
 - httpd
 - mod_ssl

runcmd

指定したコマンドを実行します。

runcmd:
 - service httpd start
 - chkconfig httpd on

write_files

ファイルの書き込みを行います。以下の例ではログイン時のバナーを変更しています。

write_files:
 - content: |
      #!/bin/sh
      version=$(rpm -q --qf '%{version}' system-release)
      cat << EOF
           __     ______       __     ______    
          /\ \   /\  __ \     /\ \   /\  __ \   
         _\_\ \  \ \ \/\ \   _\_\ \  \ \ \/\ \  
        /\_____\  \ \_____\ /\_____\  \ \_____\ 
        \/_____/   \/_____/ \/_____/   \/_____/ 
      https://aws.amazon.com/amazon-linux-ami/$version-release-notes/
      EOF
   owner: root:root
   path: /etc/update-motd.d/30-banner
   permissions: '0766'

実際ログインするとこんな表示になります。

Last login: Thu Aug 21 07:38:55 2014 from hogehoge
     __     ______       __     ______
    /\ \   /\  __ \     /\ \   /\  __ \
   _\_\ \  \ \ \/\ \   _\_\ \  \ \ \/\ \
  /\_____\  \ \_____\ /\_____\  \ \_____\
  \/_____/   \/_____/ \/_____/   \/_____/
https://aws.amazon.com/amazon-linux-ami/2014.03-release-notes/
1 package(s) needed for security, out of 1 available
Run "sudo yum update" to apply all updates.

ちなみに上記のアスキーアートはTAAGを使って作りました。便利。

ssh_authorized_keys

ec2-userの.ssh/authorized_keysにSSH公開鍵を追加登録します。追加なのでLaunch時に指定したSSH鍵も登録されたままです。複数行の指定が出来るので一気に複数の公開鍵の登録が可能です。

ssh_authorized_keys:
  - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5ohFqg4aF7gGERHWToLY+yNxWGqbUifzVRXK6N1y4yjWjzwrlnivUSmf3lbEH+XXXXXXXXX/iBVnomZEuaSjk2w9IANxYXHTVaqP27OLXSPizKWyJBCdliRCnkVMLsDWWN9cBpHOTQokcnc2z43h0n41wyYeywqPg05rsa1mxzCZtcbiJKpsMcSMDy6SeLF/TuhzqpzolbMrAhM7QNFTVHjKMB4P+XXXXXXXXXXXXXX+V smokeymokey@hoge

disable_ec2_metadata

EC2のメタデータを提供するサービスに到達出来ないようになります。具体的にはEC2メタデータサービスへのブラックホールルートを作っています。

disable_ec2_metadata: true

netstatコマンドで確認すると、ブラックホールルートが設定されていることが分かります。

# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         172.31.0.1      0.0.0.0         UG        0 0          0 eth0
169.254.169.254 -               255.255.255.255 !H        - -          - -
169.254.169.254 0.0.0.0         255.255.255.255 UH        0 0          0 eth0
172.31.0.0      0.0.0.0         255.255.240.0   U         0 0          0 eth0

amznリポジトリのバージョン固定

Amazon Linux AMIの新しいバージョンがリリースされた時でも、amznリポジトリについては特定のバージョンを固定して参照したい場合があります。その場合の書き方は...以下の記事を参照して下さい!

おまけ

Amazon Linuxのデフォルトユーザであるec2-userが削除されたAMIをLaunchする場合、指定したSSH公開鍵がどこにも配置されず、ログイン出来なくなってしまいます。この場合以下のように記述することで、指定したユーザにSSH公開鍵を登録することが出来ます。

#cloud-config
user: maintenance
ssh_genkeytypes: [ rsa, dsa ]
cloud_init_modules:
 - ssh

また、ベースパッケージで使えるusersなどはAmazon Linuxバージョンでは使えないようで、runcmdを使ってユーザを登録をするしか無さそうでした。

まとめ

User-Dataは大規模展開時に基本的な設定を一気に行う時には大変便利な仕組みです。このように様々なディレクティブを組み合わせることで、一層作業の簡略化が計れるのでは無いでしょうか。