Spinnakerで Bake ステージと呼ばれる、デプロイするためのマシンイメージを作成する工程をパイプライン上に作成することができます。AWS では AMI, GCP では VM イメージ が該当します。
Spinnaker では Hashicorp 社の Pakcer というツールを使ってマシンイメージを生成します。Spinnaker で予め用意されている Packer テンプレート を使うこともできますが、カスタム Packer テンプレートを使うことも可能です。
今回はカスタム Packer テンプレートを使って Bake ステージを設定してみます。
目次
前提条件
- 本記事では Packer および Packer テンプレートについての説明は深く取り上げません。詳細を知りたい人はドキュメントを見てください
- 今回は私が取り組んでいるプロジェクトの都合上、GCP の Windows Server の VM イメージを作成しますが、AWS や Linux ユーザであったとしても、Packer テンプレートのパラメータが異なるだけでやり方は同じなので安心して読んでください
Packer テンプレート
GCP かつ Windows Server の Packer テンプレートがなかったため、自分でカスタムして作成しました。一般公開できるような形にしたのを GitHub にアップしました。
variables セクション内の gce_xxxx パラメータは後述の hal コマンドや Bake ステージで渡されます。指定がなければ、テンプレートにあるデフォルト値が使われます。デフォルトで外部IPアドレスを持たせずに、内部IPアドレスのみで通信させるようにしています。変更したい場合は gce_use_internal_ip および gce_omit_external_ip を false に指定してください。
provisioners セクションでは、Sysprep をGCE用にラップした GCESysprep を実行しています。
Windows Remote Management(WinRM) で接続して実行するため、起動時に専用ユーザ(packer)を起動時に作成するようにしています。
Packer テンプレートファイルの設置
上記の Packerテンプレートファイルと PowerShell スクリプトを /opt/rosco/config/packer 配下に置きます。
# Packer テンプレート /opt/rosco/config/packer/gcp-windows-2012-r2.json
実行ユーザの設定も忘れずに。
$ sudo chown spinnaker:spinnaker /opt/rosco/config/packer/gcp-windows-2012-r2.json
hal コマンドでの設定
Spinnaker の設定は hal コマンドで行います。
$ PROJECT=$(gcloud info --format='value(config.project)')
# GCEのデフォルトネットワークから変更したい場合
$ hal config provider google bakery edit \
--network "sample-network" \
--network-project-id $PROJECT \
--use-internal-ip "true" \
--zone "asia-northeast1-a"
# イメージの追加
$ hal config provider google bakery base-image add "windows-2012-r2" \
--source-image-family "windows-2012-r2" \
--short-description "Windows Server 2012 R2" \
--detailed-description "Windows Server 2012 R2 Datacenter Edition, x86_64" \
--package-type nupkg \
--template-file gcp-windows-2012-r2.json
# 確認
$ hal config provider google bakery base-image get "windows-2012-r2"
+ Get current deployment
Success
+ Get windows-2012-r2 base image
Success
+ Settings for windows-2012-r2 ingoogle's bakery:
GoogleBaseImage(baseImage=GoogleBaseImage.GoogleImageSettings(super=BaseImage.ImageSettings(id=windows-2012-r2, shortDescription=Windows Server 2012 R2, detailedDescription=Windows Server 2012 R2 Datacenter Edition, x86_64, packageType=nupkg, templateFile=gcp-windows-2012-r2.json), isImageFamily=false), virtualizationSettings=GoogleBaseImage.GoogleVirtualizationSettings(sourceImage=null, sourceImageFamily=windows-2012-r2))
hal deploy apply で反映させます。 *1 数分程度かかります。
$ sudo hal deploy apply $ sudo systemctl daemon-reload
Pipeline での設定
Pipeline で Bake ステージの設定をします。Pipeline の作成は省略しています。
Add stage をクリックし、 Type を Bake に選択します。
下図のように、 Base OS に先ほど追加したイメージ( windows-2012-r2 )が追加されていますのでそれを選択します。
Show Advanced Options をチェックして、Extended Attributes で、環境変数として渡すパラメータ( gce_subnetwork, gce_service_account_email )を入力します。
設定できたら右下にある Save Changes をクリックして保存します。

