Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Terraform Bootcamp - Azure Infrastructure as Code隊

5,409 views

Published on

Azure Antenna 2018/5/29 企画

Published in: Technology

Terraform Bootcamp - Azure Infrastructure as Code隊

  1. 1. Azure Antenna Terraform Bootcamp 真壁 徹 日本マイクロソフト株式会社 クラウドソリューションアーキテクト 2018/5/29 Azure Infrastructure as Code隊
  2. 2. 自己紹介 { “名前” : “真壁 徹(まかべ とおる)”, “所属” : “グローバル クラウドアーキテクト技術本部”, “役割” : “クラウド ソリューションアーキテクト”, “経歴” : “大和総研 → HP Enterprise”, “特技” : “クラウド & オープンソース”, “Twitter” : “@tmak_tw” }
  3. 3. 本日のゴール Terraform Bootcamp Terraformの基礎を学ぶ Azure特有の知識を得る 自走に必要な情報源を知る (質問はお気軽に)
  4. 4. Agenda 13:00 – 14:00 Terraformの基礎 14:00 – 15:00 AzureにおけるTerraform 15:00 – 15:15 休憩 15:15 – 16:45 もくもくハンズオン (余裕があれば Tips紹介) 16:45 – 17:00 まとめ
  5. 5. Terraformの基礎
  6. 6. Terraform概要 マルチクラウド対応のプロビジョニングツール Hashicorp社が開発をリード GitHub上でオープンに開発 シンプルなDSL(HCL)、強力な変数表現と状態管理、小気味よいフィードバックループ クラウドプロバイダー個別機能をプラグイン化 Azure向けプラグインも活発に開発されている AzureRM Terraform Provider
  7. 7. シンプルに書ける HCL(Hashicorp Configuration Language) • 人間にとっての読み書きやすさと、Machine- Friendlyのバランスをとって設計された • JSONを使うこともできるが、HCLがおすすめ • 処理を手続き的に書くのではなく、リソース のあるべき姿を宣言的に resource "azurerm_resource_group" "test" { name = "testResourceGroup1" location = "West US" tags { environment = "Production" } }
  8. 8. マルチプラットフォーム 対象のクラウドプロバイダー、リソースをプラグイン • 総合クラウドプロバイダーだけでなく、数多 くのIaaS/PaaS/SaaSむけプラグイン(プロバイ ダー)がある • クラウドサービスに加え、インフラソフト ウェアむけプロバイダーもあり(Kubernetesな ど) https://www.terraform.io/docs/providers/index.html (以下、まだまだ続く)
  9. 9. プロバイダーの開発 GitHubでオープンに • 開発が活発か、運営が健全かどうか、使う前 に確認しましょう • 開発中の機能や不具合対応状況も把握できる • もちろん貢献もできる https://github.com/terraform-providers (以下、まだまだ続く)
  10. 10. シングルバイナリーで可搬性が高い Golangで書かれている • 実行プラットフォームに合わせてファイルを ダウンロードするだけ • 依存関係に悩まされない • 対応するパッケージマネージャーもある (Homebrew、Chocolateyなど) https://www.terraform.io/downloads.html
  11. 11. 分かりやすいオペレーション init、plan、apply、destroy init plan apply destroy • 各種初期化 • プラグインの導入 • バックエンドの初 期化 • 必要なファイルの コピー • 実行計画の作成 • リソースがどのよ うに追加、変更、 削除されるかを確 認 • 実行 • リソースの一括削 除 リソース定義の変更 planを気軽に実行できる -> コーディングと確認の小気味よいフィードバックループ
  12. 12. 実行スコープが明快 同じディレクトリにある.tfファイルがマージされる • 用途や位置づけ別に分割して定義ファイル(.tf) を書く • コマンド実行時、同じディレクトリにある.tf ファイルはマージされる • 階層化は任意 (実行スコープは分離できる) ├── main.tf ├── output.tf ├── variables.tf ├── regions │ ├── region1 │ │ ├── main.tf │ │ ├── output.tf │ │ └── variables.tf │ ├── region2 │ │ ├── main.tf │ │ ├── output.tf │ │ └── variables.tf
  13. 13. さっそく手を動かして試してみましょう こわくない • Azureの”リソースグループ”を使って、リソー スの作成、変更、削除を体験しましょう • 空のリソースグループはコストがかかりませ ん、ご安心を • Azureポータルを開き、Cloud Shellを起動して ください • Azure Cloud ShellにはTerraformが導入済みな ので、すぐ使えます ポータル右上の このボタン
  14. 14. $ cd clouddrive $ git clone https://github.com/ToruMakabe/AzureAntennaTFBC201805.git $ cd AzureAntennaTFBC201805/ex01/ $ ll total 1 drwxrwxrwx 2 root root 0 May 20 01:45 ./ drwxrwxrwx 2 root root 0 May 20 01:45 ../ -rwxrwxrwx 1 root root 121 May 20 02:22 main.tf* リソース操作体験 #1 clouddriveディレクトリへ移動しま す GitHubから演習リポジトリをクロー ンします ディレクトリex01へ移動します ディレクトリの中身を確認します main.tfがあることを確認します その他にファイル、ディレクトリは ありません
  15. 15. $ cat main.tf provider "azurerm" {} resource "azurerm_resource_group" "ex01" { name = "tfbc-ex01-rg" location = "japanwest" } リソース操作体験 #2 main.tfの中身を確認します 空のリソースグループを作るHCLで す “azurerm”プロバイダーの使用を宣言 しています “tfbc-ex01-rg”というリソースグルー プを定義しています HCLの解説は追って
  16. 16. $ terraform init Initializing provider plugins... - Checking for available provider plugins on https://releases.hashicorp.com... - Downloading plugin for provider "azurerm" (1.5.0)... [snip] Terraform has been successfully initialized! [snip] リソース操作体験 #3 terraform initコマンドで初期化しま す
  17. 17. $ ll total 1 drwxrwxrwx 2 root root 0 May 20 01:45 ./ drwxrwxrwx 2 root root 0 May 20 01:45 ../ -rwxrwxrwx 1 root root 121 May 20 02:22 main.tf* drwxrwxrwx 2 root root 0 May 20 02:30 .terraform/ $ ll .terraform/plugins/linux_amd64/ total 40331 drwxrwxrwx 2 root root 0 May 20 02:30 ./ drwxrwxrwx 2 root root 0 May 20 02:30 ../ -rwxrwxrwx 1 root root 83 May 20 02:30 lock.json* -rwxrwxrwx 1 root root 41297888 May 20 02:30 terraform-provider- azurerm_v1.5.0_x4 リソース操作体験 #4 initで何が起こったのか、ディレクト リを確認します .terraformディレクトリが作られまし た “azurerm”プラグインがインストール されたことが分かります
  18. 18. $ terraform plan Refreshing Terraform state in-memory prior to plan... [snip] Terraform will perform the following actions: + azurerm_resource_group.ex01 id: <computed> location: "japaneast" name: "tfbc-ex01-rg" tags.%: <computed> Plan: 1 to add, 0 to change, 0 to destroy. [snip] リソース操作体験 #5 terraform planコマンドで実行計画を 作成します この計画を実行すると、リソースを1 つaddできることが分かります change、destroy対象はありません “<computed>” は、実行時に決定さ れる値です “-out”パラメーターで保管しておか ないと、実行時にこの計画通りにで きるか保証はないよ、とか言われま すが、ひとまず無視でOK
  19. 19. $ az group list | grep ex01 $ terraform apply [snip] Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes [snip] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. リソース操作体験 #6 Azure CLI(azコマンド)で、リソース グループの存在を確認します 念のため、存在しないことを確認し てください ではいよいよterraform applyコマン ドで実行します 実行していいかな?と聞かれるの で、”yes”で答えます 無事にリソースを1つaddできたよう です
  20. 20. $ az group list | grep ex01 tfbc-ex01-rg japaneast Succeeded $ ll total 2 drwxrwxrwx 2 root root 0 May 20 01:45 ./ drwxrwxrwx 2 root root 0 May 20 01:45 ../ -rwxrwxrwx 1 root root 121 May 20 02:22 main.tf* drwxrwxrwx 2 root root 0 May 20 02:35 .terraform/ -rwxrwxrwx 1 root root 1152 May 20 02:37 terraform.tfstate* $ cat terraform.tfstate リソース操作体験 #7 Azure CLI(azコマンド)で、リソース グループの存在を確認します 作成できたことが分かります ディレクトリの変化を確認します terraform.tfstateというファイルがで きているはずです、これがリソース の状態管理ファイルです 中身をのぞいてみてください
  21. 21. $ terraform destroy [snip] Terraform will perform the following actions: - azurerm_resource_group.ex01 Plan: 0 to add, 0 to change, 1 to destroy. Do you really want to destroy? [snip] Destroy complete! Resources: 1 destroyed. リソース操作体験 #8 では terraform destroyコマンドでリ ソースを削除してみましょう 対象のリソースを確認のうえ、”yes” で答えます 削除できたようです
  22. 22. $ az group list | grep ex01 $ ll total 3 drwxrwxrwx 2 root root 0 May 20 01:45 ./ drwxrwxrwx 2 root root 0 May 20 01:45 ../ -rwxrwxrwx 1 root root 121 May 20 02:22 main.tf* drwxrwxrwx 2 root root 0 May 20 02:35 .terraform/ -rwxrwxrwx 1 root root 317 May 20 02:39 terraform.tfstate* -rwxrwxrwx 1 root root 1152 May 20 02:39 terraform.tfstate.backup* $ cat terraform.tfstate $ cat terraform.tfstate.backup リソース操作体験 #8 Azure CLIで、リソースグループを削 除できたことを確認します ディレクトリ内の変化も確認します terraform.tfstate.backupというファ イルが増えています .tfstateの変化と、.backupの中身を 確認してみましょう おめでとうございます、Terraformの ライフサイクルを体験できました!
  23. 23. $ terraform plan -out=./terraform.tfplan [snip] Plan: 1 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------ ------ This plan was saved to: ./terraform.tfplan To perform exactly these actions, run the following command to apply: terraform apply "./terraform.tfplan" リソース操作体験 #9 ところでplan時に「この計画が実行 されるかは保証できない」と言われ たのを覚えているでしょうか たしかにplanからapplyまでの間に、 誰かがファイルを編集してしまう可 能性がなくはない 今後planするたびに目にするメッ セージなので、スッキリしておきま しょう -outオプションでplanを実行します 実行計画がファイルに保存されます
  24. 24. $ terraform apply ./terraform.tfplan azurerm_resource_group.ex01: Creating... [snip] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. $ terraform destroy リソース操作体験 #10 実行計画を保存したファイルを指定 してapplyします 先ほどと同様に、リソースが add さ れました ひとりでterraformを使い、かつplan 後に即applyする場合、あまり使いま せんが、のちに備えて覚えておきま しょう 最後に掃除をします
  25. 25. 変数を使ってみよう 何度も参照される値に便利 • 先ほどはリソースグループのlocationに直接値 を指定しました • ですが、他にもlocationを指定するリソースが 増えたときに面倒ですし、変更漏れのリスク もあります • 変数を使いたいですね • 変数はvariableで定義できます • ${var.(変数名)}で参照します • 他にも今後${(hoge)}が出てきたら、Terraform で使われる表現だと意識してください variable "location" { default = "japaneast" } resource "azurerm_resource_group" "ex02" { name = "tfbc-ex02-rg" location = "${var.location}" }
  26. 26. ファイルを分割してみよう コードの可読性、再利用性を上げる • Terraformは実行時に同じディレクトリにあ る.tfファイルをマージします • なので、変数を定義したファイルを分離でき ます • コードの可読性、再利用性が上がります • また、他人やチーム外に見せたくない定義が あれば、ファイルを別にできます • Gitなどコード管理システムを使うときは、見 せたくないファイルの除外を忘れずに [variables.tf] variable "location" { default = "japaneast" } [main.tf] resource "azurerm_resource_group" "ex02" { name = "tfbc-ex02-rg" location = "${var.location}" }
  27. 27. .gitignoreの例 除外を忘れずに • GitHubにTerraformむけ.gitignoreのサンプル があります • 見せたくない定義が入っているファイルは確 実に除外しましょう • また、.tfstate系ファイルにはIDなどリソース の詳細情報が入るので、除外しましょう • 例にある.tfvarsファイルは変数指定の別手法 ですが、今回は触れません # Local .terraform directories **/.terraform/* # .tfstate files *.tfstate *.tfstate.* # Ignore any .tfvars files that are generated automatically for each Terraform run. Most # .tfvars files are managed as part of configuration and so should be included in # version control. # # example.tfvars
  28. 28. $ cd ~/clouddrive/AzureAntennaTFBC201805/ex02/ $ ll [snip] drwxrwxrwx 2 root root 0 May 26 01:45 dummy/ -rwxrwxrwx 1 root root 127 May 26 02:10 main.tf* -rwxrwxrwx 1 root root 48 May 26 01:38 variables.tf* $ cat main.tf $ cat variables.tf 変数定義体験 #1 ex02ディレクトリへ移動します ディレクトリの中身を確認しましょ う main.tfと、variables.tfの中身を確認 します
  29. 29. $ terraform init $ terraform plan $ terraform apply –auto-approve azurerm_resource_group.ex02: Creating... location: "" => "japaneast" name: "" => "tfbc-ex02-rg" tags.%: "" => "<computed>" [snip] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. $ az group list | grep ex02 tfbc-ex02-rg japaneast Succeeded $ terraform destroy 変数定義体験 #2 init、plan、applyします (豆知識) applyの–auto-approveオプ ションをつけると、実行確認をス キップします コマンド実行ディレクトリにある.tf ファイルがマージされ、実行された ことがわかります 最後に掃除をします
  30. 30. 実行スコープの確認 コマンドを実行するディレクトリにないファイルは、対象にならない • 実は、ex02の下にdummyディレクトリがあり ました • dummyディレクトリにはmain.tfがあり、別の リソースグループを定義してあります • ですが、ex02ディレクトリでplan、applyして も、このリソースグループは作られませんで した • 別ディレクトリは実行スコープに入らないこ とが分かります ├── ex02 │ ├── main.tf │ ├── variables.tf │ ├── dummy │ │ ├── main.tf [dummy/main.tf] provider "azurerm" {} resource "azurerm_resource_group" "ex02- dummy" { name = "tfbc-ex02-dummy-rg" location = "${var.location}" }
  31. 31. ここまでのまとめ Terraformの基礎 Terraformの特徴と基本的な情報源 Terraformのオペレーションの流れ ファイル、ディレクトリの構造 実行スコープ
  32. 32. AzureにおけるTerraform
  33. 33. 対応Azureリソースが拡充中 https://www.terraform.io/docs/providers/azurerm/index.html 2017年後半から、対応リソースの 拡充が急ピッチで進む 対応リソースの確認は公式ページ で (まだまだ続く)
  34. 34. Azureプロバイダーの開発状況を確認するには リリースノート、Issue、ロードマップ、etc CHANGELOG(リリースノート) Issues Issues:Milestones(ロードマップ) https://github.com/terraform-providers/terraform-provider-azurerm
  35. 35. ARM Template Deployとどちらを選ぶべき? 重視するポイント次第 <ARM Template Deploy> 新リソースへの対応スピード 一般的なJSONを拡張 ワンストップサポート 実行環境の管理は不要 (CLIのみ) <Terraform> マルチクラウド スッキリ書けるHCL 変数や条件の表現の豊富さ 小気味よいフィードバックループ
  36. 36. APIコールの考え方の違い アーキテクチャー上、重要なポイント ARM Template DeployTerraform 定義ファイル (.tf) 実行環境(端末、Cloud Shell、サーバー) Terraform API API API API Azure Resource Manager API & Resources 定義ファイル (.json) 投入環境(端末、Cloud Shell、サーバー、 ポータル) CLI/Portal/ API Client API Azure Resource Manager API & Resources Deploy Engine 実行計画の作成と実行管理の主体
  37. 37. New! ARM Terraform Resource Provider ARM Template DeployをTerraformで補完 現在プライベートプレビュー中 ARMテンプレートにTerraformリソースプロバイダーを埋め込む ARMエンジン内で実行され、ユーザーからは不可視 対象プロバイダーはユーザー要望とサポート実現性による (まずk8s、Datadog、CloudFlareをサポート) ARMテンプレート資産の多いユーザーにおすすめ
  38. 38. { "type": "Microsoft.TerraformOSS/resources", "name": "NginxPod", "apiVersion": "2018-05-01", "location": "northeurope", "properties": { "providerId": "[resourceId('Microsoft.TerraformOSS/providerregistrations', parameters('resourceName'))]", "resourcetype": "kubernetes_pod", "settings": { "metadata": [ { "name": "nginx", "labels": { "App": "nginx" } } ], "spec": [ { "container": { "image": "nginx:1.7.8", "name": "nginx", "port": { "container_port": 80 } } } ] } [snip] k8s Pod 定義をARMテンプレートへ埋め込む例 本日は概要まで
  39. 39. すこぶる重要!認証と認可 Infrastructure as Codeの全能感、その裏にあるリスク 簡単にリソースが作れる = 簡単に リソースを破壊できる IDとリソースに対する権限の管理 は極めて重要 Azure ADを基盤としたRBAC(Role Based Access Control)を使う IDの一元管理 きめ細かい権限管理 Azure AD 限定 読み書き 禁止
  40. 40. 3種類の認証 ユーザー(Azure CLI)認証、サービスプリンシパル認証、MSI認証 Azure AD リソース リソース リソース 認証トークン ID & シークレット MSI エンドポイン ト ユーザー(Azure CLI)認証 サービスプリン シパル認証 MSI認証 Azure CLI ログイン (ユーザーID & パスワード + MFA) Terraformへ 渡す情報
  41. 41. うっかり事故を無くすには Pushを禁止するより、そもそも認証情報をコードへ書かずに済めば幸せ provider "azurerm" { subscription_id = "YOUR-SUBSCRIPTION-ID" client_id = "YOUR-CLIENT-ID" client_secret = "YOUR-CLIENT-SECRET" tenant_id = "YOUR-TENANT-ID" } push hoge.tf Public Repo 悪意 悪意 悪意 こっち こっちより
  42. 42. 認証の比較 認証情報をコードに書かずに済むよう、整備がすすんでいる ユーザー(Azure CLI)認証 サービスプリンシパル認証 MSI認証 存在意義 インタラクティブ操作 自動化 (ユーザー認証で自 動化すると、担当者が辞め ると悲劇が起こる) セキュアに自動化 Terraformへ渡す 認証情報 Azure CLI認証で生成され たトークン サービスプリンシパルの appId、password、tenant 認証エンドポイントの情報 Terraformへ認証 情報の渡し方 Terraformがトークンを参 照 (設定不要) コードへの埋め込み、環境 変数 環境変数 ARM_USE_MSI を trueに設定 用途 インタラクティブ インタラクティブ & 自動 化 自動化 個人/チーム 個人 個人 & チーム 個人 & チーム 想定実行環境 端末 & Cloud Shell 端末 & サーバー Azure VM (MSI有効化) バックエンドをAzure Blobにする場合など、まだサービスプリンシパル認証が必要なケースはあるが、今後は Azure CLI認証かMSI認証を選択するのがトレンドになりそう
  43. 43. [snip] func getAuthorizationToken(c *authentication.Config, oauthConfig *adal.OAuthConfig, endpoint string) (*autorest.BearerAuthorizer, error) { useServicePrincipal := c.ClientSecret != "" if useServicePrincipal { spt, err := adal.NewServicePrincipalToken(*oauthConfig, c.ClientID, c.ClientSecret, endpoint) if err != nil { return nil, err } auth := autorest.NewBearerAuthorizer(spt) return auth, nil } if c.UseMsi { spt, err := adal.NewServicePrincipalTokenFromMSI(c.MsiEndpoint, endpoint) if err != nil { return nil, err } auth := autorest.NewBearerAuthorizer(spt) return auth, nil } if c.IsCloudShell { // load the refreshed tokens from the Azure CLI err := c.LoadTokensFromAzureCLI() if err != nil { return nil, fmt.Errorf("Error loading the refreshed CloudShell tokens: %+v", err) } } [snip] ご参考: 認証ロジック https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/azurerm/config.go
  44. 44. Cloud Shell、実行環境としてはいいんだけど… コーディング、つらいですか Cloud Shellには、VimとEmacsが 入ってますが これ以上はわたしの口からは ちょっと
  45. 45. Visual Studio Codeのすすめ Terraformむけ拡張あり Terraform拡張: シンタックスハイライト、補完、フォーマット Azure Terraform拡張(Preview): Cloud ShellへのコードPush、コマンド実行 本日は任意で
  46. 46. Cloud Shellの共有ディレクト リ(Azure Files)へアップロー ド 気軽に使えて、分かりやすい VS CodeからCloud Shellの共 有ディレクトリ(Azure Files) へPush 編集、Pushの流れがスムーズ まだワークスペースの最上位 ディレクトリしかPush、実行 できない (Previewです) Azure Storage Explorerソースコード管理システム VSCode Azure Terraform拡張 Gitなど バージョン管理が容易 チーム運用なら、これ 機密情報を対象にしないよう 注意 コーディング環境と実行環境のコード同期
  47. 47. そろそろ手を動かしたいですよね Azure Container Instancesを題材に理解を深めましょう Azure Container Instances (コンテナーひとつから使 えるコンテナー実行基盤) Webサーバー コンテナーを デプロイ
  48. 48. $ cd ~/clouddrive/AzureAntennaTFBC201805/ex03/ $ ll total 2 drwxrwxrwx 2 root root 0 May 28 05:16 ./ drwxrwxrwx 2 root root 0 May 26 01:38 ../ -rwxrwxrwx 1 root root 785 May 28 05:16 main.tf* -rwxrwxrwx 1 root root 161 May 28 05:16 outputs.tf* -rwxrwxrwx 1 root root 454 May 28 05:16 variables.tf* コンテナーを動かす #1 ex03ディレクトリへ移動します 3つのファイルがあることを確認しま す
  49. 49. $ cat main.tf provider "azurerm" {} resource "azurerm_resource_group" "ex03" { name = "${var.resource_group_name}" location = "${var.resource_group_location}" } resource "random_integer" "random_int" { min = 100 max = 999 } [snip] コンテナーを動かす #2 main.tfを確認します リソースグループの定義はこれまで の演習と同様です コンテナーグループ名をできるかぎ りユニークにしたいため、Terraform 組み込みプロバイダー”random”の random_integerリソースでランダム な整数を作ります
  50. 50. [snip] resource "azurerm_container_group" "aci-cg" { name = "aci-cg-${random_integer.random_int.result}" location = "${azurerm_resource_group.ex03.location}" resource_group_name = "${azurerm_resource_group.ex03.name}" ip_address_type = "public" dns_name_label = "${var.dns_name_label_prefix}-aci-cg- ${random_integer.random_int.result}" os_type = "linux" container { name = "holleworld" image = "microsoft/aci-helloworld:latest" cpu = "0.5" memory = "1.5" port = "80" } } コンテナーを動かす #3 main.tfの確認の続きです ACIのコンテナーグループを定義しま す 属性の多くに${(hoge)}が利用されて いることに気づいたでしょうか Terraformではvariableで定義した変 数のほかに、リソースを組み込み表 現で参照できます ${(リソースの種類).(リソース名).(属 性)}で参照します リソースの 種類 リソース名 (任意の名前) 属性
  51. 51. $ vim variables.tf variable "resource_group_name" { type = "string" description = "Name of the azure resource group." default = "tfbc-ex03-rg" } variable "resource_group_location" { type = "string" description = "Location of the azure resource group." default = "westus" } variable "dns_name_label_prefix" { type = "string" description = "Your DNS Name Label Prefix (must be unique in region)." default = "your-label" } コンテナーを動かす #4 variables.tfを確認、編集します これまでの演習では指定しなかった、 変数の型指定と説明を入れています コンテナーをインターネットに公開 する際、ホスト名をユニークにする ため、dns_label_prefixを指定します main.tfのコンテナーグループリソー ス dns_name_label属性で、 ${var.dns_name_label_prefix}-aci-cg- ${random_integer.random_int.result} と参照されます 組み合わせてユニークになりそうな 文字列を”your-label”に上書きします
  52. 52. $ terraform init Initializing provider plugins... - Checking for available provider plugins on https://releases.hashicorp.com... - Downloading plugin for provider "azurerm" (1.6.0)... - Downloading plugin for provider "random" (1.3.1)... [snip] * provider.azurerm: version = "~> 1.6" * provider.random: version = "~> 1.3" Terraform has been successfully initialized! [snip] コンテナーを動かす #5 initで初期化します azurermとrandomプロバイダーがダ ウンロードされます
  53. 53. $ terraform plan [snip] Terraform will perform the following actions: + azurerm_container_group.aci-cg [snip] dns_name_label: "${var.dns_name_label_prefix}-aci-cg- ${random_integer.random_int.result}" [snip] + random_integer.random_int id: <computed> max: "999" min: "100" result: <computed> [snip] Plan: 3 to add, 0 to change, 0 to destroy. [snip] コンテナーを動かす #6 planで実行計画を確認します リソースグループ、random_integer、 コンテナーグループの3つをaddする 実行計画ができます 勘のいい人は、random_integerが <computed>なので、それを dns_name_labelで参照しているコン テナーグループは、 random_integer の結果が得られるまで待たないとい けないのでは?と気付くでしょう 鋭い、それを依存関係と呼びます
  54. 54. $ terraform graph digraph { compound = "true" newrank = "true" subgraph "root" { "[root] azurerm_container_group.aci-cg" [label = "azurerm_container_group.aci-cg", shape = "box"] "[root] azurerm_resource_group.ex03" [label = "azurerm_resource_group.ex03", shape = "box"] "[root] provider.azurerm" [label = "provider.azurerm", shape = "diamond"] "[root] provider.random" [label = "provider.random", shape = "diamond"] "[root] random_integer.random_int" [label = "random_integer.random_int", shape = "box"] "[root] azurerm_container_group.aci-cg" -> "[root] azurerm_resource_group.ex03" "[root] azurerm_container_group.aci-cg" -> "[root] random_integer.random_int" "[root] azurerm_container_group.aci-cg" -> "[root] var.dns_name_label_prefix" "[root] azurerm_resource_group.ex03" -> "[root] provider.azurerm" "[root] azurerm_resource_group.ex03" -> "[root] var.resource_group_location" "[root] azurerm_resource_group.ex03" -> "[root] var.resource_group_name" "[root] meta.count-boundary (count boundary fixup)" -> "[root] output.fqdn" "[root] meta.count-boundary (count boundary fixup)" -> "[root] output.ip_address" "[root] output.fqdn" -> "[root] azurerm_container_group.aci-cg" "[root] output.ip_address" -> "[root] azurerm_container_group.aci-cg" "[root] provider.azurerm (close)" -> "[root] azurerm_container_group.aci-cg" "[root] provider.random (close)" -> "[root] random_integer.random_int" "[root] random_integer.random_int" -> "[root] provider.random" "[root] root" -> "[root] meta.count-boundary (count boundary fixup)" "[root] root" -> "[root] provider.azurerm (close)" "[root] root" -> "[root] provider.random (close)" } } コンテナーを動かす #7 ここ terraform graphコマンドで依存関 係を把握できます 実は他にも依存関係があったこと が分かります
  55. 55. resource “hogehoge" “hoge01" { name = “hoge" depends_on = [“fugafuga.fuga01"] } resource “fugafuga" “fuga01" { name = “fuga" } 明示的に依存関係を指定するには Terraformは参照を解析し、依存関係 を自動的に解決します いまコンテナーグループ名で使う乱 数で体験していますが、そのほかに は仮想マシンにアタッチするNICも いい例です ”depends_on”で明示的に指定するこ とも可能です 参照で依存関係を表現できない、ま た、不具合などでどうしても解決さ れない場合は、明示しましょう
  56. 56. $ terraform apply [snip] Apply complete! Resources: 3 added, 0 changed, 0 destroyed. Outputs: fqdn = your-label-aci-cg-447.westus.azurecontainer.io ip_address = 104.42.254.163 $ curl your-label-aci-cg-447.westus.azurecontainer.io <html> <head> <title>Welcome to Azure Container Instances!</title> </head> [snip] コンテナーを動かす #8 applyで実行します 完了すると、これまでの演習では見 なかった”Outputs:”が出力されまし た なにはともあれ、出力されたfqdnを curlでGETしてみましょう WebサーバーコンテナーがACIへ無 事デプロイされたことが分かります
  57. 57. $ cat outputs.tf output "ip_address" { value = "${azurerm_container_group.aci-cg.ip_address}" } output "fqdn" { value = "${azurerm_container_group.aci-cg.fqdn}" } $ terraform output fqdn your-label-aci-cg-447.westus.azurecontainer.io $ terraform output ip_address 104.42.254.163 コンテナーを動かす #9 実は、ex03ディレクトリにoutputs.tf というファイルを仕込んでおきまし た output のvalueで参照した属性は、 実行後に出力されます 後からterraform outputコマンドで 参照できます
  58. 58. ファイル分割と名前付けに悩んだら 特に要件やこだわりがなければ • 出力をoutputs.tf、変数をvariables.tfに分割し、 残りはmain.tfに書くのが慣例です ├── main.tf ├── outputs.tf ├── variables.tf https://www.terraform.io/docs/modules/create.html
  59. 59. $ vim variables.tf $ terraform plan [snip] Terraform will perform the following actions: -/+ azurerm_container_group.aci-cg (new resource required) [snip] dns_name_label: “your-label-aci-cg-447" => “your-label2-aci-cg-447" (forces new resource) [snip] Plan: 1 to add, 0 to change, 1 to destroy. [snip] $ terraform apply $ terraform destroy コンテナーを動かす #10 デプロイした後に、リソース定義を 変更したくなる、よくあることです dns名ラベルが不本意だったとしま しょう variable.tfのdns_name_label_prefix を変更し、planしてみてください dns名ラベルの変更では、コンテナー グループの削除と再作成が必要であ ることが分かります 削除->再作成か、属性変更で済むか は、変更内容とリソースによります applyして動きを確認し、終わったら destroyしましょう
  60. 60. resource "azurerm_resource_group" "ex03" { name = "${var.resource_group_name}" location = "${var.resource_group_location}" } 意外に迷うところ Terraformが管理するリソース名と、 Azureのリソースに指定する名前は、 別の属性、識別子です 内容は同じにしてもかまいません Terraformの識別 子として使われる Azureのリソース 名として使われる
  61. 61. ここまでのまとめ AzureにおけるTerraform AzureRMプロバイダーの情報源 ARM Template Deployとの違い、位置づけ 認証と認可 コーディング環境例、実行環境とのコード同期 コンテナーグループ作成を通じた仕様と動作の確認 (組み込みプロバイダー、依存関係、output、定義変更)
  62. 62. 休憩
  63. 63. ハンズオン (自由に もくもくと)
  64. 64. もくもく素材 #1 サンプル集 面白そうなものを選んでデプロイしてみましょう GitHubにサンプルが公開されてい ます git cloneしてもよし、必要なファ イルだけコピペしてもよし 中身は読みましょう (特に重めに課 金されるリソースがないか注意) https://github.com/terraform-providers/terraform- provider-azurerm/tree/master/examples
  65. 65. もくもく素材 #2 Azure公式チュートリアル 面白そうなものを選んでデプロイしてみましょう Azureの公式ドキュメントに、 Terraformに関するまとめページが あります 概要から読むもよし、いきなり チュートリアルするもよし 中身は読みましょう (特に重めに課 金されるリソースがないか注意) https://docs.microsoft.com/ja-jp/azure/terraform/ ここ
  66. 66. 分からない表現、構文があれば まずは公式ドキュメントを 英語ですし、頭から読むのにはむ いていませんが、リファレンスは まずここを https://www.terraform.io/docs/index.html https://www.terraform.io/docs/providers /azurerm/index.html
  67. 67. 終わったら忘れずに なあに、コードがあれば、またすぐに作れますよ $ terraform destroy
  68. 68. 自走に役立つ Tipsなど
  69. 69. 状態管理ファイル置き場がローカルでは不安 バックエンドをAzure Blobにできます 排他制御もしてくれます https://www.terraform.io/docs/backends/t ypes/azurerm.html
  70. 70. 開発/ステージング/本番環境を分けたい workspaceという機能があります terraform workspace newコマンド で環境を作り、selectコマンドで指 定ができる workspace別に状態管理される 従来はdev/stage/prodなどディレ クトリを分けていたが、不要に ただしselectし忘れに注意 https://www.terraform.io/docs/state/works paces.html
  71. 71. 共通機能をまとめたい Moduleを作ることができます module "loadbalancer" { source = "../../modules/loadbalancer" resource_group_name = "${data.azurerm_resource_group.resource_group.name}" location = "${data.azurerm_resource_group.resource_group.location}" prefix = "tf-lb" "lb_port" { http = ["80", "Tcp", "80"] } } ├── modules │ ├── loadbalancer │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf └── projects ├── project_a │ ├── backend.tf │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── project_b │ ├── backend.tf │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ここに共通 化して それぞれのプ ロジェクトか ら呼ぶ 呼ぶ側の 書き方 やりすぎ、凝りすぎ注意
  72. 72. 影響範囲を分割したい リソースのリスクに応じてディレクトリを分けるもの手です ネットワークやデータベースなど、有事 に影響の多きい共有リソースは分離する のも手です 共有リソースとプロジェクト個別リソー スで、デプロイ担当者が違う場合にも有 効です バックエンドを担当者別にAzure RBACで 権限分離するとなお安全です また、リソースが多くなってくると apply時間が長くなりがちなため、リ ソース量観点で分割することもあります └── projects ├── project_a │ ├── backend.tf │ ├── main.tf │ ├── outputs.tf │ └── variables.tf └── shared ├── backend.tf ├── main.tf ├── outputs.tf └── variables.tf
  73. 73. 全部入りのサンプルとかドキュメントない? わたしのブログでよろしければ すでにちょっと古くなりつつあり ますが ご参考になれば http://torumakabe.github.io/post/terraform_azure_sa mple_201801/
  74. 74. CI/CDのパイプラインで使いたい! そうなりますよね Azure 仮想アーキテクチャで Jenkins と Terraform を使用する不変のイ ンフラストラクチャ CI/CD についての概要
  75. 75. CI/CDのパイプラインで使いたい! そうなりますよね Tutorial: CI/CD for Azure using Terraform, Ansible and VSTS
  76. 76. CI/CDのパイプラインで使いたい! そうなりますよね Tutorial: Immutable infrastructure for Azure, using VSTS, Terraform, Packer and Ansible
  77. 77. for i in {1..10}; do curl -f -o TFVersion.json "https://checkpoint-api.hashicorp.com/v1/check/terraform" && break || sleep 1; done if [ ! -f TFVersion.json ]; then echo "TFVersion.json not found!" exit 1 fi TF_VERSION=$(jq -r -M ".current_version" TFVersion.json) echo $TF_VERSION for i in {1..10}; do curl -f -o terraform.zip "https://releases.hashicorp.com/terraform/${TF_VERSION}/terraform_${TF_VERSION}_linux_amd64.zip" && break || sleep 1; done if [ ! -f terraform.zip ]; then echo "terraform.zip not found!" exit 1 fi unzip terraform.zip sudo mv terraform /usr/local/bin rm -f terraform terraform.zip TFVersion.json unset TF_VERSION サーバーへのインストールを自動化したい バージョンチェックのAPIが公開されているので、それを利用する手がある
  78. 78. サポートが欲しい Hashicorp社の日本法人があります 近日 Meetupもあるそうです 2018/6/14(木)19:00~ https://hashicorp.connpass.com/e vent/89569/
  79. 79. まとめ
  80. 80. まとめ いかがでしたでしょうか Terraformの基礎を学ぶ Azure特有の知識を得る 自走に必要な情報源を知る オレたちはようやくのぼりはじめたばかりだからな このはてしなく遠いTerraform坂をよ…
  81. 81. © Copyright Microsoft Corporation. All rights reserved.

×