Terraform を 使って OCI File Storage Serviceのマウント (2018/12/19)

この記事は「[Oracle Cloud その2 Advent Calendar 2018](https://adventar.org/calendars/3522)」の[12月19日の記事](https://adventar.org/calendars/3522#list-2018-12-19)として書かれています。

コードを使用してインフラストラクチャのトポロジを定義するHashicorp社の[Terraform](https://www.terraform.io/)を使って[Oracle Cloud Infrastructure](https://cloud.oracle.com/ja_JP/iaas)でInfrastructure as Code（IaC）を実現することができます。

この記事では、Terraformを使ってOCI File Storage ServiceにLinuxインスタンスからマウントしてみたことを紹介します。

# 今回構築する構成
![image04.jpg](https://qiita-image-store.s3.amazonaws.com/0/108635/83eb1f97-9976-e9e4-27c0-c473a69ad53d.jpeg)
Oracle LinuxのVMインスタンス２つから同じFile Storageをマウントする構成を以下のファイルから作成します。

| ファイル名 | 内容 |
|:-:|:-:|
|data_sources.tf| 作成したリソース情報の取得 |
|export.tf| File Storage Exportの作成  |
|export_set.tf| File Storage ExportSetの作成 |
|file_system.tf|File Storageの作成|
|instance.tf|Computeインスタンスの作成|
|mount_target.tf|File Storage Mount Targetの作成|
|network.tf|VCN/InternetGateway/RouteTableの作成|
|provider.tf|Terraform OCI Provider設定|
|security_list.tf|セキュリティリストの作成|
|variables.tf|変数・値の定義|
（すべてのファイルは本ページの最下部にまとめて記載/env-vars.ps1を除く）

# 準備作業
環境を構築をする上で、使用する環境の情報および作成するインスタンスへの接続に必要な情報を準備します。
準備に必要な情報は
「[Oracle Cloud Advent Calendar 2018](https://adventar.org/calendars/3077)」の12月10日の記事
「[Terraform を 使って Oracle Cloud環境構築 (2018/12/10)](https://qiita.com/kenwatan/items/eda524e7db08a7010a66)」を参照し、Terraform の動作テスト～環境変数の設定まで実施してください。

# ネットワーク構築
VCN,Subnet,Internet Gateway,Route Tableを作成（network.tf)
NFS通信を有効とするSecurity Listを作成します。

```security_list.tf
# Protocols are specified as protocol numbers.
# http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml

resource "oci_core_security_list" "TF_security_list" {
  compartment_id = "${var.compartment_ocid}"
  display_name   = "TF_security_list"
  vcn_id         = "${oci_core_virtual_network.TF_vcn.id}"

  // Allow all outbound requests
  egress_security_rules = [
    {
      destination = "0.0.0.0/0"
      protocol    = "all"
    },
  ]

  // See https://docs.us-phoenix-1.oraclecloud.com/Content/File/Tasks/creatingfilesystems.htm.
  // Specific security list rules are required to allow mount targets to work properly.
  ingress_security_rules = [
    {
      // Allowing inbound SSH traffic to instances in the subnet from any source
      protocol = "6"
      source   = "0.0.0.0/0"

      tcp_options {
        "min" = 22
        "max" = 22
      }
    },
    {
      // Allowing inbound ICMP traffic of a specific type and code from any source
      protocol = 1
      source   = "0.0.0.0/0"

      icmp_options {
        "type" = 3
        "code" = 4
      }
    },
    {
      // Allowing inbound ICMP traffic of a specific type from within our VCN
      protocol = 1
      source   = "${var.TF_vcn-cidr}"

      icmp_options {
        "type" = 3
      }
    },
  ]
}
```

# File Storage、Mount Target、Storage export / export setの作成
##### 変数の追加
作成するリソースの名前、パス、サイズを指定します。

```variables.tf
variable "file_system_1_display_name" {
  default = "TF_fs_1"
}

variable "mount_target_1_display_name" {
  default = "my_mount_target_1"
}

variable "export_path_fs1_mt1" {
  default = "/mnt/fs1"
}

variable "export_set_name_1" {
  default = "export set for mount target 1"
}

variable "max_byte" {
  default = 23843202333
}

variable "max_files" {
  default = 223442
}

variable "export_read_write_access_source" {
  default = "10.0.0.0/8"
}

variable "export_read_only_access_source" {
  default = "0.0.0.0/0"
}

variable "export_path_fs1_mt1" {
  default = "/mnt/fs1"
}

variable "export_set_name_1" {
  default = "export set for mount target 1"
}
```

##### File Storage の作成

```file_system.tf
resource "oci_file_storage_file_system" "TF_fs_1" {
  #Required
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"

  #Optional
  display_name = "${var.file_system_1_display_name}"
}
```

##### Mount Targetの作成

```mount_target.tf
resource "oci_file_storage_mount_target" "TF_mount_target_1" {
  #Required
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
  subnet_id           = "${oci_core_subnet.TF_subnet.id}"

  #Optional
  display_name = "${var.mount_target_1_display_name}"
}
```

##### export / export set の作成

```export.tf
resource "oci_file_storage_export" "TF_export_fs1_mt1" {
  #Required
  export_set_id  = "${oci_file_storage_export_set.TF_export_set_1.id}"
  file_system_id = "${oci_file_storage_file_system.TF_fs_1.id}"
  path           = "${var.export_path_fs1_mt1}"

  export_options = [
    {
      source                         = "${var.export_read_write_access_source}"
      access                         = "READ_WRITE"
      identity_squash                = "NONE"
      require_privileged_source_port = true
    },
    {
      source                         = "${var.export_read_only_access_source}"
      access                         = "READ_ONLY"
      identity_squash                = "ALL"
      require_privileged_source_port = true
    },
  ]
}
```

```export_set.tf
resource "oci_file_storage_export_set" "TF_export_set_1" {
  # Required
  mount_target_id = "${oci_file_storage_mount_target.TF_mount_target_1.id}"

  # Optional
  display_name      = "${var.export_set_name_1}"
  max_fs_stat_bytes = "${var.max_byte}"
  max_fs_stat_files = "${var.max_files}"
}
```

# インスタンス の作成とFile Storageのマウント
変数の追加(Linux VM/VM.Standard2.1 シェイプ を 2つ作成）

```variables.tf
variable "NumInstances" {
  default = "2"
}
variable "instance_image_ocid" {
  type = "map"

  default = {
    // See https://docs.us-phoenix-1.oraclecloud.com/images/
    // Oracle-provided image "Oracle-Linux-7.5-2018.05.09-1"
    us-ashburn-1 = "ocid1.image.oc1.iad.aaaaaaaaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  }
}

variable "instance_shape" {
  default = "VM.Standard2.1"
}

locals {
  mount_target_1_ip_address = "${lookup(data.oci_core_private_ips.ip_mount_target1.private_ips[0], "ip_address")}"
}
```

「`NumInstances`」で作成するインスタンスの数を指定します。
そのほか作成するインスタンスのシェイプ、イメージを指定します。

data_sources.tfへの追加

```data_sources.tf
# Gets the list of file systems in the compartment
data "oci_file_storage_file_systems" "file_systems" {
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
}

# Gets the list of mount targets in the compartment
data "oci_file_storage_mount_targets" "mount_targets" {
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
}

# Gets the list of exports in the compartment
data "oci_file_storage_exports" "exports" {
  compartment_id = "${var.compartment_ocid}"
}

# Gets a list of snapshots for a particular file system
data "oci_file_storage_snapshots" "snapshots" {
  file_system_id = "${oci_file_storage_file_system.TF_fs_1.id}"
}

# Gets a list of export sets in a compartment and availability domain
data "oci_file_storage_export_sets" "export_sets" {
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
}

data "oci_core_private_ips" ip_mount_target1 {
  subnet_id = "${oci_file_storage_mount_target.TF_mount_target_1.subnet_id}"

  filter {
    name   = "id"
    values = ["${oci_file_storage_mount_target.TF_mount_target_1.private_ip_ids.0}"]
  }
}
```

作成したFile Storageに関してマウントに必要な情報を取得します。

```instance.tf
resource "oci_core_instance" "TF_instance" {
  count               = "${var.NumInstances}"
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
  display_name        = "TF instance${count.index}"
  hostname_label      = "TFinstance${count.index}"
  shape               = "${var.instance_shape}"
  subnet_id           = "${oci_core_subnet.TF_subnet.id}"

  metadata {
    ssh_authorized_keys = "${var.ssh_public_key}"
  }

  source_details {
    source_type = "image"
    source_id   = "${var.instance_image_ocid[var.region]}"
  }

  timeouts {
    create = "60m"
  }

}

resource "null_resource" "mount_fss_on_instance" {
  depends_on = ["oci_core_instance.TF_instance",
    "oci_file_storage_export.TF_export_fs1_mt1",
  ]
  count               = "${var.NumInstances}"

  provisioner "remote-exec" {
    connection {
      agent       = false
      timeout     = "15m"
      host        = "${oci_core_instance.TF_instance.*.public_ip[count.index % var.NumInstances]}"
      user        = "opc"
      private_key = "${var.ssh_private_key}"
    }

    inline = [
      "sudo yum -y install nfs-utils > nfs-utils-install.log",
      "sudo mkdir -p /mnt/fs1",
      "sudo mount ${local.mount_target_1_ip_address}:${var.export_path_fs1_mt1} ${var.export_path_fs1_mt1}",
    ]
  }

}
```
「`resource`」 「`null_resource`」でOS起動後にマウント用のディレクトリ作成、マウントの実行をするコマンドを記述します。

# 環境構築の実行
#### すべてのファイルが用意できたら以下のコマンドを実行し環境を作成します。

- terraform init
- terraform plan -out plan01
- terraform apply "plan01"



# 作成されたインスタンスの確認

##### instance0 への接続
10.0.1.5:/mnt/fs1 が /mnt/fs1 にマウントされていることを確認

```
[opc@tfinstance0 ~]$ df -h
Filesystem         Size  Used Avail Use% Mounted on
devtmpfs           7.2G     0  7.2G   0% /dev
tmpfs              7.3G     0  7.3G   0% /dev/shm
tmpfs              7.3G  8.6M  7.3G   1% /run
tmpfs              7.3G     0  7.3G   0% /sys/fs/cgroup
/dev/sda3           39G  2.0G   37G   6% /
/dev/sda1          512M  9.8M  502M   2% /boot/efi
10.0.1.5:/mnt/fs1   23G     0   23G   0% /mnt/fs1
tmpfs              1.5G     0  1.5G   0% /run/user/1000
```

##### instance1 への接続
10.0.1.5:/mnt/fs1 が /mnt/fs1 にマウントされていることを確認

```
[opc@tfinstance1 ~]$ df -h
Filesystem         Size  Used Avail Use% Mounted on
devtmpfs           7.2G     0  7.2G   0% /dev
tmpfs              7.3G     0  7.3G   0% /dev/shm
tmpfs              7.3G  8.6M  7.3G   1% /run
tmpfs              7.3G     0  7.3G   0% /sys/fs/cgroup
/dev/sda3           39G  2.0G   37G   6% /
/dev/sda1          512M  9.8M  502M   2% /boot/efi
10.0.1.5:/mnt/fs1   23G     0   23G   0% /mnt/fs1
tmpfs              1.5G     0  1.5G   0% /run/user/1000
```

##### instance0 で作成したディレクトリに instance1 でファイルを作成し、そのファイルが instance0 で 確認できることを確認

```instance0
[opc@tfinstance0 ~]$ ls /mnt/fs1
[opc@tfinstance0 ~]$ sudo mkdir /mnt/fs1/test01
```

```instance1
[opc@tfinstance1 ~]$ ls /mnt/fs1/
test01
[opc@tfinstance1 ~]$ sudo touch /mnt/fs1/test01/sample.txt
```

```instance0
[opc@tfinstance0 ~]$ ls /mnt/fs1/test01/
sample.txt
```

# おわりに
terraform を使って 複数インスタンスの共有用ファイルシステムとしてFile Storage Serviceがマウントできることを確認しました。

```data_sources.tf
# Gets the list of file systems in the compartment
data "oci_file_storage_file_systems" "file_systems" {
  #Required
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"

  #Optional fields. Used by the service to filter the results when returning data to the client.
  #display_name = "TF_fs_1"
  #id = "ocid1.filesystem.oc1.phx.aaaaaaaaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  #state = "DELETED"
}

# Gets the list of mount targets in the compartment
data "oci_file_storage_mount_targets" "mount_targets" {
  #Required
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"

  #Optional fields. Used by the service to filter the results when returning data to the client.
  #display_name = "${var.mount_target_display_name}"
  #export_set_id = "${var.mount_target_export_set_id}"
  #id = "${var.mount_target_id}"
  #state = "${var.mount_target_state}"
}

# Gets the list of exports in the compartment
data "oci_file_storage_exports" "exports" {
  #Required
  compartment_id = "${var.compartment_ocid}"

  #Optional fields. Used by the service to filter the results when returning data to the client.
  #export_set_id = "${oci_file_storage_mount_target.TF_mount_target_1.export_set_id}"
  #file_system_id = "${oci_file_storage_file_system.TF_fs.id}"
  #id = "${var.export_id}"
  #state = "${var.export_state}"
}

# Gets a list of snapshots for a particular file system
data "oci_file_storage_snapshots" "snapshots" {
  #Required
  file_system_id = "${oci_file_storage_file_system.TF_fs_1.id}"

  #Optional fields. Used by the service to filter the results when returning data to the client.
  #id = "${var.snapshot_id}"
  #state = "${var.snapshot_state}"
}

# Gets a list of export sets in a compartment and availability domain
data "oci_file_storage_export_sets" "export_sets" {
  #Required
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"

  #Optional fields. Used by the service to filter the results when returning data to the client.
  #display_name = "${var.export_set_display_name}"
  #id = "${var.export_set_id}"
  #state = "${var.export_set_state}"
}

data "oci_core_private_ips" ip_mount_target1 {
  subnet_id = "${oci_file_storage_mount_target.TF_mount_target_1.subnet_id}"

  filter {
    name   = "id"
    values = ["${oci_file_storage_mount_target.TF_mount_target_1.private_ip_ids.0}"]
  }
}
```

```export.tf
resource "oci_file_storage_export" "TF_export_fs1_mt1" {
  #Required
  export_set_id  = "${oci_file_storage_export_set.TF_export_set_1.id}"
  file_system_id = "${oci_file_storage_file_system.TF_fs_1.id}"
  path           = "${var.export_path_fs1_mt1}"

  export_options = [
    {
      source                         = "${var.export_read_write_access_source}"
      access                         = "READ_WRITE"
      identity_squash                = "NONE"
      require_privileged_source_port = true
    },
    {
      source                         = "${var.export_read_only_access_source}"
      access                         = "READ_ONLY"
      identity_squash                = "ALL"
      require_privileged_source_port = true
    },
  ]
}

```

```export_set.tf
resource "oci_file_storage_export_set" "TF_export_set_1" {
  # Required
  mount_target_id = "${oci_file_storage_mount_target.TF_mount_target_1.id}"

  # Optional
  display_name      = "${var.export_set_name_1}"
  max_fs_stat_bytes = "${var.max_byte}"
  max_fs_stat_files = "${var.max_files}"
}

```

```file_system.tf
resource "oci_file_storage_file_system" "TF_fs_1" {
  #Required
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"

  #Optional
  display_name = "${var.file_system_1_display_name}"
}
```

```instance.tf
resource "oci_core_instance" "TF_instance" {
  count               = "${var.NumInstances}"
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
  display_name        = "TF instance${count.index}"
  hostname_label      = "TFinstance${count.index}"
  shape               = "${var.instance_shape}"
  subnet_id           = "${oci_core_subnet.TF_subnet.id}"

  metadata {
    ssh_authorized_keys = "${var.ssh_public_key}"
  }

  source_details {
    source_type = "image"
    source_id   = "${var.instance_image_ocid[var.region]}"
  }

  timeouts {
    create = "60m"
  }

}

resource "null_resource" "mount_fss_on_instance" {
  depends_on = ["oci_core_instance.TF_instance",
    "oci_file_storage_export.TF_export_fs1_mt1",
  ]
  count               = "${var.NumInstances}"

  provisioner "remote-exec" {
    connection {
      agent       = false
      timeout     = "15m"
      host        = "${oci_core_instance.TF_instance.*.public_ip[count.index % var.NumInstances]}"
      user        = "opc"
      private_key = "${var.ssh_private_key}"
    }

    inline = [
      "sudo yum -y install nfs-utils > nfs-utils-install.log",
      "sudo mkdir -p /mnt/fs1",
      "sudo mount ${local.mount_target_1_ip_address}:${var.export_path_fs1_mt1} ${var.export_path_fs1_mt1}",
    ]
  }

}
```

```mount_target.tf
resource "oci_file_storage_mount_target" "TF_mount_target_1" {
  #Required
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
  subnet_id           = "${oci_core_subnet.TF_subnet.id}"

  #Optional
  display_name = "${var.mount_target_1_display_name}"
}

```

```network.tf
resource "oci_core_virtual_network" "TF_vcn" {
  cidr_block     = "${var.TF_vcn-cidr}"
  dns_label      = "TFvcn"
  compartment_id = "${var.compartment_ocid}"
  display_name   = "TFvcn"
  dns_label      = "TFvcn"
}

resource "oci_core_internet_gateway" "TF_internet_gateway" {
  compartment_id = "${var.compartment_ocid}"
  display_name   = "TF internet gateway"
  vcn_id         = "${oci_core_virtual_network.TF_vcn.id}"
}

resource "oci_core_route_table" "TF_route_table" {
  compartment_id = "${var.compartment_ocid}"
  vcn_id         = "${oci_core_virtual_network.TF_vcn.id}"
  display_name   = "TF route table"

  route_rules {
    destination       = "0.0.0.0/0"
    destination_type  = "CIDR_BLOCK"
    network_entity_id = "${oci_core_internet_gateway.TF_internet_gateway.id}"
  }
}

resource "oci_core_subnet" "TF_subnet" {
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  cidr_block          = "${var.TF_subnet_cidr}"
  display_name        = "TFsubnet"
  dns_label           = "TFsubnet"
  compartment_id      = "${var.compartment_ocid}"
  vcn_id              = "${oci_core_virtual_network.TF_vcn.id}"
  security_list_ids   = ["${oci_core_security_list.TF_security_list.id}"]
  route_table_id      = "${oci_core_route_table.TF_route_table.id}"
}
```

```provider.tf
provider "oci" {
  version          = ">= 3.0.0"
  tenancy_ocid     = "${var.tenancy_ocid}"
  user_ocid        = "${var.user_ocid}"
  fingerprint      = "${var.fingerprint}"
  private_key_path = "${var.private_key_path}"
  region           = "${var.region}"
}
```

```security_list.tf
# Protocols are specified as protocol numbers.
# http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml

resource "oci_core_security_list" "TF_security_list" {
  compartment_id = "${var.compartment_ocid}"
  display_name   = "TF_security_list"
  vcn_id         = "${oci_core_virtual_network.TF_vcn.id}"

  // Allow all outbound requests
  egress_security_rules = [
    {
      destination = "0.0.0.0/0"
      protocol    = "all"
    },
  ]

  // See https://docs.us-phoenix-1.oraclecloud.com/Content/File/Tasks/creatingfilesystems.htm.
  // Specific security list rules are required to allow mount targets to work properly.
  ingress_security_rules = [
    {
      protocol = "6"
      source   = "${var.TF_vcn-cidr}"

      tcp_options {
        "min" = 2048
        "max" = 2050
      }
    },
    {
      protocol = "6"
      source   = "${var.TF_vcn-cidr}"

      tcp_options {
        source_port_range {
          "min" = 2048
          "max" = 2050
        }
      }
    },
    {
      protocol = "6"
      source   = "${var.TF_vcn-cidr}"

      tcp_options {
        "min" = 111
        "max" = 111
      }
    },
    {
      // Allowing inbound SSH traffic to instances in the subnet from any source
      protocol = "6"
      source   = "0.0.0.0/0"

      tcp_options {
        "min" = 22
        "max" = 22
      }
    },
    {
      // Allowing inbound ICMP traffic of a specific type and code from any source
      protocol = 1
      source   = "0.0.0.0/0"

      icmp_options {
        "type" = 3
        "code" = 4
      }
    },
    {
      // Allowing inbound ICMP traffic of a specific type from within our VCN
      protocol = 1
      source   = "${var.TF_vcn-cidr}"

      icmp_options {
        "type" = 3
      }
    },
  ]
}
```

```variables.tf
variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "region" {}

variable "compartment_ocid" {}

# Refer https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/managingkeypairs.htm on how to setup SSH key pairs for compute instances
variable "ssh_public_key" {}

variable "ssh_private_key" {}

variable "NumInstances" {
  default = "2"
}

# Choose an Availability Domain
variable "availability_domain" {
  default = "2"
}

variable "TF_vcn-cidr" {
  default = "10.0.0.0/16"
}

variable "TF_subnet_cidr" {
  default = "10.0.1.0/24"
}

variable "file_system_1_display_name" {
  default = "TF_fs_1"
}

variable "mount_target_1_display_name" {
  default = "my_mount_target_1"
}

variable "export_path_fs1_mt1" {
  default = "/mnt/fs1"
}

variable "export_set_name_1" {
  default = "export set for mount target 1"
}

variable "max_byte" {
  default = 23843202333
}

variable "max_files" {
  default = 223442
}

variable "export_read_write_access_source" {
  default = "10.0.0.0/8"
}

variable "export_read_only_access_source" {
  default = "0.0.0.0/0"
}

variable "instance_image_ocid" {
  type = "map"

  default = {
    // See https://docs.us-phoenix-1.oraclecloud.com/images/
    // Oracle-provided image "Oracle-Linux-7.5-2018.05.09-1"
    eu-frankfurt-1 = "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaazregkysspxnktw35k4r5vzwurxk6myu44umqthjeakbkvxvxdlkq"

    us-ashburn-1 = "ocid1.image.oc1.iad.aaaaaaaa6ybn2lkqp2ejhijhehf5i65spqh3igt53iyvncyjmo7uhm5235ca"
    uk-london-1  = "ocid1.image.oc1.uk-london-1.aaaaaaaayodsld656eh5stds5mo4hrmwuhk2ugin4eyfpgoiiskqfxll6a4a"
    us-phoenix-1 = "ocid1.image.oc1.phx.aaaaaaaaozjbzisykoybkppaiwviyfzusjzokq7jzwxi7nvwdiopk7ligoia"
  }
}

variable "instance_shape" {
  default = "VM.Standard2.1"
}

locals {
  mount_target_1_ip_address = "${lookup(data.oci_core_private_ips.ip_mount_target1.private_ips[0], "ip_address")}"
}
```