ハンズオン(簡易版): CFnテンプレート入門(EC2::VolumeAttachment)

事前作業2.5. ユーザーデータの更新 (EBS Format: handson-cli-cfn-ec2-VolumeAttachment-ssh_port-userdata)

手順の目的 [why]

ユーザーデータ名"handson-cli-cfn-ec2-VolumeAttachment-ssh_port-userdata"のファイルを更新します。

設定値の指定

設定値の指定

手順に必要な設定値を変数に格納をします。

1. ユーザーデータ用ディレクトリ

ユーザーデータ用ディレクトリを指定します。

変数の設定:

DIR_USER_DATA="${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment"

ディレクトリが存在することを確認します。

コマンド:

ls -d ${DIR_USER_DATA}

結果(例:存在する場合):

${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment

存在しない場合は作成します。

コマンド:

mkdir -p ${DIR_USER_DATA}

結果(例):

(出力なし)

2. ユーザーデータファイル名

ユーザーデータファイル名を指定します。

変数の設定:

USER_DATA_NAME='handson-cli-cfn-ec2-VolumeAttachment-ssh_port-userdata'

変数の設定:

FILE_USER_DATA="${DIR_USER_DATA}/${USER_DATA_NAME}.bash" \
  && echo ${FILE_USER_DATA}

結果(例):

${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment/handson-cli-cfn-ec2-VolumeAttachment-ssh_port-userdata.bash

3. デバイスファイル名

デバイスファイル名を指定します。

変数の設定:

DEVICE_FILE_NAME='sdh'

4. マウントポイント名

マウントポイント名を指定します。

変数の設定:

MOUNT_POINT_NAME='/mnt-handson-cli-ebs'

設定値の確認

各変数に正しい設定値が格納されていることを確認しながら保存します。

変数の確認:

cat << END

  # 1. DIR_USER_DATA:"${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment"
       DIR_USER_DATA="${DIR_USER_DATA}"
  # 2. FILE_USER_DATA:"${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment/handson-cli-cfn-ec2-VolumeAttachment-ssh_port-userdata.bash"
       FILE_USER_DATA="${FILE_USER_DATA}"
  # 3. DEVICE_FILE_NAME:"sdh"
       DEVICE_FILE_NAME="${DEVICE_FILE_NAME}"
  # 4. MOUNT_POINT_NAME:"/mnt-handson-cli-ebs"
       MOUNT_POINT_NAME="${MOUNT_POINT_NAME}"

END

下段の変数が入っていない、もしくは上段と同等の値が入っていない場合は、それぞれの手順番号に戻って変数の設定を行います。

処理の実行

ユーザーデータファイルを更新します。

変数の確認:

cat << END

  # FILE_USER_DATA:"${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment/handson-cli-cfn-ec2-VolumeAttachment-ssh_port-userdata.bash"
    FILE_USER_DATA="${FILE_USER_DATA}"
  # DEVICE_FILE_NAME:"sdh"
    DEVICE_FILE_NAME="${DEVICE_FILE_NAME}"
  # MOUNT_POINT_NAME:"/mnt-handson-cli-ebs"
    MOUNT_POINT_NAME="${MOUNT_POINT_NAME}"

END

コマンド:

cat << EOF >> ${FILE_USER_DATA}

#
# disk format (${DEVICE_FILE_NAME})
#

DEVICE_FILE_NAME="${DEVICE_FILE_NAME}"
MOUNT_POINT_NAME="${MOUNT_POINT_NAME}"
DISK_TYPE='xfs'
DISK_TARGET="/dev/\${DEVICE_FILE_NAME}"

# format disk
mkfs \\
   -t \${DISK_TYPE} \\
   \${DISK_TARGET}

# make mount point
mkdir \${MOUNT_POINT_NAME}

# update fstab
cp /etc/fstab /etc/fstab.\$(date +%s)

DEVICE_LINK_NAME=\$( \\
  file -s \${DISK_TARGET} \\
  | sed "s/^.*\\\`//" \\
  | sed "s/'\$//" \\
)

DISK_UUID=\$( \\
  sudo blkid \\
    | grep /dev/\${DEVICE_LINK_NAME} \\
    | sed "s/^.*UUID=\"//" \\
    | sed "s/\".*\$//" \\
)

DISK_TYPE_TARGET=\$( \\
  sudo blkid \\
    | grep /dev/\${DEVICE_LINK_NAME} \\
    | sed "s/^.*TYPE=\"//" \\
    | sed "s/\".*\$//" \\
)

if [ ! \$( grep \${DISK_UUID} /etc/fstab ) ]; then
  sh -c "echo \"UUID=\${DISK_UUID}     \${MOUNT_POINT_NAME} \${DISK_TYPE_TARGET} defaults,nofail  0  2\" >> /etc/fstab"
fi

# mount disk
mount \${MOUNT_POINT_NAME}
chown ec2-user:ec2-user \${MOUNT_POINT_NAME}
EOF

cat ${FILE_USER_DATA}

結果(例):

#!/bin/bash

# configure sshd
cat << EOF >> /etc/ssh/sshd_config

Port 22022
EOF
systemctl restart sshd.service


# yum
yum update -y

#
# logs agent
#

readonly EC2_METADATA_SECOND='900'

readonly EC2_METADATA_TOKEN=$( \
  curl -s \
    -X PUT "http://169.254.169.254/latest/api/token" \
    -H "X-aws-ec2-metadata-token-ttl-seconds: ${EC2_METADATA_SECOND}" \
)
readonly EC2_METADATA_HEADER="X-aws-ec2-metadata-token: ${EC2_METADATA_TOKEN}"

readonly EC2_REGION_NAME=$( \
  curl -s -H "${EC2_METADATA_HEADER}" \
    http://169.254.169.254/latest/meta-data/placement/availability-zone \
  | sed -e 's/[a-z]*$//' \
)

# install cloudwatch agent
readonly URL_DOWNLOAD_LINK="https://s3.${EC2_REGION_NAME}.amazonaws.com/amazoncloudwatch-agent-${EC2_REGION_NAME}/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm"

cd /tmp/
wget ${URL_DOWNLOAD_LINK}
rpm -U ./amazon-cloudwatch-agent.rpm

# setup cloudwatch agent
readonly LOGS_CONF='/opt/aws/amazon-cloudwatch-agent/etc/logs.conf'

# logs.conf
cat << EOF > ${LOGS_CONF}
{
  "agent": {
    "logfile": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log"
  },
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/var/log/secure",
            "log_group_name": "/var/log/secure",
            "timezone": "UTC"
          }
        ]
      }
    },
    "log_stream_name": "{instance_id}",
    "force_flush_interval" : 15
  }
}
EOF

