Terraformのoci pluginを使って、作成済みOracle Cloud(OCI)リソースのconfiguration fileとstate fileを出力する

2019/12/13 新規作成
***

この記事は [Oracle Cloud Infrastructure Advent Calendar 2019](https://adventar.org/calendars/4516) の12/13の記事として書かれています。

※ Adventの記事なのに、きれいに終わらなかった…

# 1.はじめに
## やりたいこと
- OCIの特定コンパートメントに作成済みの全てのOCIリソースをTerraformで管理できるようにする
（指定したコンパートメント内の全リソースのTerraform configuration fileとstate fileを出力し、利用する）

-> 結果：出力は出来たけど、管理化に置くとこまでは至らなかった（DBCSの管理に失敗中）。

## 前提・検証環境
### 前提
- terraformが使える状態であること

### 環境
- 実行環境はOracle Linux 7.7
- Terraformのversionは0.12.17
- oci plugin(terraform-provider-oci)のverstionは3.55.0
- oci cliのversionは2.6.15
- OCIに手動で以下の環境を構築済み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109270/ec25cff0-e762-ccaf-0427-56f2dc890843.png)

※ NWリソースはクイックスタートで作成し、セキュリティリストを後から編集

# 2.準備

## 各種OCIの情報を確認・メモ
terraformを実行する際に必要なOCIの各種情報を確認し、メモしておきます（確認方法は省略します）。
必要な情報は以下です。

- テナンシーOCID
- ユーザーOCID
- APIキーのfinger print
- リージョン名
- 秘密鍵のローカルパス

## terraform init
terraform-oci-providerのversion 3.50より導入されたResource Discoveryというツールを使用するため、3.50以上のterraform-oci-providerをインストールします。すでに3.50以上のterraform-oci-providerを使用可能な状態の場合は、本手順は省略できます。

### ディレクトリ作成
作成済みのOCIリソースをterraformで管理するために使用するディレクトリ（フォルダ）を作成します。

```
$ mkdir -p work/terraform/oci/20191213_Qiita
$ ls -ld work/terraform/oci/20191213_Qiita
drwxrwxr-x. 2 opc opc 6 Dec 13 04:09 work/terraform/oci/20191213_Qiiiita
```

### provider.tf作成
ociのplug inをインストールするため、プロバイダー情報を渡すファイルを用意します（以下に記載のものをそのままコピーでOK）。

```provider.tf
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}"
}
```

### provider-var.tf作成
変数を定義するtfファイルを作成します。先ほど確認した情報をdefault値として記載しています。

```provider-var.tf
variable "tenancy_ocid" {
  default = "ocid1.tenancy.oc1..xxxxxxxxxxx"
}
variable "user_ocid" {
  default = "ocid1.user.oc1..xxxxxxxxxxx"
}
variable "fingerprint" {
  default = "00:4b:03:00:xxxx"
}
variable "private_key_path" {
  default = "/home/opc/.ssh/oci_api_key.pem"
}
variable "region" {
  default = "ap-tokyo-1"
}
```

