この記事は Ansible Advent Calendar 2021 2日目の記事になります。
Ansible Moleculeでテストを実行する時にテスト対象になるAWS EC2のゴールデンイメージの作成方法について解説します。
今回はPackerを用いてAWS EC2 AMI(Amazon machine image)へVMイメージを登録するまでになります。
なぜテスト環境用のVMイメージを作成、登録するのか?
- CIの実行時間を短縮するため
- コードの記述量を減らしメンテナンスしやすくする
これらの理由が考えられます。
CIの実行時間を短くする
Moleculeの機能から言えばMolecule実行時にMoleculeのシナリオprepareなどでテスト環境をセットアップする事は可能です。しかし例えば毎回OSをアップデート、再起動するなどの処理をしているとCIの実行時間が長くなってしまいます。
コードの記述量を減らしメンテナンスしやすくする
テスト環境用のセットアップ処理(いわゆるbootstrap)を一箇所で管理する事によりメンテナンスコストが減らせます。例えばAnsible Role / Playbookでリポジトリがそれぞれ分かれていてなおかつそれぞれのリポジトリでmolecule/scenarios/prepare.yml
が管理されている場合prepare.ymlに変更が生じると全てのリポジトリに対して修正を行う必要が出てきます。これは相当悪手なので絶対に避けます。
ゴールデンイメージの仕様
ゴールデンイメージの設計図となるPackerの設定ファイルには以下を含めます
- イメージのアップデート処理
- rootのパスワードの設定
- cloud-initの設定の変更
rootパスワードの設定
これはEC2でシリアルコンソール接続を有効にするために必要になります。また注意点としてインスタンスタイプはNitroシステムで利用できるものを選択します。サンプルコードのインスタンスタイプではシリアルコンソール接続は利用できません。利用可能なインスタンスは以下になります。
仮想化
A1、C5、C5a、C5ad、C5d、C5n、C6a、C6g、C6gd、C6gn、C6i、D3、D3en、G4、
G4ad、G5、I3en、I4i、Inf1、M5、M5a、M5ad、M5d、M5dn、M5n、M5zn、M6a、
M6g、M6gd、M6i、p3dn.24xlarge、P4、R5、R5a、R5ad、R5b、R5d、R5dn、
R5n、R6g、R6gd、R6i、T3、T3a、T4g、u-3tb1.56xlarge、u-6tb1.56xlarge、
u-6tb1.112xlarge、u-9tb1.112xlarge、u-12tb1.112xlarge、X2gd、X2idn、
X2iedn、X2iezn、z1d
ベアメタル
a1.metal、c5.metal、c5d.metal、c5n.metal、c6a.metal、c6g.metal、
c6gd.metal、c6i.metal、g4dn.metal、i3.metal、i3en.metal、i4i.metal、
m5.metal、m5d.metal、m5dn.metal、m5n.metal、m5zn.metal、m6a.metal、
m6g.metal、m6gd.metal、m6i.metal、mac1.metal、r5.metal、r5b.metal、
r5d.metal、r5dn.metal、r5n.metal、r6g.metal、r6gd.metal、r6i.metal、
u-6tb1.metal、u-9tb1.metal、u-12tb1.metal、u-18tb1.metal、
u-24tb1.metal、x2gd.metal、x2idn.metal、x2iedn.metal、x2iezn.metal、
z1d.metal
cloud-initの設定変更
cloud-initはバージョンによってはホストキーを削除してSSH接続を無効にしてしまうバグが含まれる事がありあまり信頼できるライブラリではありません。この挙動を回避するため初期設定を変更しておきます。
イメージのビルドの頻度は?
Moleculeを実行する頻度によります。数ヶ月に一回程度なら手動で実行、ほぼ毎日ならcron等で実行します。
Packerのbuild.jsonのサンプル例(CentOS Stream 8)
{
"variables": {
"ami_name": "",
"aws_profile": "",
"aws_region": "",
"tag_name": ""
},
"builders": [{
"ami_name": "{{user `ami_name`}}",
"instance_type": "t2.medium",
"profile": "{{user `aws_profile`}}",
"region": "{{user `aws_region`}}",
"source_ami": "ami-06ee905d0566e92e7",
"ssh_username": "centos",
"tags": {
"Name": "{{user `tag_name`}}"
},
"type": "amazon-ebs"
}],
"provisioners": [
{
"inline": [
"sudo echo root | sudo passwd --stdin root"
],
"type": "shell"
},
{
"inline": [
"sudo dnf -y update"
],
"type": "shell"
},
{
"inline": [
"sudo sed -i -e \"s/ssh_genkeytypes: ~/ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']/\" /etc/cloud/cloud.cfg"
],
"type": "shell"
}
]
}