# start cloudwatch agent
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config \
  -m ec2 \
  -c file:${LOGS_CONF} \
  -s

#
# disk format (sdh)
#

DEVICE_FILE_NAME="sdh"
MOUNT_POINT_NAME="/mnt-handson-cli-ebs"
DISK_TYPE='xfs'
DISK_TARGET="/dev/${DEVICE_FILE_NAME}"

# format disk
mkfs \
   -t ${DISK_TYPE} \
   ${DISK_TARGET}

# make mount point
mkdir ${MOUNT_POINT_NAME}

# update fstab
cp /etc/fstab /etc/fstab.$(date +%s)

DEVICE_LINK_NAME=$( \
  file -s ${DISK_TARGET} \
  | sed "s/^.*\`//" \
  | sed "s/'$//" \
)

DISK_UUID=$( \
  sudo blkid \
    | grep /dev/${DEVICE_LINK_NAME} \
    | sed "s/^.*UUID=\"//" \
    | sed "s/\".*$//" \
)

DISK_TYPE_TARGET=$( \
  sudo blkid \
    | grep /dev/${DEVICE_LINK_NAME} \
    | sed "s/^.*TYPE=\"//" \
    | sed "s/\".*$//" \
)

if [ ! $( grep ${DISK_UUID} /etc/fstab ) ]; then
  sh -c "echo \"UUID=${DISK_UUID}     ${MOUNT_POINT_NAME} ${DISK_TYPE_TARGET} defaults,nofail  0  2\" >> /etc/fstab"
fi

# mount disk
mount ${MOUNT_POINT_NAME}
chown ec2-user:ec2-user ${MOUNT_POINT_NAME}

完了確認

本手順の主処理は、以下の完了条件を満たしたときに成功したものとします。

完了条件1: ユーザーデータファイル名"${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment/handson-cli-cfn-ec2-VolumeAttachment-ssh_port-userdata.bash"が存在する。

「ユーザーデータファイル名"${HOME}/environment/conf-handson-cli-cfn-ec2-VolumeAttachment/handson-cli-cfn-ec2-VolumeAttachment-ssh_port-userdata.bash"が存在する。」ことを確認します。

コマンド:

cat ${FILE_USER_DATA} \
  | grep "^# disk format (${DEVICE_FILE_NAME})" -A 45

結果(例):

# disk format (sdh)
#

(略)

手順の完了