クラウドでのIaC:開発者向けTerraform入門/IaC in the Cloud: Introduction to Terraform for Developers

原文はこちら:https://blogs.oracle.com/developers/iac-in-the-cloud:-introduction-to-terraform-for-developers

このあといくつかのブログポストで、開発者の皆さんにTerraformの超概観を紹介し、どういったツールなのか、どのように動くのかの基本的な理解を得られるよう説明していきます。

いくつかの理由により、深い内容にまで立ち入っていくのはここでの目標とはしません。第一に、最も重要な理由として、Hashicorp社が既にTerraformの素晴らしいドキュメントを公開しており、それと同じことを説明しても意味がないと思っているからです。第二に、多くの開発者は、必ずしもTerraformについて隅から隅までを深く知っておく必要はないと考えているからです。もちろんDevOpsエンジニアはTerraformとすごく仲良くなりたいと思っているでしょう。しかし、開発者にとっては、多くの場合Terraformのようなツールを使う機会はそれほど頻繁なわけではなく、使うときに快適に使えるだけの知識があればそれで十分だと考えると思います。

というわけで、ここでは敢えてTerraformの詳細からは距離を置いて超概観を説明しつつ、より詳しく知りたい方向けには適宜ドキュメントへのリファレンスを紹介していきます。

以下がこのブログポストシリーズのロードマップです:

  • Terraformの初歩(このポストです)

  • Terraformのインストールと最初のスクリプトの実行

  • Oracle CloudのResource ManagerでTerraformを使ってみる

  • Oracle CloudのResource ManagerでのTerraform中級編

  • TerraformとResource ManagerをCI/CDパイプラインに統合する

イントロ

Terraformの目的は、インフラストラクチャのオブジェクトを表すリソースを定義することです。そしてもうひとつ、リソースの定義を容易にすることです。最初にこのコンセプトを理解しておくことで、Terraformの様々な要素を理解しやすくなりますし、それにつれてコンセプトの理解も深まっていくでしょう。

基本的な構造とシンタックス

Terraformの基本的な構造は以下のように表現できます:

<BLOCK TYPE> "<BLOCK LABEL>" "<BLOCK LABEL>" {
  # Block body
  <IDENTIFIER> = <EXPRESSION> # Argument
}
view rawterraform-1.tf hosted with ❤ by GitHub

ブロックは内容、例えばリソース、を格納します。ブロックにはブロックタイプがあり、ゼロ~複数のラベルがあり、Argumentや時には他のブロックを格納するボディがあります。A引数では名前に対して値を割り当てます。Terraformはリソース間の関係性を考慮してオペレーションの順序を決定するので、ブロックの順序は関係ありません。言い換えると、例えばComputeインスタンスを作成するためにはVirtual Cloud NetworkのIDが必要だった場合、Terraformはそれを理解してまずVirtual Cloud Networkを作成します。とても賢いですね!

詳細は: [OverviewConfiguration Syntax]

ファイル

Terraformのファイルは(多くの場合) .tf の拡張子を使います。他にも選択肢はありますが(JSONなど)、目にすることはあまり多くないでしょう。利便性と可読性のため、設定ファイルはしばしばいくつかの目的別のファイルに分けられます。それらが同じディレクトリに置いてあれば、Terraformはそれらをひとつの大きなファイルであるかのように管理します。

詳細は: [File Extensions]

リソース

Terraformにおける最も重要なパートであるリソースは、インフラストラクチャオブジェクトを記述します。ComputeインスタンスやVirtual Cloud Network、Object Storageバケットなどなど。リソースではタイプとローカルな名前を定義します。

resource "oci_core_instance” “compute_instance” { 
  availability_domain = var.instance_availability_domain
  compartment_id = var.compartment_id
  shape = var.instance_shape
}
view rawresource-example.tf hosted with ❤ by GitHub

上の例では、Computeインスタンス(oci_core_instance)を定義し、 my_instanceというローカル名を与えています。ここで3つの必須の引数、availability_domaincompartment_id と shapeを持っています。リソースについては後のポストで詳しく見ていきますが、今はいったんシンタックスに慣れていきましょう。リソースは他のオペレーションと同様にブロックタイプがまず記され、ラベルが続き、そしてブロック内容が始まります。名前は英字あるいはアンダースコアから始まる必要があり、英字、数字、アンダースコアとダッシュのみを含められます。クオートで囲うことは必須ではありませんが、ひとによっては囲ったほうが読みやすいかもしれません(そして囲っておけばお使いのIDEがpretyにしてくれるでしょう)。

Terraformは設定の状態を保持し、それにもとづいて後で与えられた設定の実行も賢く管理します。与えた設定を再実行する際に、オブジェクトを扱う方法が賢いです。存在しないオブジェクトがあれば作成し、既に存在しているオブジェクトについては必要に応じて更新したり、存在しているが設定からは既に削除されたオブジェクトについては破棄してくれたりします。

