LoginSignup
30
28

More than 5 years have passed since last update.

cloud-init を使って自動的に hostname の変更と、Private Route53 への登録を行う

Last updated at Posted at 2015-08-11

やりたいこと: EC2 インスタンスの Name タグの値を取得し、hostname の変更と、Route53 への登録を cloud-init を使って起動時に自動的に行いたい。

前提条件

  1. AWS CLI がセットアップされていること。See http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html
  2. cloud init がインストールされていること (Amazon Linux ならデフォルト。CentOS の場合は yum install -y epel-release && yum install -y cloud-init)
  3. jq コマンドをインストールしていること。/usr/local/bin/jq においたものとする。

方針

AWS の User-Data を毎回設定するのがダルいので、使わない。スクリプトを仕込んだ状態でイメージを作っておき、以降自動で反映されるようにする

設定

/etc/cloud/cloud.cfg の hostname を更新する行をコメントアウトする。かき消されてしまうため。

cloud_init_modules:
  - migrator
  - bootcmd
  - write-files
  - growpart
  - resizefs
#  - set_hostname
#  - update_hostname
#  - update_etc_hosts
  - rsyslog
  - users-groups
  - ssh

bootcmd にスクリプトを仕込む。cfg に直接コマンドを書いても良いが、シェルスクリプトに分離したほうが開発が楽。

/etc/cloud/cloud.cfg.d/set_hostname.cfg
bootcmd:
  - /etc/cloud/cloud.cfg.d/set_hostname.sh

本体のシェルスクリプト。

/etc/cloud/cloud.cfg.d/set_hostname.sh
#!/bin/bash
jq=/usr/local/bin/jq
aws=/usr/local/bin/aws
hosted_zone_id=XXXXXXXX
domain=xxxx.internal

# /root/.aws/credentials および /root/.aws/config があれば不要
# export AWS_ACCESS_KEY_ID=xxxxx
# export AWS_SECRET_ACCESS_KEY=xxxx
# export AWS_DEFAULT_REGION=xxxxx

instance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
json=$($aws ec2 describe-instances --instance-ids $instance_id)
private_ip_address=$(echo $json | $jq -r '.Reservations[0].Instances[0].PrivateIpAddress')
hostname=$(echo $json | $jq -r '.Reservations[].Instances[].Tags[] | select(.Key=="Name").Value')

if [ -z "$hostname" ]; then
  echo "Name tag is not set" 1>&2
  exit 1
fi

# set hostname
if [ -z $(grep ^HOSTNAME /etc/sysconfig/network) ]; then
  echo "HOSTNAME=$hostname" >> /etc/sysconfig/network
else
  sed -i "s/^HOSTNAME.*$/HOSTNAME=$hostname/" /etc/sysconfig/network
fi
hostname $hostname
echo "\$ cat /etc/sysconfig/network"
cat /etc/sysconfig/network

# register to Route53
cat > /etc/cloud/cloud.cfg.d/set_hostname.json <<EOF
{
  "Comment": "${hostname}",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "${hostname}.${domain}",
        "Type": "A",
        "TTL" : 300 ,
        "ResourceRecords": [
         {
           "Value": "${private_ip_address}"
         }
        ]
      }
    }
  ]
}
EOF
echo "\$ cat /etc/cloud/cloud.cfg.d/set_hostname.json"
cat /etc/cloud/cloud.cfg.d/set_hostname.json
echo "\$ $aws route53 change-resource-record-sets --hosted-zone-id $hosted_zone_id --change-batch file:////etc/cloud/cloud.cfg.d/set_hostname.json"
$aws route53 change-resource-record-sets --hosted-zone-id $hosted_zone_id --change-batch file:////etc/cloud/cloud.cfg.d/set_hostname.json

ハマったメモ

ログインしてシェルからスクリプトを実行すると成功するのに、cloud-init で boot プロセス時に処理させると、aws ec2 describe-instances で

A client error (AuthFailure) occurred when calling the DescribeInstances operation: AWS was not able to validate the provided access credentials
Name tag is not set
2015-08-10 15:58:41,538 - util.py[WARNING]: Failed to run bootcmd module bootcmd
2015-08-10 15:58:41,540 - util.py[WARNING]: Running bootcmd (<module 'cloudinit.config.cc_bootcmd' from '/usr/lib/python2.6/site-packages/cloudinit/config/cc_bootcmd.pyc'>) failed

とエラーが出ていた。cf. https://gist.github.com/sonots/5d7b6ff1bff5b78cb2bb

これは時刻設定が間違っていて、hwclock がズレているせいだった。aws cli は時刻があっていないと認証に失敗する。エラーメッセージから全くわからなくてハマってた。

自分の場合は、/etc/sysconfig/clock と /etc/localtime は設定していたが、/etc/adjtime (勝手に設定されると書いている文献もある)の設定がズレており、時刻がズレてしまっていた。

参考

30
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
28