Pipeline の実行
Pipeline の手動実行は Start Manual Execition をクリックします(下図①)

実行中、 Packer の実行状況やエラー調査は View Bakery Details から確認できます(上図②)
正常に完了すると、 windows-2012-r2-YYYYMMDDHHmmss のイメージが作成されます。
正常時のログを貼っておきます。
==> googlecompute: Checking image does not exist...
==> googlecompute: Creating temporary SSH key for instance...
==> googlecompute: Using image: windows-server-2012-r2-dc-v20190225
==> googlecompute: Creating instance...
googlecompute: Loading zone: asia-northeast1-a
googlecompute: Loading machine type: n1-standard-1
googlecompute: Requesting instance creation...
googlecompute: Waiting for creation operation to complete...
googlecompute: Instance has been created!
==> googlecompute: Creating windows user for instance...
googlecompute: Waiting for windows password to complete...
googlecompute: Created password.
==> googlecompute: Waiting for the instance to become running...
googlecompute: IP: 10.63.6.44
==> googlecompute: Waiting for WinRM to become available...
googlecompute: WinRM connected.
googlecompute: #< CLIXML
googlecompute: System.Management.Automation.PSCustomObjectSystem.Object1Preparing modules for first use.0-1-1Completed-1 1Preparing modules for first use.0-1-1Completed-1
==> googlecompute: Connected to WinRM!
==> googlecompute: Provisioning with Powershell...
==> googlecompute: Provisioning with powershell script: /tmp/packer-powershell-provisioner475077573
googlecompute: 2019/03/05 05:04:01 GCESysprep: Beginning GCESysprep.
googlecompute: 2019/03/05 05:04:01 GCESysprep: No answer file was specified. Using default file.
googlecompute: 2019/03/05 05:04:01 GCESysprep: Running 'schtasks' with arguments '/delete /tn GCEStartup /f'
googlecompute: 2019/03/05 05:04:01 GCESysprep: --> SUCCESS: The scheduled task "GCEStartup" was successfully deleted.
googlecompute: 2019/03/05 05:04:02 GCESysprep: Clearing events in EventViewer.
googlecompute: 2019/03/05 05:04:06 GCESysprep: Running 'C:\Windows\System32\Sysprep\sysprep.exe' with arguments '/generalize /oobe /quit /unattend:C:\Program Files\Google\Compute Engine\sysprep\unattended.xml'
googlecompute: 2019/03/05 05:05:43 GCESysprep: Waiting for sysprep to complete.
googlecompute: 2019/03/05 05:05:43 GCESysprep: Setting new startup command.
googlecompute: 2019/03/05 05:05:44 GCESysprep: Forgetting persistent disks.
googlecompute: 2019/03/05 05:05:44 GCESysprep: Clearing self signed certs.
googlecompute: 2019/03/05 05:05:44 GCESysprep: Shutting down.
googlecompute: 2019/03/05 05:05:44 GCESysprep: Running 'shutdown' with arguments '/s /t 00 /d p:2:4 /f'
==> googlecompute: Deleting instance...
googlecompute: Instance has been deleted!
==> googlecompute: Creating image...
==> googlecompute: Deleting disk...
googlecompute: Disk has been deleted!
Build 'googlecompute' finished.
==> Builds finished. The artifacts of successful builds are:
--> googlecompute: A disk image was created: windows-2012-r2-20190305050100
まとめ
Spinnaker で GCE イメージを作成する、 Bake ステージの設定やカスタムイメージの設定方法を紹介しました。
参考文献
- Bake and Deploy Pipeline - Spinnaker
- Configure the Image Bakery - Spinnaker
- Packer Templates - Spinnaker
- Continuous Deployment on Compute Engine Using Ansible with Spinnaker | Solutions | Google Cloud
- rosco/rosco-web/config/packer at master · spinnaker/rosco
*1:hal config provider google bakery base-image add で更新されるはずだが反映されなかった