多くのリソースはリソースオペレーションの結果返却された属性やデータをエクスポートします。例えば、新しいインスタンスの作成をすると、作成されたインスタンスのIDを含むいくつかの属性が返却されます。それらは他のリソースで利用したり、あるいはスクリプトの終了時に出力させたりできます。見ての通り、属性はドット記法(リスト要素については括弧付き)でアクセスします。上のコードスニペットで作成されたインスタンスのIDを取得したい場合は、oci_core_instance.new_instance.idを使うというわけです。

メタ引数

Terraformには、時折使う必要があるいくつかのメタ引数があります。これらは通常、リソース作成の振る舞いをなんらか修正するためのものです。例えば、リソースブロックの中に count 引数を加えることで、別のリソースブロックを追加せずに複数のインフラストラクチャオブジェクトを作成できます。

詳細は: [ResourcesBehaviorCount]

データソース

データソースはその名の通りのことをします…つまり、スクリプトの別の場所で使うデータを取得します。例えば、インスタンスを作成する際に、Compute Imageのリストを取得してきて、特定のイメージ名をフィルタして見つけたいとします。そうした際にデータソースを利用します。

data "oci_core_images” "images" {
  compartment_id = var.compartment_id
}
view rawdata-source.tf hosted with ❤ by GitHub

データソースはどこから来たのか?それについて次にお話しましょう。

詳細は: [Data Sources]

プロバイダー

プロバイダーは単一のプラットフォーム、クラウドプロバイダーが提供するリソースタイプとデータソースのコレクションです。プロジェクトをイニシャライズする際に、Terraformは自動的にプロバイダーをインストールします(後でやり方をより詳しく説明します)。必要であれば、単一のプロジェクトの中で複数のプロバイダーを持つこともできます。

プロバイダーは下のようなかたちです:

provider "oci" {
  tenancy_ocid = ""    
  user_ocid = ""
  private_key_path = ""
  private_key_password = ""
  fingerprint = ""
  region = ""
}
view rawprovider.tf hosted with ❤ by GitHub

詳細は: [ProvidersMultiple ProvidersProvider Registry]

変数と出力

入力変数

Terraformは入力変数の宣言をサポートしており、これによりプロジェクトで動的な入力を受け入れることができるようになります。Terraform CLIから、あるいは特別な命名規則( TF_VAR_で開始)に従った環境変数から変数に値をセットすることができます。変数は(0.13.0以降では)バリデーションできます。後でOracle Cloudで入力変数がどのように使われているかを見てみますが、楽しんでいただけると思います。

以下がシンプルな変数の宣言です:

variable “image_name" {
  type = string
}
view rawvariable.tf hosted with ❤ by GitHub

デフォルト値もセットできます:

variable “image_name" {
  type = string
  default = “my-image"
}
view rawvariable.tf hosted with ❤ by GitHub

変数は他のブロックからvar.image_nameといったように var キーワードでアクセスできます。

出力値

出力値により、プロジェクトからリソース作成の結果を(また、なんであれ必要な情報を)印字できるようになります。例えば、作成されたComputeインスタンスのパブリックIPを印字したい、などの用途です。

output "public_ip" {
  description = "Public IPs of compute instance. "
  value = oci_core_instance.compute_instance.public_ip
}
view rawoutput.tf hosted with ❤ by GitHub

詳細は: [VariablesVariable Type ConstraintsVariable ValidationOutput ValuesSensitive Values]

Expressionと関数

Expressionは設定の中で値を参照したり、計算したりするために使われます。シンプルなリテラルから、データソースからエクスポートされた要素まで様々です。基礎的な算術、条件の評価や、ビルトイン関数がExpressionの中で使えます。

Expressionと関数はTerraformにおけるごく基本的なコンセプトの一部で、Terraformツール、言語を日々使ううえで影響が大きいので、しっかりと理解しておいたほうがいいセクションのひとつです。

詳細は: [ExpressionsFunctions]

プロジェクト構成

Terraform is pretty flexible and the way you structure your projects is largely up to you. Like all things development related, I do recommend that your team develop some standards and stick to them. I like to keep separate files in my projects for different purposes: 

Terraformはとても柔軟で、プロジェクトをどのように構成するかの大部分は自由です。開発に係る他のすべてのことと同様、チームで標準を決め、それを守るようにすることをおすすめします。私の場合は、プロジェクトのファイルをいくつかの目的別に分割しています:

  • variables.tf あるいは vars.tf を変数の宣言用に

  • outputs.tf を出力ブロック用に

  • provider.tf をプロバイダー定義に

  • インフラストラクチャのカテゴリごとに分けた個々のファイル。例: core.tf でComputeインスタンスを、 functions.tf でFaaSを、などなど。インフラストラクチャファイルは対応するカテゴリに関するリソースとデータブロックを含む。

あなたとあなたのチームはどのような構成、そして慣行がベストなのかを見つけることでしょう。あなたがこのポストで、シリーズの続きでもっと学んでいくうえで必要な基本的な知識を学べていれば幸いです。ではまた次回!

詳細は: [Style Conventions]

サマリー

このポストでは開発者向けのTerraformの基礎を見てみました。次のポストでは、Terraformをインストールして、最初のスクリプトを実行します。

0 件のコメント:

コメントを投稿