※ Terraform実行のために必要なファイルなどの説明は、拙記事「[TerraformでOracle Cloud(OCI)の基本的なリソースを一通り作ってみた](https://qiita.com/feifo/items/2ca1f8451fb7f74d77c5#%E5%A4%89%E6%95%B0%E3%81%AE%E5%AE%A3%E8%A8%80)」で書きましたのでご参考までに。

### terraform initの実行
この状態でterraform initを実行します。provider情報を参照して、ociのplug inをインストールしてくれます。

```shell
$ terraform init

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "oci" (hashicorp/oci) 3.55.0...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.oci: version = "~> 3.55"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
```

完了すると、「.terraform」というディレクトリが生成され、さらに中をたどっていくと、「terraform-provider-oci_v3.55.0_x4.exe」という実行ファイルが確認できます。

```shell
$ ls -la work/terraform/oci/20191213_Qiita/.terraform/plugins/linux_amd64/terraform-provider-oci_v3.55.0_x4
-rwxr-xr-x. 1 opc opc 66824992 Dec 13 04:15 work/terraform/oci/20191213_Qiita/.terraform/plugins/linux_amd64/terraform-provider-oci_v3.55.0_x4
```

※ 指定しない限り、実行時点の最新バージョンがインストールされるので、数字は違うかもしれません。また、環境によって生成されるディレクトリの名前も異なります（例えばwindowsだと「windows_amd64」）。

準備はここまでです。

# 3.configuration fileとstate fileを出力

## terraform-provider-ociの実行
[2.準備](#2準備)でインストールした「terraform-provider-oci_v3.55.0_x4」を実行します。PATHを通してもいいですが、ここでは直接叩きます。

### 構文
`terraform-provider-oci -command=export -compartment_name=<compartment to export> -output_path=<directory under which to generate Terraform files> -generate_state`

- -command=export ： configuration fileを出力させるためのコマンド
- -compartment_name ：コンパートメントを名前で指定
- -output_path= ： ファイルの出力先を指定
- -generate_state ：stateファイルを生成させるためのオプション 

※ 他にも以下のようなオプションがあります。

- -compartment_id= ： 対象リソースが配置されているコンパートメントをOCIDで指定
- - ids ：コンパートメント内の特定リソースを指定（複数指定可）
- services ：コンパートメント内の特手サービスを指定（core, databaseなど。複数指定可）


### 実行例

```
$ ./.terraform/plugins/linux_amd64/terraform-provider-oci_v3.55.0_x4 -command=export -compartment_name=test -output_path=/home/opc/work/terraform/oci/20191213_Qiita -generate_state
2019/12/13 04:42:25 [INFO] terraform-provider-oci.55.0
2019/12/13 04:42:25 [INFO] resolved compartment name 'test' to compartment id 'ocid1.compartment.oc1..aaaaaaaanxxxxxxxxxxx'
2019/12/13 04:42:25 Running export command
2019/12/13 04:42:25 [INFO] resource discovery: visiting oci_identity_compartment.export
2019/12/13 04:42:25 [INFO] discovering resources with data source 'oci_identity_availability_domains'
2019/12/13 04:42:26 [INFO] resource discovery: visiting oci_identity_availability_domain.export_GBRF-AP-TOKYO-1-AD-1
2019/12/13 04:42:26 [INFO] discovering resources with data source 'oci_core_boot_volumes'
2019/12/13 04:42:26 [INFO] adding datasource query attribute 'availability_domain' from parent attribute 'name'
2019/12/13 04:42:26 [INFO] resource discovery: visiting oci_identity_compartment.export
2019/12/13 04:42:26 [INFO] discovering resources with data source 'oci_core_cpes'
2019/12/13 04:42:26 [INFO] discovering resources with data source 'oci_core_cross_connect_groups'
2019/12/13 04:42:26 [INFO] discovering resources with data source 'oci_core_cross_connects'
2019/12/13 04:42:26 [INFO] discovering resources with data source 'oci_core_drg_attachments'
2019/12/13 04:42:26 [INFO] discovering resources with data source 'oci_core_drgs'
2019/12/13 04:42:26 [INFO] discovering resources with data source 'oci_core_images'
2019/12/13 04:42:26 [INFO] discovering resources with data source 'oci_core_instance_configurations'

（中略）

2019/12/13 04:42:31 [INFO] ===> Generating resource 'oci_core_instance.export_compute1'
2019/12/13 04:42:31 [INFO] Optional TF attribute 'dedicated_vm_host_id' not found in source
2019/12/13 04:42:31 [INFO] Optional TF attribute 'ipxe_script' not found in source
2019/12/13 04:42:31 [INFO] Optional TF attribute 'is_pv_encryption_in_transit_enabled' not found in source
2019/12/13 04:42:31 [INFO] Optional TF attribute 'preserve_boot_volume' not found in source
2019/12/13 04:42:31 [INFO] Optional TF attribute 'boot_volume_size_in_gbs' not found in source
2019/12/13 04:42:31 [INFO] Optional TF attribute 'kms_key_id' not found in source

（中略）

2019/12/13 04:43:06 [TRACE] statemgr.Filesystem: creating backup snapshot at /home/opc/work/terraform/oci/20191213_Qiita/terraform.tfstate.tmp.backup
2019/12/13 04:43:06 [TRACE] statemgr.Filesystem: state has changed since last snapshot, so incrementing serial to 14
2019/12/13 04:43:06 [TRACE] statemgr.Filesystem: writing snapshot at /home/opc/work/terraform/oci/20191213_Qiita/terraform.tfstate.tmp

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

2019/12/13 04:43:06 [TRACE] statemgr.Filesystem: removing lock metadata file /home/opc/work/terraform/oci/20191213_Qiita/.terraform.tfstate.tmp.lock.info
2019/12/13 04:43:06 [TRACE] statemgr.Filesystem: unlocking /home/opc/work/terraform/oci/20191213_Qiita/terraform.tfstate.tmp using fcntl flock
2019/12/13 04:43:06 [INFO] ===> Importing resource 'oci_objectstorage_namespace.export_ns'
2019/12/13 04:43:06 [INFO] skip importing 'oci_objectstorage_namespace.export_ns' since it is not a Terraform OCI resource
Found 1 'availability_domain' resources. Generated under '/home/opc/work/terraform/oci/20191213_Qiita/availability_domain.tf'
Found 13 'core' resources. Generated under '/home/opc/work/terraform/oci/20191213_Qiita/core.tf'
Found 1 'database' resources. Generated under '/home/opc/work/terraform/oci/20191213_Qiita/database.tf'
Found 0 'load_balancer' resources. Generated under '/home/opc/work/terraform/oci/20191213_Qiita/load_balancer.tf'
Found 1 'object_storage' resources. Generated under '/home/opc/work/terraform/oci/20191213_Qiita/object_storage.tf'
Found 0 'tagging' resources. Generated under '/home/opc/work/terraform/oci/20191213_Qiita/tagging.tf'

Warning: There are one or more 'Required' attributes for which a value could not be discovered.
This may be expected behavior from the service, which may prevent discovery of certain sensitive attributes or secrets.
Run 'terraform plan' against the generated configuration files to get more information about the missing values.

=== COMPLETED ===
```

## 出力されたファイル
以下のファイルが出力されました。作成・使用していないサービスのconfigファイルも出力されるようです。また、output.tfは作ってはくれなさそうです（そりゃそうか）。


```
$ ll
total 108
-rw-rw-r--. 1 opc opc   201 Dec 13 04:27 availability_domain.tf
-rw-rw-r--. 1 opc opc 11890 Dec 13 04:27 core.tf
-rw-rw-r--. 1 opc opc  2251 Dec 13 04:27 database.tf
-rw-rw-r--. 1 opc opc    63 Dec 13 04:27 load_balancer.tf
-rw-rw-r--. 1 opc opc   155 Dec 13 04:27 object_storage.tf
-rw-rw-r--. 1 opc opc   202 Dec 13 04:15 provider.tf
-rw-rw-r--. 1 opc opc   452 Dec 13 04:27 provider-var.tf
-rw-rw-r--. 1 opc opc    63 Dec 13 04:27 tagging.tf
-rw-rw-r--. 1 opc opc 33151 Dec 13 04:28 terraform.tfstate
-rw-rw-r--. 1 opc opc 27535 Dec 13 04:28 terraform.tfstate.tmp.backup
-rw-rw-r--. 1 opc opc   319 Dec 13 04:27 vars.tf
```


### availability_domain.tf

<details>
<summary>availability_domain.tf</summary>
<div>

```shell
## This configuration was generated by terraform-provider-oci

data oci_identity_availability_domain export_GBRF-AP-TOKYO-1-AD-1 {
  compartment_id = "${var.compartment_ocid}"
  ad_number      = "1"
}

```

</div>
</details>

### core.tf

<details>
<summary>core.tf</summary>
<div>

```shell
## This configuration was generated by terraform-provider-oci

resource oci_core_instance export_compute1 {
  agent_config {
    is_monitoring_disabled = "false"
  }

  availability_domain = "${data.oci_identity_availability_domain.export_GBRF-AP-TOKYO-1-AD-1.name}"
  compartment_id      = "${var.compartment_ocid}"

  create_vnic_details {
    assign_public_ip = "true"
    defined_tags     = {}

    display_name  = "compute1"
    freeform_tags = {}

    hostname_label = "compute1"
    nsg_ids        = []

    private_ip             = "10.0.0.2"
    skip_source_dest_check = "false"
    subnet_id              = "${oci_core_subnet.export_Public-Subnet-VCN1.id}"
  }

  #dedicated_vm_host_id = <<Optional value not found in discovery>>
  defined_tags = {}

  display_name      = "compute1"
  extended_metadata = {}

  fault_domain  = "FAULT-DOMAIN-3"
  freeform_tags = {}

  #ipxe_script = <<Optional value not found in discovery>>
  #is_pv_encryption_in_transit_enabled = <<Optional value not found in discovery>>
  launch_options {
    boot_volume_type                    = "PARAVIRTUALIZED"
    firmware                            = "UEFI_64"
    is_consistent_volume_naming_enabled = "true"
    is_pv_encryption_in_transit_enabled = "true"
    network_type                        = "PARAVIRTUALIZED"
    remote_data_volume_type             = "PARAVIRTUALIZED"
  }

  metadata = {
    "ssh_authorized_keys" = "ssh-rsa AAAAB3Nzxxxxxxxx"
  }

  #preserve_boot_volume = <<Optional value not found in discovery>>
  shape = "VM.Standard2.1"

  source_details {
    #boot_volume_size_in_gbs = <<Optional value not found in discovery>>
    #kms_key_id = <<Optional value not found in discovery>>
    source_id = "${var.export_compute2_source_image_id}"

    source_type = "image"
  }

  state = "RUNNING"
}

resource oci_core_instance export_compute2 {
  agent_config {
    is_monitoring_disabled = "false"
  }

  availability_domain = "${data.oci_identity_availability_domain.export_GBRF-AP-TOKYO-1-AD-1.name}"
  compartment_id      = "${var.compartment_ocid}"

  create_vnic_details {
    assign_public_ip = "true"
    defined_tags     = {}

    display_name  = "compute2"
    freeform_tags = {}

    hostname_label = "compute2"
    nsg_ids        = []

    private_ip             = "10.0.0.3"
    skip_source_dest_check = "false"
    subnet_id              = "${oci_core_subnet.export_Public-Subnet-VCN1.id}"
  }

  #dedicated_vm_host_id = <<Optional value not found in discovery>>
  defined_tags = {}

  display_name      = "compute2"
  extended_metadata = {}

  fault_domain  = "FAULT-DOMAIN-3"
  freeform_tags = {}

  #ipxe_script = <<Optional value not found in discovery>>
  #is_pv_encryption_in_transit_enabled = <<Optional value not found in discovery>>
  launch_options {
    boot_volume_type                    = "PARAVIRTUALIZED"
    firmware                            = "UEFI_64"
    is_consistent_volume_naming_enabled = "true"
    is_pv_encryption_in_transit_enabled = "true"
    network_type                        = "PARAVIRTUALIZED"
    remote_data_volume_type             = "PARAVIRTUALIZED"
  }

  metadata = {
    "ssh_authorized_keys" = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzVgnno6hXcLInzzwbdP69m3wEG8cGZTGFlJilq6pQCvlpksk70X1IurlUZWI0eMqICpA/wbEthSyMjeyIKRumtBi/Li2cdV/Ep2ekFeAuZ6i1hJhE+z7DtbyGxmBimfwoch5v+K3Q/uemmh3a9UqGijLH5WRvqtODI6hIdGYEXahUp5LiKfzpYPsRDnujhuKHXsrZVc4O3zK/ElRBTv1ZkZGZ3WS4HGcBVoW6lAfvHSnUx+2S0kyNBw2OP5N2fSRsxEjtHJbb/N+qEF9gETwK7KbO8HV/p8DaY/jAKdt4eYUk66tKMSpRBQRIQnxQihDzxmxCB9yP4Qte77MkIDHKw== aktanaka@AKTANAKA-JP"
  }

  #preserve_boot_volume = <<Optional value not found in discovery>>
  shape = "VM.Standard2.1"

  source_details {
    #boot_volume_size_in_gbs = <<Optional value not found in discovery>>
    #kms_key_id = <<Optional value not found in discovery>>
    source_id = "${var.export_compute2_source_image_id}"

    source_type = "image"
  }

  state = "RUNNING"
}

resource oci_core_service_gateway export_Service-Gateway-VCN1 {
  compartment_id = "${var.compartment_ocid}"
  defined_tags   = {}

  display_name = "Service Gateway-VCN1"

  freeform_tags = {
    "VCN" = "VCN-2019-12-13T01:24:51"
  }

  #route_table_id = <<Optional value not found in discovery>>
  services {
    service_id = "ocid1.service.oc1.ap-tokyo-1.aaaaaaaasijciseg5tzfchafero765m7yvl2dekfnayvyges6dnjnotlvzpa"
  }

  vcn_id = "${oci_core_vcn.export_VCN1.id}"
}

resource oci_core_vcn export_VCN1 {
  cidr_block     = "10.0.0.0/16"
  compartment_id = "${var.compartment_ocid}"
  defined_tags   = {}

  display_name = "VCN1"
  dns_label    = "vcn1"

  freeform_tags = {
    "VCN" = "VCN-2019-12-13T01:24:51"
  }

  #ipv6cidr_block = <<Optional value not found in discovery>>
  #is_ipv6enabled = <<Optional value not found in discovery>>
}

resource oci_core_default_dhcp_options export_Default-DHCP-Options-for-VCN1 {
  defined_tags = {}

  display_name = "Default DHCP Options for VCN1"

  freeform_tags = {
    "VCN" = "VCN-2019-12-13T01:24:51"
  }

  manage_default_resource_id = "${oci_core_vcn.export_VCN1.default_dhcp_options_id}"

  options {
    custom_dns_servers = []

    #search_domain_names = <<Optional value not found in discovery>>
    server_type = "VcnLocalPlusInternet"
    type        = "DomainNameServer"
  }

  options {
    #custom_dns_servers = <<Optional value not found in discovery>>
    search_domain_names = [
      "vcn1.oraclevcn.com",
    ]

    #server_type = <<Optional value not found in discovery>>
    type = "SearchDomain"
  }
}

resource oci_core_internet_gateway export_Internet-Gateway-VCN1 {
  compartment_id = "${var.compartment_ocid}"
  defined_tags   = {}

  display_name = "Internet Gateway-VCN1"
  enabled      = "true"

  freeform_tags = {
    "VCN" = "VCN-2019-12-13T01:24:51"
  }

  vcn_id = "${oci_core_vcn.export_VCN1.id}"
}

resource oci_core_nat_gateway export_NAT-Gateway-VCN1 {
  block_traffic  = "false"
  compartment_id = "${var.compartment_ocid}"
  defined_tags   = {}

  display_name = "NAT Gateway-VCN1"

  freeform_tags = {
    "VCN" = "VCN-2019-12-13T01:24:51"
  }

  vcn_id = "${oci_core_vcn.export_VCN1.id}"
}

resource oci_core_route_table export_Route-Table-for-Private-Subnet-VCN1 {
  compartment_id = "${var.compartment_ocid}"
  defined_tags   = {}

  display_name = "Route Table for Private Subnet-VCN1"

  freeform_tags = {
    "VCN" = "VCN-2019-12-13T01:24:51"
  }

  route_rules {
    destination       = "0.0.0.0/0"
    destination_type  = "CIDR_BLOCK"
    network_entity_id = "${oci_core_nat_gateway.export_NAT-Gateway-VCN1.id}"
  }

  route_rules {
    destination       = "all-nrt-services-in-oracle-services-network"
    destination_type  = "SERVICE_CIDR_BLOCK"
    network_entity_id = "${oci_core_service_gateway.export_Service-Gateway-VCN1.id}"
  }

  vcn_id = "${oci_core_vcn.export_VCN1.id}"
}

resource oci_core_default_route_table export_Default-Route-Table-for-VCN1 {
  defined_tags = {}

  display_name = "Default Route Table for VCN1"

  freeform_tags = {
    "VCN" = "VCN-2019-12-13T01:24:51"
  }

  manage_default_resource_id = "${oci_core_vcn.export_VCN1.default_route_table_id}"

  route_rules {
    destination       = "0.0.0.0/0"
    destination_type  = "CIDR_BLOCK"
    network_entity_id = "${oci_core_internet_gateway.export_Internet-Gateway-VCN1.id}"
  }
}

resource oci_core_security_list export_Security-List-for-Private-Subnet-VCN1 {
  compartment_id = "${var.compartment_ocid}"
  defined_tags   = {}

  display_name = "Security List for Private Subnet-VCN1"

  egress_security_rules {
    destination      = "0.0.0.0/0"
    destination_type = "CIDR_BLOCK"

    #icmp_options = <<Optional value not found in discovery>>
    protocol  = "all"
    stateless = "false"

    #tcp_options = <<Optional value not found in discovery>>
    #udp_options = <<Optional value not found in discovery>>
  }

  freeform_tags = {
    "VCN" = "VCN-2019-12-13T01:24:51"
  }

  ingress_security_rules {
    #icmp_options = <<Optional value not found in discovery>>
    protocol    = "6"
    source      = "10.0.0.0/16"
    source_type = "CIDR_BLOCK"
    stateless   = "false"

    #tcp_options = <<Optional value not found in discovery>>
    #udp_options = <<Optional value not found in discovery>>
  }

  ingress_security_rules {
    #icmp_options = <<Optional value not found in discovery>>
    protocol    = "1"
    source      = "10.0.0.0/16"
    source_type = "CIDR_BLOCK"
    stateless   = "false"

    #tcp_options = <<Optional value not found in discovery>>
    #udp_options = <<Optional value not found in discovery>>
  }

  vcn_id = "${oci_core_vcn.export_VCN1.id}"
}

resource oci_core_default_security_list export_Default-Security-List-for-VCN1 {
  defined_tags = {}

  display_name = "Default Security List for VCN1"

  egress_security_rules {
    destination      = "0.0.0.0/0"
    destination_type = "CIDR_BLOCK"

    #icmp_options = <<Optional value not found in discovery>>
    protocol  = "all"
    stateless = "false"

    #tcp_options = <<Optional value not found in discovery>>
    #udp_options = <<Optional value not found in discovery>>
  }

  freeform_tags = {
    "VCN" = "VCN-2019-12-13T01:24:51"
  }

  ingress_security_rules {
    #icmp_options = <<Optional value not found in discovery>>
    protocol    = "6"
    source      = "0.0.0.0/0"
    source_type = "CIDR_BLOCK"
    stateless   = "false"

    tcp_options {
      max = "22"
      min = "22"

      #source_port_range = <<Optional value not found in discovery>>
    }

    #udp_options = <<Optional value not found in discovery>>
  }

  ingress_security_rules {
    #icmp_options = <<Optional value not found in discovery>>
    protocol    = "1"
    source      = "0.0.0.0/0"
    source_type = "CIDR_BLOCK"
    stateless   = "false"

    #tcp_options = <<Optional value not found in discovery>>
    #udp_options = <<Optional value not found in discovery>>
  }

  manage_default_resource_id = "${oci_core_vcn.export_VCN1.default_security_list_id}"
}

resource oci_core_subnet export_Private-Subnet-VCN1 {
  #availability_domain = <<Optional value not found in discovery>>
  cidr_block     = "10.0.1.0/24"
  compartment_id = "${var.compartment_ocid}"
  defined_tags   = {}

  dhcp_options_id = "${oci_core_vcn.export_VCN1.default_dhcp_options_id}"
  display_name    = "Private Subnet-VCN1"
  dns_label       = "sub12130125211"

  freeform_tags = {
    "VCN" = "VCN-2019-12-13T01:24:51"
  }

  #ipv6cidr_block = <<Optional value not found in discovery>>
  prohibit_public_ip_on_vnic = "true"
  route_table_id             = "${oci_core_route_table.export_Route-Table-for-Private-Subnet-VCN1.id}"

  security_list_ids = [
    "${oci_core_security_list.export_Security-List-for-Private-Subnet-VCN1.id}",
  ]

  vcn_id = "${oci_core_vcn.export_VCN1.id}"
}

resource oci_core_subnet export_Public-Subnet-VCN1 {
  #availability_domain = <<Optional value not found in discovery>>
  cidr_block     = "10.0.0.0/24"
  compartment_id = "${var.compartment_ocid}"
  defined_tags   = {}

  dhcp_options_id = "${oci_core_vcn.export_VCN1.default_dhcp_options_id}"
  display_name    = "Public Subnet-VCN1"
  dns_label       = "sub12130125210"

  freeform_tags = {
    "VCN" = "VCN-2019-12-13T01:24:51"
  }

  #ipv6cidr_block = <<Optional value not found in discovery>>
  prohibit_public_ip_on_vnic = "false"
  route_table_id             = "${oci_core_vcn.export_VCN1.default_route_table_id}"

  security_list_ids = [
    "${oci_core_vcn.export_VCN1.default_security_list_id}",
  ]

  vcn_id = "${oci_core_vcn.export_VCN1.id}"
}
\```
</div></details>




```

</div>
</details>

### database.tf

<details>
<summary>database.tf</summary>
<div>

```shell
## This configuration was generated by terraform-provider-oci

resource oci_database_db_system export_DBSystem1 {
  availability_domain    = "${data.oci_identity_availability_domain.export_GBRF-AP-TOKYO-1-AD-1.name}"
  backup_network_nsg_ids = []

  #backup_subnet_id = <<Optional value not found in discovery>>
  #cluster_name = <<Optional value not found in discovery>>
  compartment_id = "${var.compartment_ocid}"

  cpu_core_count          = "1"
  data_storage_percentage = "80"
  data_storage_size_in_gb = "256"
  database_edition        = "STANDARD_EDITION"

  db_home {
    database {
      #admin_password = <<Required attribute not found in discovery>>
      #backup_id = <<Optional value not found in discovery>>
      #backup_tde_password = <<Optional value not found in discovery>>
      character_set = "AL32UTF8"

      db_backup_config {
        auto_backup_enabled     = "true"
        auto_backup_window      = ""
        recovery_window_in_days = "7"
      }

      db_name      = "DB1213"
      db_workload  = "OLTP"
      defined_tags = {}

      freeform_tags = {}

      ncharacter_set = "AL16UTF16"
      pdb_name       = "pdb01"
    }

    db_version   = "19.4.0.0.190716"
    display_name = "dbhome20191213012928"
  }

  db_system_options {
    storage_management = "ASM"
  }

  defined_tags = {}

  disk_redundancy = "HIGH"
  display_name    = "DBSystem1"
  domain          = "sub12130125211.vcn1.oraclevcn.com"

  fault_domains = [
    "FAULT-DOMAIN-2",
  ]

  freeform_tags = {}

  hostname      = "dbhost1"
  license_model = "LICENSE_INCLUDED"
  node_count    = "1"
  nsg_ids       = []

  shape  = "VM.Standard2.1"
  source = "NONE"

  #sparse_diskgroup = <<Optional value not found in discovery>>
  ssh_public_keys = [
    "ssh-rsa AAAAB3NzaC1xxxxxxxxxxxxxxxxx",
  ]

  subnet_id = "${oci_core_subnet.export_Private-Subnet-VCN1.id}"
  time_zone = "UTC"
}
```

</div>
</details>

→DBCSの管理者パスワードのようなクレデンシャル情報は抽出できない仕様となっているので、以下のようなカタチで出力されている。

```
  db_home {
    database {
      #admin_password = <<Required attribute not found in discovery>>
      #backup_id = <<Optional value not found in discovery>>
      #backup_tde_password = <<Optional value not found in discovery>>
```

### loadbalancer.tf

<details>
<summary>load_balancer.tf</summary>
<div>

```shell
## This configuration was generated by terraform-provider-oci

```

</div>
</details>

### object_storage.tf

<details>
<summary>object_storage.tf</summary>
<div>

```shell
## This configuration was generated by terraform-provider-oci

data oci_objectstorage_namespace export_ns {
  compartment_id = "${var.compartment_ocid}"
}
```

</div>
</details>

### tagging.tf

<details>
<summary>tagging.tf</summary>
<div>

```shell
## This configuration was generated by terraform-provider-oci

```

</div>
</details>

### vars.tf

<details>
<summary>vars.tf</summary>
<div>

```shell
variable compartment_ocid {}
variable export_compute1_source_image_id { default = "ocid1.image.oc1.ap-tokyo-1.aaaaaaaa54xb7m4f42vckxkrmtlpys32quyjfldbkhq5zsbmw2r6v5hzgvkq" }
variable export_compute2_source_image_id { default = "ocid1.image.oc1.ap-tokyo-1.aaaaaaaa54xb7m4f42vckxkrmtlpys32quyjfldbkhq5zsbmw2r6v5hzgvkq" }
```

</div>
</details>

# 3.出力されたファイルを使う

## DBの管理者パスワードの設定
上述の通り、DB管理者パスワードはexportで拾えないので、terraform planを実行すると、以下のようなエラーとなります。

```
Error: Missing required argument

  on database.tf line 17, in resource "oci_database_db_system" "export_DBSystem1":
  17:     database {

The argument "admin_password" is required, but no definition was found.
```

そこで、database.tfを編集し、管理者パスワードの部分を変数で指定するよう書き換えました。

```database.tf
  db_home {
    database {
      admin_password = "${var.db_admin_password}"
      #backup_id = <<Optional value not found in discovery>>
      #backup_tde_password = <<Optional value not found in discovery>>
      character_set = "AL32UTF8"
```

変数はとりあえず、vars.tfに以下を追加し、実行時に入力するようにしました。

```vars.tf
variable db_admin_password {}
```

## terraform planの実行（試行錯誤中）
生成されたconfig fileとstate fileを使って、terraform planを実行してみます。
「No changes. Infrastructure is up-to-date.」が出ることを期待していたのですが…

- 書き方が古いのでさっそく怒られる。（無視可能）

```
$ terraform plan

Warning: Interpolation-only expressions are deprecated

  on core.tf line 8, in resource "oci_core_instance" "export_compute1":
   8:   availability_domain = "${data.oci_identity_availability_domain.export_GBRF-AP-TOKYO-1-AD-1.name}"

Terraform 0.11 and earlier required all non-constant expressions to be
provided via interpolation syntax, but this pattern is now deprecated. To
silence this warning, remove the "${ sequence from the start and the }"
sequence from the end of this expression, leaving just the inner expression.

Template interpolation syntax is still used to construct strings from
expressions when the template includes multiple interpolation sequences or a
mixture of literal strings and interpolations. This deprecation applies only
to templates that consist entirely of a single interpolation sequence.
（後略）
```

- vars.tfで定義していなかった変数が聞かれる（想定通り）

```
var.compartment_ocid
  Enter a value: ocid1.compartment.oc1..aaxxxxx

var.db_admin_password
  Enter a value: xxxxxxx
```


- DBCSで差分が検出されてしまう

このままだと再作成となってしまうので、既存DBリソースのそのまま管理化における方法がないか、今後調査します。

```
  # oci_database_db_system.export_DBSystem1 must be replaced
-/+ resource "oci_database_db_system" "export_DBSystem1" {
        availability_domain         = "GBRF:AP-TOKYO-1-AD-1"
      - backup_network_nsg_ids      = [] -> null
      + backup_subnet_id            = (known after apply)
      + cluster_name                = (known after apply)
 （中略）
      - nsg_ids                     = [] -> null
（中略）
Plan: 1 to add, 0 to change, 1 to destroy.
```

※ computeは差分検知されなかったので、そのまま管理が可能そう。

# 4.その他

## 参考

- [Discovering Terraform resources in an Oracle Cloud Infrastructure compartment](https://www.terraform.io/docs/providers/oci/guides/resource_discovery.html)
- [TerraformでOracle Cloud(OCI)の基本的なリソースを一通り作ってみた](https://qiita.com/feifo/items/2ca1f8451fb7f74d77c5#2-6output%E7%94%A8%E3%81%AEtf)

## ハマったところ

- ociの各種情報については、oci cliのconfigの設定を使用してくれるような記載があったのですが、うまくいきませんでした。再挑戦したい。→一応できた（https://qiita.com/feifo/items/b601a8b3edc5b761e806）
- terraform-provider-oci実行時、-compartment_idでコンパートメントのOCIDを指定しようとすると以下のエラーで失敗。名前を指定するオプションへ変えて成功（outputオプションまわりは変更していない）。 
`[ERROR] output_path does not exist: Stat : The system cannot find the path specified.`