PackerでWindows Server 2019のAMIを作ってみた
はじめに
業務でAWS環境上の新規EC2インスタンスにActiveDirectoryを導入する機会がありました。
別業務でPackerに入門したばかりだったこともあり、いい機会なのでPackerでAMIを作成してみます。
本ブログの全体の流れについては、WindowsServer2016版の検証を行なっている下記ブログを参考にしています。
Packerとは?
Packerとは、皆さんご存知のTerraformで有名なHashiCorp社が提供しているマシンイメージ自動作成ツールです。
Terraformの会社のツールということもあり、AWSを含むさまざまな環境(GCP/Azule/Docker/Vagrantなど)のマシンイメージを作成することが可能です。
実際Packerってどういうことやってるの?な説明については、コンサルティング部が誇る作図大将チバユキの図解が超絶わかりやすかったのでこちらを参照ください。
実行環境
今回は下記のような環境からお届けします。
OS(ローカルPC)
% sw_vers ProductName: macOS ProductVersion: 11.6 BuildVersion: 20G165
Packerバージョン
% packer --version 1.7.6
事前準備
今回使用するテンプレートファイルはすべてGitHubにアップロードしておりますので、そちらをご利用ください。
h-ashisan/packer_winsrv2019_ad
上記リポジトリからPullするなどして、Packer実行に必要なテンプレートを準備します。
{ "variables": { "PROFILE": "default" }, "builders": [{ "type": "amazon-ebs", "profile": "{{user `PROFILE`}}", "region": "ap-northeast-1", "source_ami_filter": { "filters": { "name": "Windows_Server-2019-Japanese-Full-Base*" }, "owners": ["801119661308"], "most_recent": true }, "instance_type": "t3.micro", "ami_name": "windows-server-2019-{{isotime | clean_resource_name}}", "user_data_file": "{{template_dir}}/setup_winrm.txt", "tags": { "Base_AMI_ID": "{{ .SourceAMI }}", "Base_AMI_NAME": "{{ .SourceAMIName }}" }, "communicator": "winrm", "winrm_username": "Administrator" }], "provisioners": [{ "type": "powershell", "scripts": [ "{{template_dir}}/scripts/install_ad.ps1", "{{template_dir}}/scripts/sysprep_winsvr2019.ps1" ] }] }
テンプレートについての補足説明
今回記述したPackerテンプレートの説明を少ししだけします。
builders[]
EC2起動時のビルド設定をここで定義します。
builders[].source_ami_filter
builders[].most_recent
の値をtrue
指定することで、「Windows_Server-2019-Japanese-Full-Base*」でフィルタリングされた一覧から最新のものをSourceAMIとして選択することが可能です。
builders[].user_data_file
Packerではユーザーデータとして実行するコードをファイルからインポートすることが可能です。
今回はWinRMの設定変更を行い、実行ポリシーをBypassに変更する内容のファイルを外部ファイル(setup_winrm.txt)として使用しています。
CFnのテンプレートでよくあるユーザーデータへの直書き&テンプレート肥大化
を防げるのでとても便利だな、と思いました。
builders[].tags
タグにSourceAMIのIDとAMI名を付与します。
AMIにタグをつけたら何が嬉しいのか?はこのブログが参考になります。
provisioners[]
EC2の起動後のプロビジョニング設定をここで定義します。
今回のテンプレートでは「powershell」で下記2つのスクリプトを実行させます。
- ./scripts/install_ad.ps1
- ./scripts/sysprep_winsvr2019.ps1
前者のスクリプトではActive Directory
をインストールし、後者のスクリプトでSysgrep
を実行しています。
Sysgrep
はAMI等でWindowsを複製する時にSID重複防止のために新しいマシンIDを付与するツールです。
なんでSysgrep
をやらなきゃいけないの?を把握するために、下記ブログが参考になりました。
EC2を起動しインスタンス上でスクリプトを実行してくれるので、本番環境でやってみたら動かないとかそういった環境差異がなさそうというとことが嬉しいポイントだな、と思いました。
やってみた
実行
準備ができたら下記コマンドでPackerを実行しましょう
packer build build-ad-win2019.json
参考までに実行ログを添付しておきます。
→Builds finished.〜〜 ap-northeast-1: ami-XXXXXXXXXXXXXXX
と出力されたら実行完了です。
bash-3.2$ packer build build-ad-win2019.json amazon-ebs: output will be in this color. ==> amazon-ebs: Prevalidating any provided VPC information ==> amazon-ebs: Prevalidating AMI Name: windows-server-2019-2021-10-24T10-14-49Z amazon-ebs: Found Image ID: ami-XXXXXXXXXXXXXXX ==> amazon-ebs: Creating temporary keypair: packer_61753219-4dac-3afe-c973-5fc11ae1cd56 ==> amazon-ebs: Creating temporary security group for this instance: packer_6175321b-97db-e99a-3014-bac250581e10 ==> amazon-ebs: Authorizing access to port 5985 from [0.0.0.0/0] in the temporary security groups... ==> amazon-ebs: Launching a source AWS instance... ==> amazon-ebs: Adding tags to source instance amazon-ebs: Adding tag: "Name": "Packer Builder" amazon-ebs: Instance ID: i-XXXXXXXXXXXXXXX ==> amazon-ebs: Waiting for instance (i-XXXXXXXXXXXXXXX) to become ready... ==> amazon-ebs: Waiting for auto-generated password for instance... amazon-ebs: It is normal for this process to take up to 15 minutes, amazon-ebs: but it usually takes around 5. Please wait. amazon-ebs: amazon-ebs: Password retrieved! ==> amazon-ebs: Using WinRM communicator to connect: 54.238.87.249 ==> amazon-ebs: Waiting for WinRM to become available... amazon-ebs: WinRM connected. ==> amazon-ebs: Connected to WinRM! ==> amazon-ebs: Provisioning with Powershell... ==> amazon-ebs: Provisioning with powershell script: 【現在のディレクトリ】/scripts/install_ad.ps1 amazon-ebs: amazon-ebs: Success Restart Needed Exit Code Feature Result amazon-ebs: ------- -------------- --------- -------------- amazon-ebs: True No Success {Active Directory ドメイン サービス, グループ ポリシーの管理,... amazon-ebs: True No NoChangeNeeded {} ==> amazon-ebs: Provisioning with powershell script: 【現在のディレクトリ】/scripts/sysprep_winsvr2019.ps1 amazon-ebs: amazon-ebs: TaskPath TaskName State amazon-ebs: -------- -------- ----- amazon-ebs: \ Amazon Ec2 Launch - Instance I... Ready ==> amazon-ebs: Stopping the source instance... amazon-ebs: Stopping instance ==> amazon-ebs: Waiting for the instance to stop... ==> amazon-ebs: Creating AMI windows-server-2019-2021-10-24T10-14-49Z from instance i-XXXXXXXXXXXXXXX amazon-ebs: AMI: ami-XXXXXXXXXXXXXXX ==> amazon-ebs: Waiting for AMI to become ready... ==> amazon-ebs: Adding tags to AMI (ami-XXXXXXXXXXXXXXX)... ==> amazon-ebs: Tagging snapshot: snap-019aeff0d7f076bd2 ==> amazon-ebs: Creating AMI tags amazon-ebs: Adding tag: "Base_AMI_ID": "ami-XXXXXXXXXXXXXXX" amazon-ebs: Adding tag: "Base_AMI_NAME": "Windows_Server-2019-Japanese-Full-Base-2021.10.13" ==> amazon-ebs: Creating snapshot tags ==> amazon-ebs: Skipping Enable AMI deprecation... ==> amazon-ebs: Terminating the source AWS instance... ==> amazon-ebs: Cleaning up any extra volumes... ==> amazon-ebs: No volumes to clean up, skipping ==> amazon-ebs: Deleting temporary security group... ==> amazon-ebs: Deleting temporary keypair... Build 'amazon-ebs' finished after 9 minutes 51 seconds. ==> Wait completed after 9 minutes 51 seconds ==> Builds finished. The artifacts of successful builds are: --> amazon-ebs: AMIs were created: ap-northeast-1: ami-XXXXXXXXXXXXXXX
確認
作成したAMIからEC2インスタンスを起動し、正しくビルド、プロビジョニングできているか確認します。
- コンソール上からAMIが作成されていること
- AMIから作成したEC2インスタンスでActive Direcrotyがインストールされていること
まとめ
- Packerは初心者でも簡単にAMIを自動作成できるお手軽ツール
- IaCやメンテナンス性の観点で優れている
- 基本的に環境定義はjsonファイル1つでOK
- ビルド時に実行するユーザーデータについて、別ファイル管理可能
- プロビジョニング時に実行したいシェルについて、別ファイル管理可能
おわりに
今回はPackerを実際手を動かしてみて使ってみたことでPackerを使うことで何が嬉しいのか?を身をもって実感できたことがよかっです。
皆さんもぜひPackerを使ってみてください。