EC2 Linuxを起動するたびに同じコマンドを実行させる

2021.10.18

cloud-init はデフォルトでは初回起動時のみユーザーデータを実行

Amazon EC2のAmazon Linux 2インスタンス起動時に特定の処理を走らせたい場合、 cloud-init のユーザーデータを記述することで実現できます。

例えば、起動時にLAMP一式をインストールしたい場合は以下の通りです。

#!/bin/bash
yum update -y
amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2
yum install -y httpd mariadb-server
systemctl start httpd
systemctl enable httpd
usermod -a -G apache ec2-user
chown -R ec2-user:apache /var/www
chmod 2775 /var/www
find /var/www -type d -exec chmod 2775 {} \;
find /var/www -type f -exec chmod 0664 {} \;
echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php

ただし、この記述方式の場合、ユーザーデータはインスタンス作成時の1回しか実行されません

cloud-init を起動のたびに実行させる

再起動、停止→起動など、インスタンス起動の度にコマンド実行したい場合、MIME マルチパートファイルで記述すると実現できます。

Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
/bin/echo "Hello World" >> /tmp/testfile.txt
--//--

ポイントは以下です。

  • scripts-user パラメーターに 頻度の always を指定
  • ユーザーデータ向けファイルには Content-Type: text/x-shellscript; を指定
  • ユーザーデータ向けファイルにはシェルスクリプトを記述

なお、既存インスタンスに対してユーザーデータを変更する場合、インスタンスを停止させた上で「アクション→インスタンスの設定→ユーザーデータを変更」から変更してください。

EC2内の cloud-init ファイルを見る

cloud-init の設定ファイルは、EC2 内の /var/lib/cloud/instances/i-インスタンスID 以下に展開されます。

$ pwd
/var/lib/cloud/instances/i-06bd137d0b020fae3

$ ls -F1
cloud-config.txt
datasource
handlers/
obj.pkl
scripts/
sem/
user-data.txt
user-data.txt.i
vendor-data.txt
vendor-data.txt.i

$ cat user-data.txt
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
/bin/echo "Hello World" >> /tmp/testfile.txt
--//--

$ cat cloud-config.txt
#cloud-config

# from 1 files
# cloud-config.txt

---
cloud_final_modules:
-   - scripts-user
    - always
...

$ cat scripts/userdata.txt
#!/bin/bash
/bin/echo "Hello World" >> /tmp/testfile.txt

EC2起動のたびにセキュリティアップデートを実行

EC2 Linux 初回起動時には、 cloud-init.log からわかるように、yum のセキュリティアップグレードが走っています。

Oct 17 13:20:52 cloud-init[981]: util.py[DEBUG]: Running command ['yum', '-t', '-y', '--exclude=kernel', '--exclude=nvidia*', '--exclude=cuda*', '--security', '--sec-severity=critical', '--sec-severity=important
', 'upgrade'] with allowed return codes [0] (shell=False, capture=False)

いつもは停止させているEC2インスタンスに対して、起動のたびに本処理を実行したい場合、上述スクリプトの

#!/bin/bash
/bin/echo "Hello World" >> /tmp/testfile.txt

の部分を

#!/bin/bash
yum -t -y --exclude=kernel --exclude=nvidia* --exclude=cuda* --security --sec-severity=critical --sec-severity=important upgrade

と変更します。

起動時に YUM セキュリティアップデートの実行ログを確認できるようになります。

/var/log/messages

Oct 17 13:25:33 ip-172-31-41-149 cloud-init: Cloud-init v. 19.3-44.amzn2 running 'modules:final' at Sun, 17 Oct 2021 10:25:33 +0000. Up 10.16 seconds.
...
Oct 17 13:25:39 ip-172-31-41-149 cloud-init: No packages needed for security; 14 packages available
Oct 17 13:25:39 ip-172-31-41-149 cloud-init: Resolving Dependencies

なお、運用に組み込みながらより安全にパッチ適用をしたい場合は、 AWS Systems Manager Patch Manager の利用をご検討ください。

参考