PackerでWindows Server 2016のAMIを作成してみた
おはようございます、加藤です。
業務でActive Directoryを使う必要があったのでPackerでAMIとして作成してみました。
Packerのインストール
使っている端末がMacなのでHomebrewでインストールしました。使用するPackerのバージョンは1.2.2です。
brew install packer packer --version # 1.2.2
作ったもの
今回作成した物をGitHubへアップしておきました。
kmd2kmd/packer-winsrv2016-on-aws: Windows Server 2016 に Active Directory をインストールしたAMIを作成する
説明
{ "builders": [{ "type": "amazon-ebs", "profile": "default", "region": "ap-northeast-1", "source_ami": "ami-07f2a061", "instance_type": "t2.large", "ami_name": "Windows_Server-2016-Japanese-Full-Base-Active_Directory-{{timestamp}}", "user_data_file": "{{template_dir}}/setup_winrm.txt", "communicator": "winrm", "winrm_username": "Administrator" }], "provisioners": [ { "type": "powershell", "scripts": [ "Scripts/install_ad.ps1", "Scripts/sysprep_winsrv2016.ps1" ] } ] }
Packerのテンプレートファイルです。
特に重要なのは、"user_data_file"と"provisioners"です。
user_data_file ではUserDataを設定しています。
<powershell> winrm quickconfig -q winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="300"}' winrm set winrm/config '@{MaxTimeoutms="1800000"}' winrm set winrm/config/service '@{AllowUnencrypted="true"}' winrm set winrm/config/service/auth '@{Basic="true"}' netsh advfirewall firewall add rule name="WinRM 5985" protocol=TCP dir=in localport=5985 action=allow netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP dir=in localport=5986 action=allow net stop winrm sc config winrm start=auto net start winrm Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope LocalMachine </powershell>
WinRMを有効化して、PowerShellの実行ポリシーをBypassに変更しています。
scriptsでActive Directory のインストールとSysprepを行うPowerShellスクリプトを呼び出しています。
Install-WindowsFeature AD-Domain-Services,GPMC -IncludeManagementTools -restart Add-WindowsFeature RSAT-ADDS Import-Module ADDSDeployment
C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 -Schedule C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\SysprepInstance.ps1
Active Directoryのインストールは下記のページを参考にしました。
Setting up Active Directory via PowerShell – TechNet UK Blog
Sysprepの実行は下記のページを参考にしました。
EC2Launch を使用した Windows インスタンスの設定 - Amazon Elastic Compute Cloud
動かしてみた
packer build build.json amazon-ebs output will be in this color. ==> amazon-ebs: Prevalidating AMI Name: Windows_Server-2016-Japanese-Full-Base-Active_Directory-1522285155 amazon-ebs: Found Image ID: ami-07f2a061 ==> amazon-ebs: Creating temporary keypair: packer_5abc3a63-61bf-c782-4ebe-b56e75129762 ==> amazon-ebs: Creating temporary security group for this instance: packer_5abc3a66-3a3e-e671-77bc-fd07de9aedf8 ==> amazon-ebs: Authorizing access to port 5985 from 0.0.0.0/0 in the temporary security group... ==> 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-0451aae7c35a7c1e1 ==> amazon-ebs: Waiting for instance (i-0451aae7c35a7c1e1) 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: Waiting for WinRM to become available... amazon-ebs: WinRM connected. amazon-ebs: #< CLIXML amazon-ebs: <Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04"><Obj S="progress" RefId="0"><TN RefId="0"><T>System.Management.Automation.PSCustomObject</T><T>System.Object</T></TN><MS><I64 N="SourceId">1</I64><PR N="Record"><AV>Preparing modules for first use.</AV><AI>0</AI><Nil /><PI>-1</PI><PC>-1</PC><T>Completed</T><SR>-1</SR><SD> </SD></PR></MS></Obj><Obj S="progress" RefId="1"><TNRef RefId="0" /><MS><I64 N="SourceId">1</I64><PR N="Record"><AV>Preparing modules for first use.</AV><AI>0</AI><Nil /><PI>-1</PI><PC>-1</PC><T>Completed</T><SR>-1</SR><SD> </SD></PR></MS></Obj></Objs> ==> 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_winsrv2016.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, attempt 1 ==> amazon-ebs: Waiting for the instance to stop... ==> amazon-ebs: Creating the AMI: Windows_Server-2016-Japanese-Full-Base-Active_Directory-1522285155 amazon-ebs: AMI: ami-******** ==> amazon-ebs: Waiting for AMI to become ready... ==> 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. ==> Builds finished. The artifacts of successful builds are: --> amazon-ebs: AMIs were created: ap-northeast-1: ami-********
正常に作成が完了しました!確認してみます。
aws ec2 describe-images --owners self | jq '.Images[] | {Name, ImageId}' { "Name": "Windows_Server-2016-Japanese-Full-Base-Active_Directory-1522285155", "ImageId": "ami-********" }
AMIが認識されていました!
このAMIからEC2インスタンスを作成しActive Directoryがインストールされていることも確認できました。
起動直後はWindowsのライセンス認証が失敗していましたが、起動後5分程度で自動的に認証されました。もしうまくいかない場合は下記のページが参考になりそうです。
一般的なメッセージ - Amazon Elastic Compute Cloud
参考
あとがき
簡単にActive Directoryを構築・破棄したかったのでAMI化しました。ScriptsのPowerShellを追加すれば、他のWindowsの機能にも簡単に対応できそうですね。
テストが手動なのがイケてないですね...自動化したいです。さらに下記のページを参考にCodeBuildを活用して実行できるようにすればもっといい感じにできそうです。
AWS CodeBuild と HashiCorp Packer を用いた AMI ビルダーの構築方法 | Amazon Web Services ブログ
今回はAMI作成がメインではないので、ここで切り上げます。