Upgrade to Pro — share decks privately, control downloads, hide ads and more …

泣きながらPacker/Ansible provisionerでつくるWindows AMI

泣きながらPacker/Ansible provisionerでつくるWindows AMI

July Tech Festa 2019で発表した「[B10] 泣きながらAWS CodeBuidとPacker/Ansible provisionerでつくるWindows AMI」のセッションスライドです。

https://2019.techfesta.jp/speakers#B20

Masataka Tsukamoto

December 08, 2019
Tweet

More Decks by Masataka Tsukamoto

Other Decks in Technology

Transcript

  1. 誰? • 名前:_・) つかまん (@tsukaman) • 仕事:HPE / Pointnext Hybrid

    IT Practice • 役割:Cloud Solution Architect、打楽器 • 書籍:Ansible実践ガイド 第3版、Raspberry Pi〔実用〕入門 • 好き:せがれいじり、ガジェットIYH、眼鏡、楽しいこと • 参加:Cloud Native Days Tokyo、 RancherJP、Tokyo HackerSpace 他 • 最近:合気道で白帯脱出しました(まだ茶帯) 2
  2. これをしました。 PowerShell AMI Instance Snapshot EBS EC2 AWS CodeBuild Provisioner

    PR/Merge Web Hook Run Custom Image 流れ コードを書いてPRすると⼀旦CodeBuild上でPacker のValidationが⾛ります。結果が問題なさそうだっ たらPRをMergeします。そうするとCodeBuild上で PackerによりAMI作成までの⾃動処理が流れます。 処理が終わるまで珈琲を飲みます。 5
  3. これをしました。 PowerShell AMI Instance Snapshot EBS EC2 AWS CodeBuild Provisioner

    PR/Merge Web Hook Run Custom Image Github コードリポジトリとして、CodeBuild や Packer が 使う各種ファイルの管理を⾏う。 Ansible や PowerShell など、Packer が使う各 Provisioner の コードも併せて管理する。Pull Request や Merge を契機に WebHook にて CodeBuild へ通知する。 6
  4. これをしました。 PowerShell AMI Instance Snapshot EBS EC2 AWS CodeBuild Provisioner

    PR/Merge Web Hook Run Custom Image AWS CodeBuild 予め定義した内容に従い、⾃動処理を⾏う。今回 はGitHubからのWebHookを契機に、カスタマイズ Dockerイメージからコンテナを起動し、その中で Packerの処理を実⾏する。AWSを利⽤する場合は、 安価で柔軟性も⾼く、使いやすい⾃動化ツール。 7
  5. これをしました。 PowerShell AMI Instance Snapshot EBS EC2 AWS CodeBuild Provisioner

    PR/Merge Web Hook Run Custom Image Docker(カスタムイメージ) CodeBuildの⾃動処理では、実⾏環境としてDocker コンテナを利⽤する。処理の内容に合わせて、利 ⽤するDockerイメージを指定するが、今回は Windowsに対して⾏う処理内容に併せて、必要な ツール群を配置したカスタムイメージを⽤意。 8
  6. これをしました。 PowerShell AMI Instance Snapshot EBS EC2 AWS CodeBuild Provisioner

    PR/Merge Web Hook Run Custom Image Packer HachiCorp社が中⼼に開発をしているOSS。各IaaS 基盤や仮想化環境に合わせたマシンイメージを コードから⾃動⽣成することができる。イメージ のカスタマイズにはProvisionerと呼ばれる様々な コンポーネントを組み合わせることが可能。 9
  7. これをしました。 PowerShell AMI Instance Snapshot EBS EC2 AWS CodeBuild Provisioner

    PR/Merge Web Hook Run Custom Image Provisioner Packerでカスタムイメージを作成する際に、ベー スとなるインスタンスに対して様々な処理をする ためのコンポーネント。処理の内容やお好みの定 義⽅法に合わせてツールを選択できる。今回は Ansible、PowerShell、Windows Shell、Fileを利⽤。 10
  8. これをしました。 PowerShell AMI Instance Snapshot EBS EC2 AWS CodeBuild Provisioner

    PR/Merge Web Hook Run Custom Image AWS EC2 / EBS 泣く⼦も黙るPublic Cloud界の重鎮であるAWS様に よる仮想サーバおよび仮想ボリュームを提供する サービス。EC2ではサーバインスタンスの起動に、 ベースとなるAMIを利⽤するが、今回はカスタマ イズしたWindows AMIをPackerで作るよ︕って話。 11
  9. これをしました。 PowerShell AMI Instance Snapshot EBS EC2 AWS CodeBuild Provisioner

    PR/Merge Web Hook Run Custom Image 社畜(私) 泣く⼦。この仕組みを作るため、夜なべを繰り返 しながら⾃動処理が流れては死んでいくのを⽣暖 かく⾒守るというお仕事をする。⾃分でPRして⾃ 分でMergeするという作業を200回くらいやってた。 仕組みが出来た後は、他者に引き継いで去る⼈。 12
  10. 動かす こ い つ ・ ・ ・ 動 く ぞ

    ︕ ( た ぶ ん ) 14 デモ
  11. カスタム Dockerイメージ • CodeBuildの⾃動処理で利⽤するDockerイメージ – CodeBuildが提供するマネージドのイメージもある • この場合、必要なツールは処理の都度インストールすることになる – 必要な処理に併せたイメージを事前に⽤意することもできる

    • 処理時間を短縮したい場合は⽤意した⽅が無難 • イメージはアクセス出来る場所ならどこで保管しても良い – DockerHubやAmazon ECRなど、任意のDockerレジストリを利⽤可 – レジストリの認証情報を設定することも可能 • 今回利⽤しているDockerイメージはDockerHubで公開中 – https://hub.docker.com/repository/docker/tsukaman/jtf2019-packer- ansible-docker-image 16
  12. Dockerfile https://github.com /tsukaman /jtf2019-packer-ansible-docker-image FROM ansible/ansible-runner:1.3.4 ENV PACKER_VERSION 1.4.5 WORKDIR

    /usr/local/bin RUN set -x && ¥ yum install -y https://centos7.iuscommunity.org/ius-release.rpm && ¥ yum update -y --exclude='ansible*' && ¥ yum install -y jq python2-pip tree unzip wget && ¥ rm -rf /var/cache/yum/* && yum clean all && ¥ wget -q https://releases.hashicorp.com/packer/${PACKER_VERSION}/ packer_${PACKER_VERSION}_linux_amd64.zip && ¥ unzip ./packer_${PACKER_VERSION}_linux_amd64.zip && ¥ rm ./packer_${PACKER_VERSION}_linux_amd64.zip && ¥ pip install --upgrade pip && ¥ pip install awscli boto pywinrm 17 1⾏で⼊⼒
  13. AWS CodeBuildの Build Project • CodeBuildでは⾃動処理単位として「Build Project」を作成する • AWSコンソールのほか、AWS CLIやTerraformでも設定が可能

    • Build Projectの設定前にやっておく準備の例 – ⾃動処理で利⽤するDockerコンテナイメージ – GithubのRepositoryの作成 – SystemsManagerのパラメータストアへ機密情報の登録 • パラメータストアでは機密情報を暗号化して保管が可能 – CodeBuildからはこの値を安全に実⾏環境コンテナへ引き渡せる • GitHubでコード化したくない情報を登録すると良い – Ansible vaultのパスワードとか 18
  14. 紹介するファイル⼀覧 https://github.com/tsukaman /jtf2019-packer-ansible-aws ├ README.md ├ ansible │ ├ after_reboot.yml

    │ ├ connection_plugins │ │ └ packer.py │ └ site.yml ├ buildspec.yml ├ files │ └ ansible.cfg [ 右へ続く ] [ 左からの続き ] ├ packer.json ├ powershell │ ├ ConfigureRemotingForAnsible.ps1 │ └ sysprep.ps1 ├ scripts │ ├ build.sh │ ├ run.sh │ └ validate.sh └ win-userdata.txt 31 “packer.py” はPackerがWindowsインスタンスに対してAnsibleで処理を⾏う 為に必要なプラグインスクリプト。PackrのGithubにて配布している。 “ConfigureRemotingForAnsible.ps1” はWindowsがAnsibleの接続を受け付け る為に必要な設定を⾏う為のPowerShellスクリプト。AnsibleのGithubにて 配布している。
  15. 紹介するファイル⼀覧 https://github.com/tsukaman /jtf2019-packer-ansible-aws ├ README.md ├ ansible │ ├ after_reboot.yml

    │ ├ connection_plugins │ │ └ packer.py │ └ site.yml ├ buildspec.yml ├ files │ └ ansible.cfg [ 右へ続く ] [ 左からの続き ] ├ packer.json ├ powershell │ ├ ConfigureRemotingForAnsible.ps1 │ └ sysprep.ps1 ├ scripts │ ├ build.sh │ ├ run.sh │ └ validate.sh └ win-userdata.txt 32 • ConfigureRemotingForAnsible.ps1 の⼊⼿先 https://github.com/ansible/ansible/blob/devel/examples/ scripts/ConfigureRemotingForAnsible.ps1 • packer.py の⼊⼿先 https://github.com/hashicorp/packer/blob/master/examples/ ansible/connection-plugin/2.6.x/packer.py
  16. 紹介するファイル⼀覧 https://github.com/tsukaman /jtf2019-packer-ansible-aws ├ README.md ├ ansible │ ├ after_reboot.yml

    │ ├ connection_plugins │ │ └ packer.py │ └ site.yml ├ buildspec.yml ├ files │ └ ansible.cfg [ 右へ続く ] [ 左からの続き ] ├ packer.json ├ powershell │ ├ ConfigureRemotingForAnsible.ps1 │ └ sysprep.ps1 ├ scripts │ ├ build.sh │ ├ run.sh │ └ validate.sh └ win-userdata.txt 33 • ConfigureRemotingForAnsible.ps1 の⼊⼿先 https://github.com/ansible/ansible/blob/devel/examples/ scripts/ConfigureRemotingForAnsible.ps1 • packer.py の⼊⼿先 https://github.com/hashicorp/packer/blob/master/examples/ ansible/connection-plugin/2.6.x/packer.py
  17. AWS CodeBuildの buildspec.yml • CodeBuildではどのような処理を⾏うかの内容を buildspec.yml で 定義することができる – ソースコードリポジトリのルートディレクトリに配置する

    • 配置場所やファイル名は違うものを指定することも可能 – このファイルの代わりに直接ビルドコマンドを定義することもで きる • YAML形式で様々な設定を柔軟に⾏える – 変数定義やフェーズ毎の細かい処理内容などを定義できる – https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec- ref.html 34
  18. buildspec.yml version: 0.2 phases: install: commands: - ansible –version -

    packer --version - aws --version build: commands: - echo "$VAULT_PASS" > vault_password_file - /bin/sh scripts/run.sh 35 やっていることは⾮常にシンプル。 事前処理で各ソフトウェアのバージョンを出⼒。 実処理ではAnsibleVault⽤のパスワードファイルを 環境変数(パラメータストアの値から定義したア レ)から作成し、その後 run.sh を呼び出している。
  19. 紹介するファイル⼀覧 https://github.com/tsukaman /jtf2019-packer-ansible-aws ├ README.md ├ ansible │ ├ after_reboot.yml

    │ ├ connection_plugins │ │ └ packer.py │ └ site.yml ├ buildspec.yml ├ files │ └ ansible.cfg [ 右へ続く ] [ 左からの続き ] ├ packer.json ├ powershell │ ├ ConfigureRemotingForAnsible.ps1 │ └ sysprep.ps1 ├ scripts │ ├ build.sh │ ├ run.sh │ └ validate.sh └ win-userdata.txt 36 • ConfigureRemotingForAnsible.ps1 の⼊⼿先 https://github.com/ansible/ansible/blob/devel/examples/ scripts/ConfigureRemotingForAnsible.ps1 • packer.py の⼊⼿先 https://github.com/hashicorp/packer/blob/master/examples/ ansible/connection-plugin/2.6.x/packer.py
  20. run.sh #!/bin/sh -xe if echo ${CODEBUILD_SOURCE_VERSION} | grep -q 'pr/ʼ

    ; then /bin/sh scripts/validate.sh else /bin/sh scripts/build.sh fi 37 run.sh では、CodeBuildが⾃動的に設定する環境変数 「CODEBUILD_SOURCE_VERSION」に「pr/」が含まれるかどうかで実⾏する シェルスクリプトを切り替え。Pull-Reqの場合のみ、pr/が含まれる。 この処理はmixiのSREであるIsao Shimizu⽒の記事を参考に実装。 参考︓Terraform どこで実⾏していますか︖|Medium https://medium.com/mixi-developers/terraform-on-aws-codebuild-44dda951fead
  21. build.sh #!/bin/sh -xe packer validate packer.json 38 #!/bin/sh -xe mkdir

    /etc/ansible cp -f ${CODEBUILD_SRC_DIR}/files/ansible.cfg /etc/ansible/ansible.cfg packer build -color=false packer.json validate.sh PRかPush/Mergeかで、packerのサブコマ ンドが変わる。 なおbuildにおいては、CodeBuildのログ コンソールがカラーコードを上⼿く処 理/表⽰できないため -color=false をつけ て実⾏している。
  22. 紹介するファイル⼀覧 https://github.com/tsukaman /jtf2019-packer-ansible-aws ├ README.md ├ ansible │ ├ after_reboot.yml

    │ ├ connection_plugins │ │ └ packer.py │ └ site.yml ├ buildspec.yml ├ files │ └ ansible.cfg [ 右へ続く ] [ 左からの続き ] ├ packer.json ├ powershell │ ├ ConfigureRemotingForAnsible.ps1 │ └ sysprep.ps1 ├ scripts │ ├ build.sh │ ├ run.sh │ └ validate.sh └ win-userdata.txt 39 • ConfigureRemotingForAnsible.ps1 の⼊⼿先 https://github.com/ansible/ansible/blob/devel/examples/ scripts/ConfigureRemotingForAnsible.ps1 • packer.py の⼊⼿先 https://github.com/hashicorp/packer/blob/master/examples/ ansible/connection-plugin/2.6.x/packer.py
  23. ansible.cfg [defaults] gathering = smart fact_caching = jsonfile fact_caching_connection =

    /tmp/facts_cache # two hours timeout fact_caching_timeout = 7200 40 また、packer buildの実⾏の前処理として、/etc/ansible にコピーしていた ansible.cfg はfactキャッシュさせる為のカスタマイズ。 なくても良いが、複数のPlaybookを流す際などは時間が余計にかかるので 必要に応じて設定すると吉。
  24. 紹介するファイル⼀覧 https://github.com/tsukaman /jtf2019-packer-ansible-aws ├ README.md ├ ansible │ ├ after_reboot.yml

    │ ├ connection_plugins │ │ └ packer.py │ └ site.yml ├ buildspec.yml ├ files │ └ ansible.cfg [ 右へ続く ] [ 左からの続き ] ├ packer.json ├ powershell │ ├ ConfigureRemotingForAnsible.ps1 │ └ sysprep.ps1 ├ scripts │ ├ build.sh │ ├ run.sh │ └ validate.sh └ win-userdata.txt 41 • ConfigureRemotingForAnsible.ps1 の⼊⼿先 https://github.com/ansible/ansible/blob/devel/examples/ scripts/ConfigureRemotingForAnsible.ps1 • packer.py の⼊⼿先 https://github.com/hashicorp/packer/blob/master/examples/ ansible/connection-plugin/2.6.x/packer.py
  25. Packerテンプレート ( JSON形式 ) • Packerでどのようなマシンイメージを作成するかを 定義したJSON形式のファイル – ファイル名は任意につけることができる(今回は packer.json

    ) – builders、description、min_packer_version、post-processors、 provisioners、variables のセクションで細かく定義が可能 • 必須セクションは builders のみで残りはオプション • 今回、特に重要なのが builders と provisioners – https://www.packer.io/docs/templates/index.html 42
  26. packer.json (1) { "builders": [ { "ami_description": "Windows 2016 AMI

    image created by Packer", "ami_name": "packer-win2016-{{timestamp | clean_resource_name}}", "iam_instance_profile": "packer-ec2-role", "instance_type": "t3.medium", "vpc_id": "vpc-XXXXXXXXXXXXXXX”, "subnet_id": "subnet-XXXXXXXXXX", "region": "ap-northeast-1", "type": "amazon-ebs", "user_data_file": "win-userdata.txt", "communicator": "winrm", "winrm_username": "Administrator", 43 buildersセクションでは、作成す るAMIに関する設定や、AMIの元 となるEC2インスタンスに関係す るパラメータを指定する。 また、今回はWindowsを利⽤する ので、コミュニケーターに 「WinRM」を指定している。
  27. 紹介するファイル⼀覧 https://github.com/tsukaman /jtf2019-packer-ansible-aws ├ README.md ├ ansible │ ├ after_reboot.yml

    │ ├ connection_plugins │ │ └ packer.py │ └ site.yml ├ buildspec.yml ├ files │ └ ansible.cfg [ 右へ続く ] [ 左からの続き ] ├ packer.json ├ powershell │ ├ ConfigureRemotingForAnsible.ps1 │ └ sysprep.ps1 ├ scripts │ ├ build.sh │ ├ run.sh │ └ validate.sh └ win-userdata.txt 44 • ConfigureRemotingForAnsible.ps1 の⼊⼿先 https://github.com/ansible/ansible/blob/devel/examples/ scripts/ConfigureRemotingForAnsible.ps1 • packer.py の⼊⼿先 https://github.com/hashicorp/packer/blob/master/examples/ ansible/connection-plugin/2.6.x/packer.py
  28. win-userdata.txt <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> 45 1⾏ずつで⼊⼒ インスタンス起動時の実⾏スクリプト(PowerShell)で、 WinRM通信が出来るように設定している。 参考︓PackerでWindows Server 2016のAMIを作成してみた https://dev.classmethod.jp/cloud/aws/packer-winsrv2016-createami/
  29. packer.json (2) "source_ami_filter": { "filters": { "virtualization-type": "hvm", "name": "*Windows_Server-2016-Japanese-Full-Base-*",

    "root-device-type": "ebs" }, "owners": "amazon", "most_recent": true }, 46 カスタムAMIの元となるEC2インスタンスを、どのAMIから起動させるかの 設定。今回は、Windows2016イメージで、上記の条件にマッチするものの うち、最新のものを選択するようにフィルタリングしている。
  30. packer.json (3) "tags": { "Base_AMI_Name": "{{ .SourceAMIName }}", "Extra": "{{

    .SourceAMITags.TagName }}", "Packer": "true", "Release": "Latest" }, "run_tags": { "Packer": "true" }, "run_volume_tags": { "Packer": "true" }, } ], 47 作成されるAMIや、作成中のEC2インスタンス およびEBSボリュームに設定されるTAG情報を 指定している。 カスタマイズAMIは元々どのAMIを元に作成さ れたかなどを情報として埋め込んでいる。
  31. packer.json (4) "provisioners": [ { "type": "ansible", "playbook_file": "./ansible/site.yml", "extra_arguments":

    [ "--connection", "packer", "-v", "--extra-vars", "ansible_shell_type=powershell ansible_shell_executable=None", "--vault-password-file={{user `vault_path`}}" ] }, 48 1⾏で⼊⼒ ここからProvisionerセクション。作成したEC2インスタンスへのカ スタマイズとして、site.ymlのプレイブックを実⾏している。ansible 実⾏時の引数なども柔軟に指定出来る。vault-password-fileは後ほど 定義するユーザ変数を参照させている。
  32. packer.json (5) { "type": "powershell", "inline": [ "mkdir C:¥¥tmp" ]

    }, { "type": "powershell", "inline": [ "Import-Module -name AWSPowerShell", "Copy-S3Object -BucketName バケット名 -Key ファイル名 - LocalFile C:¥¥tmp¥¥保存ファイル名" ] }, 49 1⾏で⼊⼒ powershell provisionerにより、EC2上でコマンドを 実⾏させている。 こちらの内容詳細は後述する。
  33. packer.json (6) { "type": "windows-restart", "restart_check_command": "powershell -command ¥"& {Write-

    Output 'restarted.'}¥"" }, { "type": "ansible", "playbook_file": "./ansible/after_reboot.yml", "extra_arguments": [ "--connection", "packer", "-v", "--extra-vars", "ansible_shell_type=powershell ansible_shell_executable=None", "--vault-password-file={{user `vault_path`}}" ] }, 50 1⾏で⼊⼒ 1⾏で⼊⼒ windows-restart provisionerによりEC2インスタンスを再起動させてい る。また、再起動後にafter_reboot.ymlのプレイブックを実⾏させて いる。この部分の詳細は後述する。
  34. packer.json (7) { "type": "file", "source": "powershell/ConfigureRemotingForAnsible.ps1", "destination": "C:¥¥tmp¥¥ConfigureRemotingForAnsible.ps1" },

    { "type": "powershell", "inline": [ "C:¥¥tmp¥¥ConfigureRemotingForAnsible.ps1 -SkipNetworkProfileChec -CertValidityDays 3650", "rm C:¥¥tmp -Recurse" ] }, 51 1⾏で⼊⼒ HTTPS経由でAnsibleを実⾏させる為のセットアップスクリプトを配 置して実⾏させている。また、このスクリプトが⾃動作成する⾃⼰ 署名証明書の有効期限を3650⽇に延⻑している。
  35. packer.json (8) { "type": "powershell", "scripts": [ "powershell/sysprep.ps1" ] }

    ], "variables": { "vault_path": "vault_password_file" } } 52 処理の最後にsysprepを実⾏させる PowerShellスクリプトをpowershell provisionerで実⾏している。 この部分では、前述のユーザ変 数”vault-path”を定義している。
  36. 紹介するファイル⼀覧 https://github.com/tsukaman /jtf2019-packer-ansible-aws ├ README.md ├ ansible │ ├ after_reboot.yml

    │ ├ connection_plugins │ │ └ packer.py │ └ site.yml ├ buildspec.yml ├ files │ └ ansible.cfg [ 右へ続く ] [ 左からの続き ] ├ packer.json ├ powershell │ ├ ConfigureRemotingForAnsible.ps1 │ └ sysprep.ps1 ├ scripts │ ├ build.sh │ ├ run.sh │ └ validate.sh └ win-userdata.txt 53 • ConfigureRemotingForAnsible.ps1 の⼊⼿先 https://github.com/ansible/ansible/blob/devel/examples/ scripts/ConfigureRemotingForAnsible.ps1 • packer.py の⼊⼿先 https://github.com/hashicorp/packer/blob/master/examples/ ansible/connection-plugin/2.6.x/packer.py
  37. sysprep.ps1 C:¥ProgramData¥Amazon¥EC2- Windows¥Launch¥Scripts¥InitializeInstance.ps1 –Schedule C:¥ProgramData¥Amazon¥EC2- Windows¥Launch¥Scripts¥SysprepInstance.ps1 54 1⾏で⼊⼒ 1⾏で⼊⼒ AWSで提供されるWindows2016

    AMI内で⽤意されている、初 期化スクリプトを実⾏している。 参考︓Amazon EC2 Windows インスタンス⽤ユーザーガイド | Sysprep と EC2Launch の使⽤ https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/ ec2launch.html#ec2launch-sysprep
  38. 紹介するファイル⼀覧 https://github.com/tsukaman /jtf2019-packer-ansible-aws ├ README.md ├ ansible │ ├ after_reboot.yml

    │ ├ connection_plugins │ │ └ packer.py │ └ site.yml ├ buildspec.yml ├ files │ └ ansible.cfg [ 右へ続く ] [ 左からの続き ] ├ packer.json ├ powershell │ ├ ConfigureRemotingForAnsible.ps1 │ └ sysprep.ps1 ├ scripts │ ├ build.sh │ ├ run.sh │ └ validate.sh └ win-userdata.txt 55 • ConfigureRemotingForAnsible.ps1 の⼊⼿先 https://github.com/ansible/ansible/blob/devel/examples/ scripts/ConfigureRemotingForAnsible.ps1 • packer.py の⼊⼿先 https://github.com/hashicorp/packer/blob/master/examples/ ansible/connection-plugin/2.6.x/packer.py
  39. site.yml (1) --- - hosts: all tasks: - name: Ensure

    local user for ansible is present win_user: name: ansible fullname: ansible description: 'Ansible⽤ユーザ' password: '@nsible01' password_never_expires: yes state: present groups: - Administrators - name: Disable password expirartion win_security_policy: section: System Access key: MaximumPasswordAge value: -1 56 - name: Disable password complexity req win_security_policy: section: System Access key: PasswordComplexity value: 0 - name: Set Allowed user for shutdown win_user_right: name: SeShutdownPrivilege users: - Administrators action: set - name: Change power plan to high performance win_power_plan: name: '⾼パフォーマンス'
  40. site.yml (2) - name: Disable Windows Firewall win_firewall: state: disabled

    profiles: - Domain - Private - Public - name: Install SNMP service win_feature: name: SNMP-Service include_management_tools: yes include_sub_features: yes state: present 57
  41. after_reboot.yml - hosts: all tasks: - name: Set startup mode

    to auto and ensure it is started win_service: name: SNMP start_mode: auto state: started 58 SNMPサービスの起動設定は機能インストール後、 ⼀度再起動を経てからじゃないと設定できないので、 別のプレイブックにタスクを記述し、再起動後に実 ⾏する
  42. Ansibleのバージョンが 新しすぎる場合に死ぬ • Packer/Ansible Provisionerを使ってWindows2016のAMIを 作成する場合、Ansible2.8を使うと謎のエラーで死ぬ – Windows2016以外でもダメかも知れない(未検証) – そのうち直ると思うけど、12⽉2⽇現在でIssueはOpenのまま

    – 2.7.10なら動くという報告がIssueのDiscussionスレッドにある • 私は何をしたか︖ – Dockerイメージのベースであるansible-runnerのTAG指定 • ansible-runner:1.3.4ではAnsibleは2.7.10 • yum updateをウッカリかけると最新バージョンになるので注意 – yum update -y --exclude=ʻansible*ʻ みたいにしよう 60
  43. Dockerfile https://github.com /tsukaman /jtf2019-packer-ansible-docker-image FROM ansible/ansible-runner:1.3.4 ENV PACKER_VERSION 1.4.5 WORKDIR

    /usr/local/bin RUN set -x && ¥ yum install -y https://centos7.iuscommunity.org/ius-release.rpm && ¥ yum update -y --exclude='ansible*' && ¥ yum install -y jq python2-pip tree unzip wget && ¥ rm -rf /var/cache/yum/* && yum clean all && ¥ wget -q https://releases.hashicorp.com/packer/${PACKER_VERSION}/ packer_${PACKER_VERSION}_linux_amd64.zip && ¥ unzip ./packer_${PACKER_VERSION}_linux_amd64.zip && ¥ rm ./packer_${PACKER_VERSION}_linux_amd64.zip && ¥ pip install --upgrade pip && ¥ pip install awscli boto pywinrm 61 1⾏で⼊⼒
  44. ファイル転送が 死ぬほど遅いので死ぬ • WinRMを利⽤している場合、そもそもファイル転送速度が遅い – ⾮常に転送速度が遅いので⼤きなファイルの転送は避ける – Ansibleのwin_copyモジュールのドキュメントにも⾔及あり • 「Webサーバでホストし、ターゲットにダウンロードさせろ」

    – openSSHを使った通信も試験的に導⼊されたが私は未検証 • 私は何をしたか︖ – ⾃動処理の中でWebサーバを建てるという⾏為が微妙だった – AWS環境なのでS3 Bucketに巨⼤ファイルを置くことにした – ターゲットからはPowerShell for AWSでダウンロードさせる • S3にアクセスできるようにEC2 Roleの仕組みを使う 62
  45. packer.json (1) { "builders": [ { "ami_description": "Windows 2016 AMI

    image created by Packer", "ami_name": "packer-win2016-{{timestamp | clean_resource_name}}", "iam_instance_profile": "packer-ec2-role", "instance_type": "t3.medium", "vpc_id": "vpc-XXXXXXXXXXXXXXX” "subnet_id": "subnet-XXXXXXXXXX", "region": "ap-northeast-1", "type": "amazon-ebs", "user_data_file": "win-userdata.txt", "communicator": "winrm", "winrm_username": "Administrator", 63 S3 バケットからファイルのダウ ンロードをさせる為に、特定のS3 Bucket内のファイルを読み取るこ とができるRoleを作成し、EC2イ ンスタンスに割り当てる。
  46. Roleに割り当てる ポリシー(例) { "Version": "2012-10-17", "Statement": [ { "Sid": "",

    "Effect": "Allow", "Action": [ "s3:List*", "s3:Get*" ], "Resource": [ "arn:aws:s3:::バケット名/*", "arn:aws:s3:::バケット名" ] }, 64 { "Sid": "", "Effect": "Allow", "Action": "s3:ListAllMyBuckets", "Resource": "*" } ] } Role作成時は、信頼するエンティ ティとしてEC2を選択し、権限ポ リシーとしてこの内容を指定する。
  47. packer.json (5) { "type": "powershell", "inline": [ "mkdir C:¥¥tmp" ]

    }, { "type": "powershell", "inline": [ "Import-Module -name AWSPowerShell", “Copy-S3Object -BucketName バケット名 -Key ファイル名 - LocalFile C:¥¥tmp¥¥保存ファイル名" ] }, 65 1⾏で⼊⼒ ポリシーで許可したS3バケット内にダウンロード させたいファイルを置き、それをEC2インスタン ス内に保存させる。
  48. win_rebootを使うと packerの処理が死ぬ • カスタマイズ内容によっては再起動が必要なケースがある – サービスやアプリケーションのインストール、レジストリの変更 など、再起動しないと反映されない項⽬がある – 新規サービスの起動設定をする場合、再起動が必要になった –

    Ansibleには再起動を⾏うModuleがあるが、安直に使うべからず • 再起動後にセッションが復帰せず、Packer処理がTimeoutする • 私は何をしたか︖ – そもそもPackerに、インスタンスを再起動する為の仕組み (windows-restart provisioner)が⽤意されている – Ansibleにこだわりすぎないで、他の⼿段にも⽬を向ける • 特にPowerShellはWindowsではほぼ最強・・・。 66
  49. packer.json (6) { "type": "windows-restart", "restart_check_command": "powershell -command ¥"& {Write-

    Output 'restarted.'}¥"" }, { "type": "ansible", "playbook_file": "./ansible/after_reboot.yml", "extra_arguments": [ "--connection", "packer", "-v", "--extra-vars", "ansible_shell_type=powershell ansible_shell_executable=None", "--vault-password-file={{user `vault_path`}}" ] }, 67 1⾏で⼊⼒ 1⾏で⼊⼒ windows-restart provisionerによりEC2インスタンスを再起動させてい る。また、再起動後にafter_reboot.ymlのプレイブックを実⾏させて いる。
  50. sysprepで初期化される 項⽬がでて死ぬ • 作成するのはGolden ImageなのでSIDなどの初期化が必要 – AWSのWindows AMIはsysprepを実⾏する仕組みが⽤意される – ただし、Sysprep実⾏により初期化される設定がある

    • ライセンス情報、Administratorユーザ情報、Networkアダプタ情報、 Windows Firewall設定など – 尚、この件、調査してくれたのは同僚で私ではない・・・(ありがたや • 私は何をしたか︖ – 巻き戻るものは仕⽅がないので、EC2インスタンス作成時または 作成後にこれらの設定がされるようにした • user-dataでの設定と、ansible-playbook実⾏を併⽤ • PackerでAnsibleを使うため、Ansibleの為の設定がほぼ出来ている という点はメリットと⾔える 68
  51. ほかにも こんな 素敵♡な 地獄が たくさん。 • そもそも情報が少ない。 – ⽇本語だけじゃなく英語も。 •

    Windows Moduleが少ない。 – 2.8で対応になったものもあるが・・・。 • 結局PowerShell頼みになるケースも。 – Ansibleを使う意味を⾒失いそうに。 • レジストリ編集しか⽅法がないことも。 – Ansibleを使う意m(ry • カスタマイズ指⽰がGUIベース。 – 「チェックボックスを外す」「お、おう」 • デバッグがつろい。原因 is どこ。 – Packer?Ansible?CodeBuild?いいえケf(ry • ケチってインスタンスを低スペックで起動し死ぬ。 – 特にメモリがしょぼいとすぐAnsibleがエラーに。 • 私のWindows⼒、PowerShell⼒が低い。 – Apple信者ゆえ・・・。ゆるして・・・。 • ノリノリでJTFのCFPだしたけど仕事が⼤炎上 – これは⾃業⾃得(なのかな・・・) 69
  52. ほかにも こんな 素敵♡な 地獄が たくさん。 • そもそも情報が少ない。 – ⽇本語だけじゃなく英語も。 •

    Windows Moduleが少ない。 – 2.8で対応になったものもあるが・・・。 • 結局PowerShell頼みになるケースも。 – Ansibleを使う意味を⾒失いそうに。 • レジストリ編集しか⽅法がないことも。 – Ansibleを使う意m(ry • カスタマイズ指⽰がGUIベース。 – 「チェックボックスを外す」「お、おう」 • デバッグがつろい。原因isどこ。 – Packer?Ansible?CodeBuild?いいえケf(ry • 私のWindows⼒、PowerShell⼒が低い。 – Apple信者ゆえ・・・。ゆるして・・・。 • やってることが変態(ドM)すぎて仲間が居ない。 – PR/Mergeを1⼈でやる意味(時間かかるんじゃ) 70 One More Thing...
  53. 待て︕ まだ慌てる時間じゃない︕ • Packerのいいところ – AWS以外のイメージも作れるよ︕ – ちまたに情報が結構あるよ(ただし悪魔合体させなければ) – Ansibleが使える

    = 学習コストが低い・・・かも︕ – 使えるベースイメージも幅広く柔軟性が⾼い︕ • EC2 Image Builderのいいところ – AWS公式ツールの安⼼感 – マネージドサービスですぐ使える&基本無料 – AWSサービスとの連携が充実(S3とかIAMとか) – 更新やテストなどの痒いところに⼿が届く機能も実装 76
  54. 待て︕ まだ慌てる時間じゃない︕ • Packerのいいところ – AWS以外のイメージも作れるよ︕ – ちまたに情報が結構あるよ(ただし悪魔合体させなければ) – Ansibleが使える

    = 学習コストが低い・・・かも︕ – 使えるベースイメージも幅広く柔軟性が⾼い︕ • EC2 Image Builderのいいところ – AWS公式ツールの安⼼感 – マネージドサービスですぐ使える&基本無料 – AWSサービスとの連携が充実(S3とかIAMとか) – 更新やテストなどの痒いところに⼿が届く機能も実装 77 選択肢を増やし 状況に応じて 使い分ける!
  55. 86