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

IaCのベストプラクティス/Best practice of IaC

IaCのベストプラクティス/Best practice of IaC

2023/07/05に行われた、OCHaCafe Season7 #2 - IaCのベストプラクティスで用いた資料です。

デモで用いたコード: oracle-japan/ochacafe-iac

oracle4engineer

July 05, 2023
Tweet

More Decks by oracle4engineer

Other Decks in Technology

Transcript

  1. IaCのベストプラクティス Terraform, Pulumi (AI) Oracle Cloud Hangout Café – Season

    7 #2 Shuhei Kawamura Cloud Architect Oracle Digital, Oracle Corporation Japan July 5, 2023
  2. Copyright © 2023, Oracle and/or its affiliates 2 • 所属

    • 日本オラクル株式会社 • Oracle Digital • 普段の業務 • Digital Nativeなお客様を技術面でご支援 • コミュニティ • OCHaCafe • CloudNative Days – Observability 川村 修平 (Shuhei Kawamura) @shukawam Twitter/GitHub/Qiita
  3. Copyright © 2023, Oracle and/or its affiliates 3 Agenda 1.

    Infrastructure as Code(IaC)とは 2. Terraform 3. Pulumi/Pulumi AI
  4. Copyright © 2023, Oracle and/or its affiliates 5 (広義には)インフラストラクチャを定義、展開、更新、破棄するためのコードを書き、それを実行すること •

    アドホックなスクリプト – Bash, Ruby, Python, etc. • 構成管理ツール – Chef, Puppet, Ansible, etc. • サーバーテンプレートツール – Docker, Packer, Vagrant, etc. • オーケストレーションツール – Kubernetes, Docker Swarm, Nomad, etc. • プロビジョニングツール – Terraform, Pulumi, etc. 手動で実施してきた作業をコードに変換する先行投資と引き換えに、ソフトウェアのデリバリーを効率化する Infrastructure as Code(IaC)とは? … これ以外にもたくさんツールがあります…
  5. Copyright © 2023, Oracle and/or its affiliates 6 セルフサービス ✓

    開発者がインフラ担当者に頼らずにデプロイメントを開始できる スピードと安全性 ✓ 自動化によるデプロイメントの高速化&人的ミスの削減 ドキュメンテーション ✓ IaCのコードは、環境情報を表すドキュメントとして機能 バージョン管理 ✓ Git等のバージョン管理ツールと組み合わせることで、インフラ操作に対する履歴をコミットログとして記録可能 検証 ✓ コード・レビューや自動テスト、静的解析ツールの活用が可能 再利用性 ✓ 再利用可能なモジュールにパッケージ化することで効率的なインフラ定義が可能 反復作業からの解放 ✓ 反復的な作業(コードのデプロイとインフラ管理)からの解放 IaCが提供する価値
  6. Copyright © 2023, Oracle and/or its affiliates 7 • 構成管理ツール/プロビジョニングツール

    • 可変(Mutable)/不変(Immutable) • 手続き型/宣言型 • 汎用言語(GPL*)/ドメイン固有言語(DSL**) • Master/Masterless • Agent/Agentless • Paid/Free • 大規模コミュニティ/小規模コミュニティ *GPL: General Public Licence **DSL: Domain Specific Language IaCのツール選定において検討するべき主な項目
  7. Copyright © 2023, Oracle and/or its affiliates 8 • IaC

    = インフラストラクチャを定義、展開、更新、破棄するためのコードを書き、それを実行すること • ソフトウェアの開発においてクラウド活用が当たり前となった現代では、IaCの需要が非常に高い • IaCツールは、数多く存在する • トレードオフを見ながらツールを選定する • 複数のツールを組み合わせて使う場合もある • e.g. Terraform + Ansible, Docker + Kubernetes, … ここまでのまとめ
  8. Copyright © 2023, Oracle and/or its affiliates 10 Demo: OKE(+周辺リソース)のプロビジョニング

    まずは、どんなことができるのか見てみよう! . ├── examples │ ├── container-engine │ ├── kube-config │ └── vcn ├── live │ └── oke-tutorial └── modules ├── container-engine ├── kube-config └── vcn OCI Region Availability Domain 1 Fault Domain 1 Fault Domain 2 Fault Domain 3 VCN LB Subnet 10.0.20.0/24 K8s API Subnet 10.0.0.0/28 Node Subnet 10.0.10.0/24 Container Engine for Kubernetes Worker Nodes Service Gateway Internet Gateway NAT Gateway terraform init|plan|apply
  9. Copyright © 2023, Oracle and/or its affiliates 11 Terraform •

    HashiCorp社が開発しているIaC(プロビジョニング)ツール • あるべき状態を定義し、TerraformがクラウドベンダーへAPIリクエストを行うことでインフラのプロビジョニングを行う • HCL* (or JSON)を用いて宣言的にあるべき状態を定義 • 状態を記録するStateファイルを用いてTerraformのエンジンで計算を行うことで、冪等性を担保 • リソース間の依存関係は、Terraform側で考慮され実行されるため、ユーザーの考慮事項が少ない *: HashiCorp Configuration Language Terraformとは?
  10. Cloud Service Provider AWS Provider Copyright © 2023, Oracle and/or

    its affiliates 12 Terraformのアーキテクチャ Terraform Core/Terraform Plugins Azure Provider OCI Provider Terraform Core Terraform Plugins RPC* Client Library HTTP(S) Golang *: Remote Procedure Call
  11. Copyright © 2023, Oracle and/or its affiliates 13 Terraform Core

    • どのプラットフォームでも使われるTerraformの基本機能、共通のインターフェースを提供 • Terraformのバイナリ • CLI(init, plan, apply, graph, …, etc.) • リソースやデータソース等から依存関係グラフを作成する機能 • ステートファイルを読み書きするロジック • etc. • HashiCorpが所有し、GitHubリポジトリで管理 • https://github.com/hashicorp/terraform Terraform Core
  12. Copyright © 2023, Oracle and/or its affiliates 14 Terraform Plugins

    • Terraform Coreに対応するプラグイン • Golangで実装されたバイナリでTerraform CoreとRPCを用いて通信 • ネットワーク(HTTP, etc.)を用いて対応するプラットフォームと通信する • 各プラグインのコードは、個別のリポジトリで管理される • https://github.com/hashicorp/terraform-provider-aws • https://github.com/oracle/terraform-provider-oci • プラグインの開発やメンテナンスには専用のFrameworkやSDKを用いる • プラグイン開発 … Terraform Plugin Framework • legacy SDKで作られたプラグインのメンテナンス … Terraform Plugin SDKv2 Terraform Plugins
  13. Copyright © 2023, Oracle and/or its affiliates 15 Terraform Providers(2023/07現在)

    引用:https://registry.terraform.io/browse/providers Partner, Communityまで 含めると3,000以上!
  14. Copyright © 2023, Oracle and/or its affiliates 16 Terraformを用いたインフラのプロビジョニングの流れ Write

    → Plan → Apply provider "oci" { region = var.region } variable "region" {} variable "compartment_ocid" {} variable "vcn_display_name" {} locals { vcn_cidr_block = "10.0.0.0/16" } resource "oci_core_vcn" "vcn" { compartment_id = var.compartment_ocid cidr_block = local.vcn_cidr_block display_name = var.vcn_display_name } $ terraform init . └── .terraform └── providers └── registry.terraform.io └── hashicorp └── oci └── 4.116.0 └── linux_amd64 ├── CHANGELOG.md ├── LICENSE.md ├── README.md └── terraform-provider-oci_v4.116.0 TF Core RPC Client Library OCI Provider TF Plugins $ terraform plan | apply download plugins HTTP(S) terraform.tfstate
  15. Copyright © 2023, Oracle and/or its affiliates 18 Cloud Provider(OCI)と通信するために必要なPluginを指定する

    プロバイダーを指定する Write variable "region" { default = "ap-tokyo-1" description = "OCI Region Identifier. (e.g. ap-tokyo-1, ...)" } provider "oci" { region = var.region } providers.tf
  16. Copyright © 2023, Oracle and/or its affiliates 19 依存ライブラリをダウンロードする(terraform init)

    依存ライブラリをダウンロードする Write $ terraform init Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/oci... - Installing hashicorp/oci v4.121.0... - Installed hashicorp/oci v4.121.0 (signed by HashiCorp) ... 省略 ... ╷ │ Warning: Additional provider information from registry │ │ The remote registry returned warnings for registry.terraform.io/hashicorp/oci: │ - For users on Terraform 0.13 or greater, this provider has moved to oracle/oci. Please update your source in required_providers. ╵ Terraform has been successfully initialized! ... 省略 ... . ├── .terraform │ └── providers │ └── registry.terraform.io │ └── hashicorp │ └── oci │ └── 4.121.0 │ └── linux_amd64 │ ├── CHANGELOG.md │ ├── LICENSE.md │ ├── README.md │ └── terraform-provider-oci_v4.121.0 ├── .terraform.lock.hcl # ダウンロードしたプロバイダー情報が記録される ├── ... 省略 ...
  17. Copyright © 2023, Oracle and/or its affiliates 20 ドキュメントなどを参照しながら、プロビジョニングしたいリソースを定義する プロビジョニングしたいクラウドリソースを定義する

    Write variable "compartment_ocid" { description = "OCID of compartment." } variable "objectstorage_namespace" { description = "Namespace of Object Storage." } variable "objectstorage_bucket_name" { description = "Name of Object Storage Bucket." } ##### # Object Storage resource "oci_objectstorage_bucket" "objectstorage_bucket" { compartment_id = var.compartment_ocid name = var.objectstorage_bucket_name namespace = var.objectstorage_namespace } main.tf https://registry.terraform.io/providers/oracle/oci/latest/ docs/resources/objectstorage_bucket
  18. Copyright © 2023, Oracle and/or its affiliates 21 プロビジョニングされるリソースを確認する(terraform plan)

    プロビジョニングされるリソースを確認する(1/2) Plan $ terraform plan var.compartment_ocid OCID of compartment. Enter a value: ocid1.compartment.oc1... var.objectstorage_bucket_name Name of Object Storage Bucket. Enter a value: example-bucket var.objectstorage_namespace Namespace of Object Storage. Enter a value: orasejapan var.region OCI Region Identifier. (e.g. ap-tokyo-1, ...) Enter a value: ap-tokyo-1 入力変数(以下、順に評価され後勝ち) • variables.tfのdefault属性にデフォルト値を記載する • 環境変数から渡す(TF_VAR_xxx) • terraform.tfvars(.json)ファイルから渡す • *.auto.tfvars(.json)ファイルから渡す • CLIから渡す • -var=“xxx=…” or -var-file=“xxx.tfvars” • (←参照)実行時に対話形式で指定する
  19. Copyright © 2023, Oracle and/or its affiliates 22 プロビジョニングされるリソースを確認する(2/2) Terraform

    used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # oci_objectstorage_bucket.objectstorage_bucket will be created + resource "oci_objectstorage_bucket" "objectstorage_bucket" { + access_type = "NoPublicAccess" + approximate_count = (known after apply) + approximate_size = (known after apply) + auto_tiering = (known after apply) + bucket_id = (known after apply) + compartment_id = "ocid1.compartment.oc1..aaaaaaaanjtbllhqxcg67dq7em3vto2mvsbc6pbgk4pw6cx37afzk3tngmoa" + created_by = (known after apply) + defined_tags = (known after apply) + etag = (known after apply) + freeform_tags = (known after apply) + id = (known after apply) + is_read_only = (known after apply) + kms_key_id = (known after apply) + name = “example-bucket" + namespace = "orasejapan" + object_events_enabled = (known after apply) + object_lifecycle_policy_etag = (known after apply) + replication_enabled = (known after apply) + storage_tier = (known after apply) + time_created = (known after apply) + versioning = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. Plan 出力 概要 + リソースが作成される - リソースが破棄される +/-, -/+ リソースが破棄および再作成される ~ リソースがインプレースで更新される
  20. Copyright © 2023, Oracle and/or its affiliates 23 リソースをプロビジョニングする(terraform apply)

    クラウドリソースをプロビジョニングする Apply $ terraform apply # ... 省略 ... 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 oci_objectstorage_bucket.objectstorage_bucket: Creating... oci_objectstorage_bucket.objectstorage_bucket: Creation complete after 1s [id=n/orasejapan/b/example-bucket] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: # ... 省略 ...
  21. Copyright © 2023, Oracle and/or its affiliates 24 再度、同じ入力変数を与えてプロビジョニングしてみる(terraform apply)

    参考: 冪等性の確認のために同一リソースの再作成を試みる Apply $ terraform apply -var-file variables.tfvars oci_objectstorage_bucket.objectstorage_bucket: Refreshing state... [id=n/orasejapan/b/example-bucket] No changes. Your infrastructure matches the configuration. Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: objectstorage_bucket_name = "example-bucket"
  22. Copyright © 2023, Oracle and/or its affiliates 25 リソース間の依存関係を出力する(terraform graph)

    参考: リソース間の依存関係を参照する $ terraform graph | dot -Tpng > object-storage-graph.png object-storage-graph.png
  23. Copyright © 2023, Oracle and/or its affiliates 26 リソースを削除する(terraform apply

    -destroy) ※terraform destroyは、改善の計画があるため可能な限り、terraform apply -destroyを使う クラウドリソースを削除する $ terraform apply -destroy # ... 省略 ... Plan: 0 to add, 0 to change, 1 to destroy. Changes to Outputs: - objectstorage_bucket_name = "example-bucket" -> null Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes oci_objectstorage_bucket.objectstorage_bucket: Destroying... [id=n/orasejapan/b/example-bucket] oci_objectstorage_bucket.objectstorage_bucket: Destruction complete after 2s Apply complete! Resources: 0 added, 0 changed, 1 destroyed. # ... 省略 ... Apply
  24. Copyright © 2023, Oracle and/or its affiliates 27 • プロバイダーのバージョンが上がって非互換がでたらどうしよう?

    • 作ったコードを他の箇所でも流用したいけど、同じ定義をもう一度しないとダメなのか? • チームで開発を進めたい時、冪等性の担保のためのTerraform Stateはどうやって共有したらいい? • 期待するリソースが作成されることを自動的に確認したいけど、どうすれば? クラウドリソースは作られたけど…これで満足ですか?
  25. Copyright © 2023, Oracle and/or its affiliates 28 • プロバイダーのバージョンが上がって非互換がでたらどうしよう?

    → プロバイダーのバージョンはきちんと指定する • 作ったコードを他の箇所でも流用したいけど、同じ定義をもう一度しないとダメなのか? → Terraformの再利用可能な仕組み(Terraform Module)を活用する • チームで開発を進めたい時、冪等性の担保のためのTerraform Stateはどうやって共有したらいい? → 専用のバックエンドを用いて共有する • 期待するリソースが作成されることを自動的に確認したいけど、どうすれば? → Terraformでも静的解析や自動テストに取り組む クラウドリソースは作られたけど…これで満足ですか?
  26. Copyright © 2023, Oracle and/or its affiliates 29 terraformブロックを用いると、Terraformによるプロバイダーのインストールに細かな条件を設けることができる Terraform

    Provider provider "oci" { region = var.region } terraform { required_version = ">=1.4.5" required_providers { oci = { source = "oracle/oci" version = ">= 4.116.0, < 5.0.0" } } } .terraform └── providers └── registry.terraform.io └── oracle └── oci └── 4.122.0 .terraform └── providers └── registry.terraform.io └── hashicorp └── oci └── 4.122.0 providerブロックのみ指定した場合 provider "oci" { region = var.region }
  27. Copyright © 2023, Oracle and/or its affiliates 30 Terraform Module

    • 一緒に使用する複数リソースが書かれた.tf(.tf.json)ファイルをディレクトリにまとめたもの • Terraformでリソースの設定をパッケージ化して再利用するための主な方法 Terraform Module 再利用性の高いTerraform Code module "vcn-stage" { source = "../modules" compartment_ocid = "..." region = "ap-osaka-1" vcn_display_name = "vcn-stage" } module "vcn-prod" { source = "../modules" compartment_ocid = "..." region = "ap-tokyo-1" vcn_display_name = "vcn-prod" } provider "oci" { region = var.region } variable "region" {} variable "compartment_ocid" {} variable "vcn_display_name" {} locals { vcn_cidr_block = "10.0.0.0/16" } resource "oci_core_vcn" "vcn" { compartment_id = var.compartment_ocid cidr_block = local.vcn_cidr_block display_name = var.vcn_display_name } output "vcn" { value = oci_core_vcn.vcn } modules/main.tf stage/main.tf prod/main.tf
  28. Copyright © 2023, Oracle and/or its affiliates 31 Terraformのモジュールには、標準の構造が存在する https://developer.hashicorp.com/terraform/language/modules/develop/structure

    Terraform Module 標準のモジュール構造に従う $ tree complete-module/ . ├── README.md ├── main.tf ├── variables.tf ├── outputs.tf ├── ... ├── modules/ │ ├── nestedA/ │ │ ├── README.md │ │ ├── variables.tf │ │ ├── main.tf │ │ ├── outputs.tf │ ├── nestedB/ │ ├── .../ ├── examples/ │ ├── exampleA/ │ │ ├── main.tf │ ├── exampleB/ │ ├── .../ ルートモジュール • main.tf • ルートモジュールのエントリーポイント • 複雑なモジュールの場合には、複数に分割する場合もある • variables.tf • ルートモジュールに対する入力変数を宣言する • descriptionは、可能な限り記述する • outputs.tf • ルートモジュールに対する出力変数を宣言する • descriptionは、可能な限り記述する
  29. Copyright © 2023, Oracle and/or its affiliates 32 Terraformのモジュールには、標準の構造が存在する https://developer.hashicorp.com/terraform/language/modules/develop/structure

    Terraform Module 標準のモジュール構造に従う $ tree complete-module/ . ├── README.md ├── main.tf ├── variables.tf ├── outputs.tf ├── ... ├── modules/ │ ├── nestedA/ │ │ ├── README.md │ │ ├── variables.tf │ │ ├── main.tf │ │ ├── outputs.tf │ ├── nestedB/ │ ├── .../ ├── examples/ │ ├── exampleA/ │ │ ├── main.tf │ ├── exampleB/ │ ├── .../ • モジュールは、modules/*に配置する • 小さなモジュールに分割し、ユーザーが選択可能にするべき • README.md • 存在するモジュール → 外部ユーザーが使用可能なモジュール • 存在しないモジュール → 内部利用に限定されたモジュール
  30. Copyright © 2023, Oracle and/or its affiliates 33 Terraformのモジュールには、標準の構造が存在する https://developer.hashicorp.com/terraform/language/modules/develop/structure

    Terraform Module 標準のモジュール構造に従う $ tree complete-module/ . ├── README.md ├── main.tf ├── variables.tf ├── outputs.tf ├── ... ├── modules/ │ ├── nestedA/ │ │ ├── README.md │ │ ├── variables.tf │ │ ├── main.tf │ │ ├── outputs.tf │ ├── nestedB/ │ ├── .../ ├── examples/ │ ├── exampleA/ │ │ ├── main.tf │ ├── exampleB/ │ ├── .../ • モジュールの使用例を examples/*に配置する • examples/*の目的、使い方を説明するREADMEを置いても良い
  31. Copyright © 2023, Oracle and/or its affiliates 34 • モジュールは、GitHubのパブリックリポジトリとして公開する

    • リポジトリが命名規則(terraform-[PROVIDER]-[NAME])に則っている • e.g. terraform-oci-oke-quickstart • リポジトリにdescriptionを設定する • モジュールの標準構造に従っていること • リリースのタグ名がセマンティックバージョンであること • e.g. v1.0.4, 0.9.2 参考: 作ったTerraform Moduleを公開する
  32. Copyright © 2023, Oracle and/or its affiliates 35 Terraform State

    = 管理対象のインフラや構成に関する状態を保存したもの 現実世界のリソースと構成ファイルとのマッピングや、メタデータの追跡等に用いられる Terraform State 宣言的なインフラを実現するための状態管理 { "version": 4, "terraform_version": "1.3.0", "serial": 16, "lineage": "9bcb7903-7f6a-ede8-d00c-1d5b34af2892", "outputs": {}, "resources": [ { "module": "module.shukawam_containerengine_cluster", "mode": "data", "type": "oci_containerengine_cluster_option", "name": "cluster_option", "provider": "module.shukawam_containerengine_cluster.provider[¥"registry.terraform.io/hashicorp/oci¥"]", "instances": [ { "schema_version": 0, "attributes": { "cluster_option_id": "all", "cluster_pod_network_options": [{"cni_type": "OCI_VCN_IP_NATIVE"}, {"cni_type": "FLANNEL_OVERLAY"}], "compartment_id": "ocid1.compartment.oc1..aaaaaaaanjtbllhqxcg67dq7em3vto2mvsbc6pbgk4pw6cx37afzk3tngmoa", "id": "ContainerengineClusterOptionDataSource-3081187312", "kubernetes_versions": ["v1.23.4", "v1.24.1", "v1.25.4"] }, "sensitive_attributes": [] } ] }, ... omit ... ], "check_results": [] } terraform.tfstate チーム間で共有したい場合はどうするか ロック…?更新漏れ…?機密情報…?
  33. Copyright © 2023, Oracle and/or its affiliates 36 チーム間で何かを共有する →

    バージョン管理システム(Git, etc.)を使うのが一般的 Terraform Stateの場合 • バージョン管理下に置くことは良くないとされている • 最新のStateファイルのプッシュし忘れ • 同じStateファイルに対して、terraform applyを実行することをロックする機構が存在しない • 機密情報の扱いが複雑になる(Stateファイルが平文で保存されるため) • … バージョン管理システムではなく、専用のバックエンドを用いる • local, azurerm, consul, gcs, http, Kubernetes, pg, s3, Terraform Cloud, … *: OCI Object Storageの場合は、HTTP or S3互換バックエンドを用いる Terraform State Stateをチーム間でセキュアに公開する
  34. Copyright © 2023, Oracle and/or its affiliates 37 1. 事前承認済みリクエスト(Read

    & Write)を作成する 2. ローカルのStateファイルを手動でアップロードする 3. Terraformバックエンドの構成を追加する 4. Terraformの再初期化(terraform init)を行う 例: OCI Object Storageをバックエンドとして使う https://docs.oracle.com/ja-jp/iaas/Content/API/SDKDocs/terraformUsingObjectStore.htm provider "oci" { region = var.region } terraform { required_version = ">=1.4.5" required_providers { oci = { source = "oracle/oci" version = ">= 4.116.0, < 5.0.0" } } backend "http" { address = "https://objectstorage.ap-tokyo-1.oraclecloud.com/<my-access-uri>" update_method = "PUT" } } 追記して再初期化
  35. Copyright © 2023, Oracle and/or its affiliates 38 参考: セキュアなTerraformの使い方

    https://speakerdeck.com/harukasakihara/sekiyuanaterraformfalseshi-ifang-ji-mi-qing-bao-wokodonihan-mezuhuan-jing-gou-zhu-surunihadousitaraiifalse 特にStateファイル(tfstate)に焦点を当てて、 • 機密情報の扱い方 • 機密情報を使うもの(DBのパスワード、etc.) • 機密情報そのもの(OCI Vault、etc.) • IaCで作るもの/CLI等手動で作ったほうが良いもの が非常によくまとまっています。是非、一読を!
  36. Copyright © 2023, Oracle and/or its affiliates 39 通常のソフトウェア開発では… 期待する結果が得られることを自動的に確認したい

    → Unit, Integration, End-to-endテストを書く (特にモジュール開発の文脈では)Terraformでも… • Unitテスト → 再利用可能な単一のモジュールに対して正しく動作することを確認する • ※Terraformを扱う以上、外部依存をゼロにする方法はないので、純粋な意味でのUnitテストとは異なります • Integrationテスト → 複数のモジュールをデプロイし、それが正しく動作することを確認する • End-to-endテスト → 全てのモジュールをデプロイし、それが正しく動作することを確認する Terraformとテスト テストケースの数 コスト/ 忠実性 速度/ 決定性 テストピラミッドの考え方は、 ソフトウェアの開発・Terraformを 用いた開発で変わらない Unit tests Integration tests E2E tests
  37. Copyright © 2023, Oracle and/or its affiliates 40 Terratest •

    Gruntwork社が開発 • インフラストラクチャのコードの自動テストを簡単に書けるようにするためのGoのライブラリ • Terraform, Packer, Docker, Kubernetes, …, etc. に対するヘルパー関数を提供 • Terraformモジュールから提供されているヘルパー関数の一例 • func terraform.WithDefaultRetryableErrors(t testing.TestingT, originalOptions *terraform.Options) • func terraform.InitAndApply(t testing.TestingT, options *terraform.Options) string • func terraform.Plan(t testing.TestingT, options *terraform.Options) string • func terraform.Destroy(t testing.TestingT, options *terraform.Options) string • etc. Terraformのテストを自動化する - Terratest
  38. Copyright © 2023, Oracle and/or its affiliates 41 Demo: Terratestを用いたTerraformモジュールに対する自動テスト

    Buckets Tokyo . ├── .github │ └── workflows ├── terraform │ ├── examples │ ├── live │ └── modules └── test ├── go.mod ├── go.sum └── object-storage_test.go InitAndApply Terratest stretchr/testify assert.Equal(t,expected, actual) Tokyo Destroy Terratest trigger
  39. Copyright © 2023, Oracle and/or its affiliates 42 静的解析ツール •

    検証可能なエラーは限定的だが、高速&安定的に動作する • クラウドプロバイダに対する認証が不要で使えるのもメリット Terraformと静的解析 terraform validate tfsec tflint Terrascan Overview Terraform組み込みコマンド Terraformコードに対する セキュリティスキャン Terraform用のリンター コンプライアンス、 セキュリティ違反チェック License Terraformと同じ MIT MPL 2.0 Apache 2.0 Built-in checks 構文チェックのみ AWS, Azure, OCI, Kubernetes, etc. AWS, Azure, Google Cloud AWS, Azure, Google Cloud, Kubernetes, etc. Custom checks 非対応 YAML or JSON Go plugin Rego
  40. Copyright © 2023, Oracle and/or its affiliates 43 tfsecを使って、可視性がパブリック(ObjectRead|ObjectReadWithoutList)のバケットの作成を指摘する Demo:

    Terraformの静的解析 - tfsec tfsec ¥ --var-file variables.tfvars resource "oci_objectstorage_bucket" "objectstorage_bucket" { compartment_id = var.compartment_ocid name = var.objectstorage_bucket_name namespace = var.objectstorage_namespace access_type = var.public_access_type } objectstorage_bucket_name = "example-bucket" objectstorage_namespace = "orasejapan" region = "ap-tokyo-1" public_access_type = "ObjectRead" main.tf variables.tfvars Result #1 HIGH Custom check failed for resource oci_objectstorage_bucket.objectstorage_bucket. Bucket visibility is public. ───────────────────────────────────────────────────────────── main.tf:3-8 ───────────────────────────────────────────────────────────── 3 resource "oci_objectstorage_bucket" "objectstorage_bucket" { 4 compartment_id = var.compartment_ocid 5 name = var.objectstorage_bucket_name 6 namespace = var.objectstorage_namespace 7 access_type = var.public_access_type 8 } ───────────────────────────────────────────────────────────── ID custom-custom-oci-00001 Impact Contents could be accidentally published externally. Resolution Set visibility to private ─────────────────────────────────────────────────────────────
  41. Copyright © 2023, Oracle and/or its affiliates 44 Demo: OKE(+周辺リソース)のプロビジョニング

    最初に実施したデモを改めて振り返る . ├── examples │ ├── container-engine │ ├── kube-config │ └── vcn ├── live │ └── oke-tutorial └── modules ├── container-engine ├── kube-config └── vcn OCI Region Availability Domain 1 Fault Domain 1 Fault Domain 2 Fault Domain 3 VCN LB Subnet 10.0.20.0/24 K8s API Subnet 10.0.0.0/28 Node Subnet 10.0.10.0/24 Container Engine for Kubernetes Worker Nodes Service Gateway Internet Gateway NAT Gateway terraform init|plan|apply
  42. Copyright © 2023, Oracle and/or its affiliates 45 • HashiCorp社が開発しているIaCツールで、主にクラウドリソースのプロビジョニングに焦点を当てたツール

    • 実装におけるプラクティス • プロバイダーのインストールに細かく条件を設定する • 再利用可能な形でTerraformのコードを実装する(Terraform Module) • 専用のバックエンドを使ったStateのチーム間共有 • (特にモジュール開発では)自動テストや静的解析に取り組む • こんな人に向いている • 目的特化のシンプルな言語(HCL)で素早く習得したい • コミュニティの成熟度でツールを選定したい Terraformまとめ
  43. Copyright © 2023, Oracle and/or its affiliates 47 Pulumi •

    Pulumi社が開発しているクラウドインフラを作成、デプロイ、管理するためのOSSのIaCツール • あるべき状態を定義し、Pulumi (SDK)がクラウドベンダーへAPIリクエストを行うことでインフラの管理を行う • 既存のプログラミング言語を用いて宣言的にあるべき状態を定義 • TypeScript, JavaScript, Python, Go, .NET, Java, YAMLなどのマークアップ言語, etc. • 状態を記録するStateファイルを用いてPulumiのエンジンが計算を行うことで、冪等性担保 Pulumiとは?
  44. Copyright © 2023, Oracle and/or its affiliates 49 Pulumi Providers

    Terraformには劣るが 主要所は大体カバーできている 参考: https://www.pulumi.com/registry/packages/oci/ Terraform Provider for OCIのラッパーを Pulumiが開発・管理している
  45. Copyright © 2023, Oracle and/or its affiliates 50 ところで、今日扱ったIaCツールのコードを実際に書いたことありますか? const

    opensearchCluster = new oci.opensearch.Cluster("OpenSearch Cluster", { compartmentId: compartmentId, displayName: "opensearch-cluster", dataNodeCount: 1, dataNodeHostType: "FLEX", dataNodeHostOcpuCount: 1, dataNodeHostMemoryGb: 20, dataNodeStorageGb: 50, masterNodeCount: 1, masterNodeHostType: "FLEX", masterNodeHostOcpuCount: 1, masterNodeHostMemoryGb: 20, opendashboardNodeCount: 1, opendashboardNodeHostOcpuCount: 1, opendashboardNodeHostMemoryGb: 8, softwareVersion: "2.3.0", subnetCompartmentId: compartmentId, subnetId: subnet.id, vcnCompartmentId: compartmentId, vcnId: vcn.id, }); ##### VCN resource "oci_core_vcn" "vcn" { compartment_id = var.compartment_ocid cidr_block = local.vcn_cidr_block display_name = var.vcn_display_name } ##### Gateways resource "oci_core_internet_gateway" "internet_gateway" { compartment_id = var.compartment_ocid vcn_id = oci_core_vcn.vcn.id display_name = local.internet_gateway_display_name } resource "oci_core_nat_gateway" "nat_gateway" { compartment_id = var.compartment_ocid vcn_id = oci_core_vcn.vcn.id display_name = local.nat_gateway_display_name } # ... omit ... pulumi/index.ts terraform/main.tf
  46. Copyright © 2023, Oracle and/or its affiliates 52 • 簡単な構成だけど、意外とパラメータを沢山設定しないといけないものが多い

    • いちいち、API Docsを調べるのが面倒 • 使用例はあるけど、一部のパラメータの例しか掲載されていなくて丁度良いスニペットが中々ない • 実際に動かしてみる(=実際にデプロイしてみる)までそのコードが正しく動くか分からない いい感じに動くコードをいい感じに生成してくれる何かがあれば… IaCのコードを書くことが辛い理由
  47. Copyright © 2023, Oracle and/or its affiliates 53 Pulumi AI

    is an experimental feature that lets you use natural-language prompts to generate Pulumi infrastructure-as-code programs in any language. This page is a web-based version of the open-source Pulumi AI project. 引用)https://www.pulumi.com/ai/ 日本語訳: Pulumi AIは、自然言語のプロンプトを使って、任意の言語でPulumi infrastructure-as-codeプログラムを生成できる 実験的機能です。このページは、オープンソースのPulumi AIプロジェクトのウェブベース版です。 昨今、流行りのGPTモデルを搭載した自然言語 → インフラ構成コードを自動生成するヤツ Pulumi AI - IaCのコードを書く上での救世主になりえるか…?
  48. Copyright © 2023, Oracle and/or its affiliates 54 Demo: Helidon

    on Kubernetes w/ Pulumi AI OCI Region Availability Domain 1 Fault Domain 1 Fault Domain 2 Fault Domain 3 VCN LB Subnet 10.0.20.0/24 K8s API Subnet 10.0.0.0/28 Node Subnet 10.0.10.0/24 Container Engine for Kubernetes Worker Nodes Service Gateway Internet Gateway NAT Gateway . ├── Pulumi.yaml ├── index.ts ├── node_modules ├── package-lock.json ├── package.json └── tsconfig.json pulumi preview|up Deployment Pulumi AIで作ります
  49. Copyright © 2023, Oracle and/or its affiliates 55 • Pulumi社が開発しているクラウドインフラを作成、デプロイ、管理するためのOSSのIaCツール

    • 既存のプログラミング言語を用いて宣言的にあるべき状態を定義 • あるべき状態を定義し、Pulumi (SDK)がクラウドベンダーへAPIリクエストを行うことでインフラの管理を行う • こんな人に向いている • GPLの知識を活かしたい • GPLならではの柔軟な表現力を活用してインフラ管理したい • 言語の持つエコシステム(IDE、テストライブラリ、etc.)を活用したい Pulumiまとめ
  50. Copyright © 2023, Oracle and/or its affiliates 56 Terraform Pulumi/Pulumi

    AI GPL/DSL DSL GPL(TypeScript, Go, Python, …) Providers 3,000+ 130+ エコシステム Terratest, Terragrunt, tfsec, tflint, … 言語のエコシステムをそのまま活用 表現の自由度 なし(=統一的な書き方を強制できる) 高い コミュニティ 大規模 小~中規模 本日扱ったIaCツール総まとめ ※2023/07現在
  51. Copyright © 2023, Oracle and/or its affiliates 57 • IaC

    =(広義には)インフラストラクチャを定義、展開、更新、破棄するためのコードを書き、それを実行すること • 手動で実施してきた作業をコードに変換する先行投資と引き換えに、ソフトウェアのデリバリーを効率化する • 多くのツールが存在するが、実現したいこと・スキルセット等を考え最適なツールを選ぶことが重要 まとめ
  52. Copyright © 2023, Oracle and/or its affiliates 58 Terraform •

    https://www.terraform.io/ • Terraform: Up and Running, 3rd Edition • Terraformを使用するためのベストプラクティス • Terratest • セキュアなTerraformの使い方 ~ 機密情報をコードに含めず環境構築するにはどうしたらいいの? Pulumi • https://www.pulumi.com/ その他(デモコードなど) • デモコード: https://github.com/oracle-japan/ochacafe-iac/ • モジュール公開のサンプル: https://registry.terraform.io/modules/shukawam/oke-quickstart/oci/latest • Cloud Guardに基づくtfsecのルール(for OCI): https://github.com/shukawam/tfsec-oci-custom-checks 参考情報