構成の作成
HashiCorp構成言語形式(HCL)を使用してOCIインフラストラクチャを記述するTerraform構成を記述します。
Terraformを使用すると、HashiCorp Configuration Language (HCL)フォーマットでインフラストラクチャ・リソースについてTerraform構成ファイルに記述できます(構成構文を参照)。Terraform構成ファイルでは2つのフォーマットのいずれかを使用できます。Terraformドメイン固有の言語(HashiCorp Configuration Language (HCL)フォーマット)をお薦めします。また、マシン判読可能のファイルが必要な場合のためのJSONフォーマットがあります。HCLフォーマットを使用する構成ファイルのファイル拡張子は.tf
です。JSONフォーマットを使用するファイルのファイル拡張子は.tf.json
です。Terraformフォーマットは人が読むことができますが、JSONフォーマットはマシン判読可能です。
Terraform構成を使用して、Oracle Cloud Infrastructure (OCI)のリソース、変数定義、データ・ソース、その他多数を定義します。その後、Terraformは、OCI構成をOCI APIエンドポイントに対する一連のAPIコールに変換します。Terraform構成を作成する鍵は、必要なインフラストラクチャを構成構文として概念的に抽象化する方法を理解することです。
Oracle Cloud Infrastructure APIではcamelCaseを幅広く使用していますが、Terraformの構成ファイルではcamelCaseをサポートしていません。このため、構成ではセパレータとして大文字ではなくアンダースコアが示されます。たとえば、APIでは
availabilityDomain
が使用されますが、Terraform構成ではavailability_domain
が使用されます。構成ファイルの要件
Terraform構成(.tf
)ファイルには、ファイルで定義されるコンポーネントに応じて固有の要件があります。たとえば、Terraformプロバイダを1つのファイル(provider.tf
)、変数を別のファイル(variables.tf
)、データ・ソースをさらに別のファイルで定義できます。
プロバイダの定義
次のTerraform構文の使用例では、OCI Terraformプロバイダ定義の要件を示し、さらに関連する変数定義も示しています。プロバイダ定義では、構成ファイル自体に機密データが含まれないように変数が利用されます。機密データが含まれていると、構成ファイルの交換時または共有時にセキュリティ・リスクが発生します。
variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "region" {}
provider "oci" {
tenancy_ocid = "${var.tenancy_ocid}"
user_ocid = "${var.user_ocid}"
fingerprint = "${var.fingerprint}"
private_key_path = "${var.private_key_path}"
region = "${var.region}"
}
The region
attribute specifies the geographical region in which your provider resources are created. To target multiple regions in a single configuration, you simply create a provider definition for each region and then differentiate by using a provider alias, as shown in the following example. Notice that only one provider, named oci
is defined, and yet the oci
provider definition is entered twice, once for the us-phoenix-1
region (with the alias phx
), and once for the region us-ashburn-1
(with the alias "iad").
variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "compartment_ocid" {}
provider "oci" {
region = "us-phoenix-1"
alias = "phx"
tenancy_ocid = "${var.tenancy_ocid}"
user_ocid = "${var.user_ocid}"
fingerprint = "${var.fingerprint}"
private_key_path = "${var.private_key_path}"
}
provider "oci" {
region = "us-ashburn-1"
alias = "iad"
tenancy_ocid = "${var.tenancy_ocid}"
user_ocid = "${var.user_ocid}"
fingerprint = "${var.fingerprint}"
private_key_path = "${var.private_key_path}"
}
詳細は、Provider Configurationを参照してください。
変数の定義
Terraformの変数は、Terraformモジュールのパラメータを表します。変数の定義では、各ブロックが1つの入力変数を構成します。また、各定義に次のオプションの引数のいずれか、またはすべてを指定できます:
type
(オプション): 許可されている3つの値(string
、list
、map
)の1つとして、変数タイプを定義します。この引数が使用されない場合、変数の型はdefault
に基づいて推測されます。default
が指定されない場合、型はstring
であるとみなされます。default
(オプション): 変数のデフォルト値を設定します。デフォルト値が指定されない場合、コール元が値を指定する必要があります。指定しない場合はTerraformによってエラーがスローされます。description
(オプション): 人が読むことができる変数の説明です。
次に、いくつかの変数定義の例を示します。一部の定義には、オプション・パラメータが含まれます。
variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "region" {}
variable "AD" {
default = "1"
description = "Availability Domain"
}
variable "CPUCoreCount" {
default = "2"
type = string
}
詳細は、入力変数を参照してください。
出力の構成
出力変数によって、Terraformエンド・ユーザー問合せをサポートする手段が提供されます。出力変数を使用して、複雑なインフラストラクチャに関連する潜在的な大量データから、意味のあるデータを抽出します。たとえば、どのような時点でも関心を持つ重要な値はごく少数しかありません。出力変数を定義することで、必要な情報を正確に抽出できます。
次に示す単純な例では、ごくわずかの出力変数(インスタンスのIPアドレスとブート・ボリュームID)が定義されています:
# Output the private and public IPs of the instance
output "InstancePrivateIPs" {
value = ["${oci_core_instance.TFInstance.*.private_ip}"]
}
output "InstancePublicIPs" {
value = ["${oci_core_instance.TFInstance.*.public_ip}"]
}
# Output the boot volume IDs of the instance
output "BootVolumeIDs" {
value = ["${oci_core_instance.TFInstance.*.boot_volume_id}"]
}
詳細は、Terraformからのデータの出力を参照してください。「出力値」も参照してください。
リソース
リソースは、Oracle Cloud Infrastructureのコンポーネントです。このようなリソースには、下位レベルのコンポーネント(物理サーバーや仮想サーバーなど)から上位レベルのコンポーネント(電子メール・プロバイダ、データベース・プロバイダ、DNSレコードなど)まですべてが含まれます。
OCI Terraformプロバイダのサポートされているリソースおよびデータ・ソースの完全なリファレンスには、使用方法、引数および属性の詳細が含まれます。完全なリファレンスは、docs.oracle.comおよびTerraformレジストリから入手できます。
データ・ソースとリソースは、リファレンス内のサービスごとにグループ化されます。
Terraform状態ファイルには、構成ファイルの一部として指定されたすべてのリソース属性が含まれます。データベースまたはユーザーのパスワードやインスタンスの秘密キーなどの機密データをTerraformで管理する場合は、その状態ファイル自体を機密データとして扱うことをお薦めします。詳細は、「Sensitive Data in State」を参照してください。
リソースの宣言
次に示すのは、基本的な構造が記述されたリソース定義の簡単な例です。
resource "oci_core_virtual_network" "vcn1" {
cidr_block = "10.0.0.0/16"
dns_label = "vcn1"
compartment_id = "${var.compartment_ocid}"
display_name = "vcn1"
}
この例の最初の行のリソース宣言では、キーワードresourceが使用され、2つのパラメータとしてリソースのtype
とリソースの名前name
(この例ではoci_core_virtual_networkとvcn1)が指定されています。その後のコード・ブロック内には、リソース構成があります。
詳細は、リソースを参照してください。
リソース依存性
リソースがそのリソース・ブロック内の別のリソースを参照する場合、Terraformでは、参照されるリソースに対するプライマリ・リソースの依存関係が自動的に推測されます。リソースは、そのブロック内で明示的に参照されていないリソースに依存している場合もあります。たとえば、リソース自体を作成する前に、リソースのポリシーを作成する必要があるとします。
Terraformで自動的に推測できない非表示の依存関係を定義するには、リソース・ブロックでdepends_onメタ引数を使用できます。
次の例では、関連するポリシーのoci_datascience_notebook_session
リソースおよびoci_identity_policy
リソースが作成されます。oci_datascience_notebook_session
リソースにdepends_on
メタ引数を追加すると、ポリシーが先に作成されます:
resource "oci_datascience_notebook_session" "ods-notebook-session" {
count = var.enable_ods ? var.ods_number_of_notebooks : 0
#Required
compartment_id = var.compartment_ocid
notebook_session_configuration_details {
#Required
shape = var.ods_compute_shape
subnet_id = local.private_subnet_id
#Optional
block_storage_size_in_gbs = var.ods_storage_size
}
project_id = oci_datascience_project.ods-project[0].id
display_name = "${var.ods_notebook_name}-${count.index}"
depends_on = ["oci_identity_policy.ods-policy"]
}
resource "oci_identity_policy" "ods-policy" {
provider = oci.home
compartment_id = var.compartment_ocid
description = "Data Science Policies"
name = var.ods_policy_name
statements = var.enable_vault ? concat(local.ods_policies , local.vault_policies) : local.ods_policies
}
別のスタック内のリソースの参照(スタック出力値のエクスポートによる)
他のスタックに存在するリソースを参照できます。Terraformのremote_state
データ・ソースを使用すると、状態ファイルから出力変数を読み取ることができます。
たとえば、新しいWebアプリケーション用のTerraform構成を記述するとき、ネットワーク・スタックで作成したサブネットをそのWebアプリケーションで使用できます(必要なサブネット値がネットワーク・スタックの状態ファイルに出力された場合のみ)。新しいWebアプリケーションのTerraform構成で、次を行います:
-
既存のネットワーク・スタックの状態ファイルを現行のTerraform構成のコンテキストにプルします。
状態ファイルをプルすると、スタック出力値が有効にエクスポートされます。リソース・マネージャで状態ファイルをプルする手順は、スタックの状態ファイルの取得を参照してください。
-
プルした状態ファイルを、リモート状態ファイルのデータ・ソースにロードします。
-
現在の構成のサブネット・データ・ソースに、参照する状態ファイルの対応する出力変数の値を移入します。
-
オプションで、移入されたデータ・ソースの識別情報を出力し、予期した値であることを確認します。
リソース・マネージャ操作に必要な権限に加え、参照しているリソース・タイプの適切な権限が、それらを参照しているコンパートメントで必要です。この例では、ネットワーク・リソースが配置されているコンパートメントで、ネットワーク・リソースに対する読取り権限が必要です。
次のTerraform構成の抜粋は、別のスタック内のサブネットを参照しています:
# The following example assumes that the source stack (defined by `stack_id`) has output a value named `subnet_id`
# Terraform v0.12 is assumed
variable "stack_id" {}
# Pull the state file of the existing Resource Manager stack (the network stack) into this context
data "oci_resourcemanager_stack_tf_state" "stack1_tf_state" {
stack_id = "${var.stack_id}"
local_path = "stack1.tfstate"
}
# Load the pulled state file into a remote state data source
data "terraform_remote_state" "external_stack_remote_state" {
backend = "local"
config = {
path = "${data.oci_resourcemanager_stack_tf_state.stack1_tf_state.local_path}"
}
}
# Populate a data source in this configuration using a value from the remote state data source
data "oci_core_subnet" "subnet1" {
subnet_id = "${data.terraform_remote_state.external_stack_remote_state.outputs.subnet_id}"
}
# Print the values of the populated data source
output "print-subnet1" {
value = "${data.oci_core_subnet.subnet1}"
}
データ・ソース
データ・ソースは、既存インフラストラクチャの読取り専用ビューを表し、Terraform構成でセマンティックとしての使用を対象としています。次のデータソース構成の単純な例は、基本的な構造を示しています:
# Gets a list of Availability Domains
data "oci_identity_availability_domains" "ADs" {
compartment_id = "${var.tenancy_ocid}"
}
# Get DB node list
data "oci_database_db_nodes" "DBNodeList" {
compartment_id = "${var.compartment_ocid}"
db_system_id = "${oci_database_db_system.TFDBNode.id}"
}
# Get DB node details
data "oci_database_db_node" "DBNodeDetails" {
db_node_id = "${lookup(data.oci_database_db_nodes.DBNodeList.db_nodes[0], "id")}"
}
# Gets the OCID of the first (default) vNIC
data "oci_core_vnic" "DBNodeVnic" {
vnic_id = "${data.oci_database_db_node.DBNodeDetails.vnic_id}"
}
詳細は、データ・ソースを参照してください。
データ・ソースのフィルタリング
リソースのリストを返すデータ・ソースでは、フィルタリング・セマンティクスがサポートされます。フィルタを使用するには、データ・ソース定義に次のブロックを含めます:
filter {
name = ""
values = [""]
}
name
値はフィルタに使用する修飾プロパティ名に対応し、values
リストにはフィルタに使用する1つ以上の値を含めることができます。
ネストしたプロパティおよびマップ要素は、プロパティ名を親プロパティ名で修飾することで指定できます。例のr1
は、source_type
イメージを持つすべてのインスタンスを提供します。例のr2
は、ネームスペースOperations
のキーCostCenter
で値が「42」の定義済タグを含むすべてのインスタンスを提供します。
data "oci_core_instances" "r1" {
...
filter {
name = "source_details.source_type"
values = ["image"]
}
}
data "oci_core_instances" "r2" {
...
filter {
name = "defined_tags.Operations.CostCenter"
values = ["42"]
}
}
複数のvalues
は、ORタイプ・フィルタとして機能します。次のシェイプの例では、結果のデータ・ソースにVMシェイプのStandard 1.1とStandard 1.2の両方が含まれます:
data "oci_core_shape" "t" {
...
filter {
name = "name"
values = ["VM.Standard1.1", "VM.Standard1.2"]
}
}
複数のフィルタ・ブロックを組み合せると、ANDタイプ比較を構成できます。次の例では、リージョンの最初のADに実行中のインスタンスを含むデータ・ソースを返します:
data "oci_core_instances" "s" {
...
filter {
name = "availability_domain"
values = ["\\w*-AD-1"]
regex = true
}
filter {
name = "state"
values = ["RUNNING"]
}
}
前述の例が示すように、フィルタは正規表現も使用できます。regex = true
を設定すると、values
リストの各項目は正規表現として扱われます。"\\w*-AD-1"
の\w
の前の最初の\
のように、前述の例で示したように、正規表現の特殊文字の文字列内にあるバックラッシュは、別のスラッシュでエスケープする必要があります。
構造化オブジェクトのリストへのドリルはサポートされていません。これらのプロパティがターゲット指定されている場合、データソースから結果は返されません。
関数
Terraformには、構成ファイルで使用できるいくつかの組込みファンクションが用意されています。これらのファンクションを使用して、文字列の変更、数値に対する計算の実行、コレクションの管理などを行うことができます。
詳細は、「ビルトイン関数」を参照してください。