LoginSignup
0

More than 1 year has passed since last update.

PackerでMoleculeテスト環境用のAWS EC2ゴールデンイメージを作成する

Last updated at Posted at 2021-12-26

この記事は 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)

build.json
{
  "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"
    }
  ]
}

参考サイト

今回の記事のサンプルになるGitHubリポジトリ

シリアルコンソール接続とは

AWS Nitro systemとは

cloud-initのバグについて

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
What you can do with signing up
0