terraform cloudで初めるAWS その4: cloud-init編
これはシリーズ化する予定なので続きは←リンクからどうぞ。
ちなみに最低限AWSでEC2を起動してSSHした事程度は事ある人向けの記事です
前回まで
ボリュームをアタッチしてファイルシステムを作ってmountしてみる所までやりました。ただ、マウントの自動化は出来ていないという所までやりました。
cloud-initとは
Linux用の構成スクリプトです。今は提供されたAMIイメージを適当に起動していますがこれが起動した後に最低限の構成を行うのがcloud-initであります。
もともとEC2用に開発されたものではありますが実は今は汎用的に使う事ができるそーです(他で使ったことない)、が、やっぱりEC2で開発されたものなのでEC2では使えるぞって事になります。
ためしに適当に作成したEC2インスタンスにSSHして以下のコマンドを確認してみましょう。
1$ sudo cloud-init --version
2cloud-init 0.7.7
このように全てのEC2イメージはこれで構成されているはずで、つまりコマンドが入ってたりこの仕組みが使えるという事になります。
ちなみにオフィシャルドキュメントはここです
https://cloudinit.readthedocs.io/en/latest/index.html
cloud.cfgを見てみよう
Debianの場合なぜ「admin」なんていうユーザが作成されているかがここで理解できてきます。
/etc/cloud/cloud.cfg(抜粋)
1# System and/or distro specific settings
2# (not accessible to handlers/transforms)
3system_info:
4 # This will affect which distro class gets used
5 distro: debian
6 # Default user name + that default users groups (if added/used)
7 default_user:
8 name: admin
9 sudo: ALL=(ALL) NOPASSWD:ALL
10 shell: /bin/bash
11 lock_passwd: True
12 gecos: Debian
13 groups: [adm, audio, cdrom, dialout, dip, floppy, netdev, plugdev, sudo, video]
14 sudo: ["ALL=(ALL) NOPASSWD:ALL"]
15 shell: /bin/bash
なるほど、内容はわかったがどうやって変更する?
まあ問題はこれでしょう。これはuser_dataという仕組みで注入する事ができます
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html
細かい設定を読むのは酷なので問題の「terraformから注入」を行います。
その前に現在のEC2関連の設定を見ておきましょう。
1resource "aws_instance" "web" {
2 instance_type = "t2.micro"
3 ami = "ami-0662319323823ba88" # jessie
4 subnet_id = aws_subnet.pub.id
5 key_name = "xxxxxxxx"
6 tags = {
7 Name = local.workspace
8 }
9}
ここに
1 user_data = data.template_cloudinit_config.web.rendered
2 tags = {
3 Name = local.workspace
4 }
こんなのを入れました。要するにuser_data
って奴です。見ての通りdata
(data source)で定義されていますんで、実物のデータを用意する必要があります。
1data "template_cloudinit_config" "web" {
2 gzip = true
3 base64_encode = true
4
5 part {
6 content_type = "text/cloud-config"
7 content = templatefile("cloud-init.yml", {})
8 }
9}
この設定を見るとわかるように
1 content = templatefile("cloud-init.yml", {})
ここからcloud-init.ymlというファイルを用意する必要があるのがわかります。これを作って注入すればよさそうですね。 ,{} の部分は引数を渡せるのですが、今回は使いません
ディスクをマウントする
cloud-init.ymlですが、これは実はつきつめると結構奥の深いものになっています。なので今回はディスクのマウントのみに絞って解説します。とはいえ、それだけだと寂しいのでtimezoneも設定してみます。
cloud-init.yml
1#cloud-config
2
3timezone: "Asia/Tokyo"
4
5mounts:
6 - [/dev/xvdf1, /data, ext4, "rw,noatime", "0", "0"]
このようなyamlファイルを配置してcommitします。
これでterraform cloudからapplyします。するとマシンは作り直しになると思われます。
なおボリュームのデタッチはなんか結構失敗しますんでそういう場合は手動でインスタンスを終了してください。
これで起動しadminとかでsshして以下のコマンドを起動してみると…
1$ date
2Tue Oct 13 15:34:10 JST 2020
JSTになっていますが
1$ df -h
2Filesystem Size Used Avail Use% Mounted on
3/dev/xvda2 7.8G 1.1G 6.4G 14% /
4udev 10M 0 10M 0% /dev
5tmpfs 200M 4.2M 196M 3% /run
6tmpfs 500M 0 500M 0% /dev/shm
7tmpfs 5.0M 0 5.0M 0% /run/lock
8tmpfs 500M 0 500M 0% /sys/fs/cgroup
ボリュームはマウントされていません。しかし /etc/fstab をみると
1$ cat /etc/fstab
2UUID=711e1ec2-2a36-4405-bf46-44b43cfee42e / ext4 defaults 1 1
3/dev/xvdf1 /data ext4 rw,noatime,comment=cloudconfig 0 0
このようなエントリはみえます。手で
1$ sudo mount -a
とかすればマウントできて、ディスクの容量などがdf
コマンドで見る事とかできますが。
1$ df -h
2Filesystem Size Used Avail Use% Mounted on
3/dev/xvda2 7.8G 1.1G 6.4G 14% /
4udev 10M 0 10M 0% /dev
5tmpfs 200M 4.2M 196M 3% /run
6tmpfs 500M 0 500M 0% /dev/shm
7tmpfs 5.0M 0 5.0M 0% /run/lock
8tmpfs 500M 0 500M 0% /sys/fs/cgroup
9/dev/xvdf1 20G 44M 20G 1% /data
んー、なんかイマイチなので再起動させておきます。この辺もうちょっといい方法があるやもしれません。 いずれにせよ、タイムゾーンなんかを変更した場合は再起動させておくのが無難らしいという話はあります。
再起動する場合power_state
というエントリで実行するからこれを追記します。
1power_state:
2 mode: reboot
3 message: "Rebooting ..."
4 timeout: 30
これを適当なclout-init.ymlの中に書いておきます。なお、clout-init.ymlは書いた順番に実行されるわけではないので注意ください。今回はこの辺掘り下げません。マシンを破壊して戻した時に正しく表示されていればokです。
なお、/var/log/cloud-init.logに
1Oct 13 07:02:23 ip-192-168-1-236 [CLOUDINIT] cc_power_state_change.py[DEBUG]: After pid 411 ends, will execute: shutdown -r now Rebooting ...
とか表示されていると思います。興味があればどうぞ。
ちなみに
cloud-initもガッツリ書けばそこそこチューニングできますが、限界もあります。
冒頭
Linux用の構成スクリプトです。今は提供されたAMIイメージを適当に起動していますがこれが起動した後に最低限の構成を行うのがcloud-initであります。
と書きましたが、起動する前に仕掛けておかないといけないものもあるので、これはイメージを作成する事になったりするんですが、そこまでは今回やりません、多分。
apache2 + libapache2-mod-php5 を入れてみる
debian jessieを使ってる場合なんですが、こいつはちょっとクセのあるイメージになっており(なんせ古いすぎる)、パッケージを追加するにはいろいろと面倒くささがあります。仕方がないのでruncmd
で構成してみました。
なお、これはYAMLファイルの先頭に書こうがどこに書こうが最後の方に実行されます。何故かはここでは書きませんが
1runcmd:
2 - [ sh, -c, echo "setting up apt" ]
3 - [ rm, "/etc/apt/sources.list.d/backports.list"]
4 - [ apt, "update"]
5 - [ apt, "upgrade", "-y"]
6 - [ apt, "install", "-y", "libapache2-mod-php5"]
さらにwebサーバということなので80番を空けときます。
ただし、単品のテスト用という事で、ロードバランサ経由でhttp/httpsにアクセスさせる時は、まあ考えてみてください。
1resource "aws_security_group" "web" {
2 vpc_id = aws_vpc.vpc.id
3 name = "webfront"
4 description = "Allow http"
5 ingress {
6 from_port = 80
7 to_port = 80
8 protocol = "tcp"
9 cidr_blocks = ["0.0.0.0/0"]
10 }
11}
12
13resource "aws_instance" "web" {
14 instance_type = "t2.micro"
15 ami = "ami-0662319323823ba88" # jessie
16 subnet_id = aws_subnet.pub.id
17 key_name = "xxxxxx"
18 user_data = data.template_cloudinit_config.web.rendered
19
20 # ↓ このへん
21 vpc_security_group_ids = [
22 aws_security_group.web.id,
23 aws_vpc.vpc.default_security_group_id
24 ]
25
26 tags = {
27 Name = local.workspace
28 }
29}
ここまでで
clount-initを使った簡単な構成管理でボリュームをmountできるようにしました。
また、かなり強引にwebサーバを起動できるようにしました。
まあこれで概ね使い出せるんですが、次回はそうっすねえ、、DBサーバですかね?
よろしくお願いします。