[OCI] Terraform でOCI  Marketplace imageの利用 (2019/12/10)

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

この記事では、OCI  Marketplace のimage（Oracle Image)を使ってインスタンスを作成することをOCIのマネージドTerraform環境であるリソース・マネージャで行ってみたことを紹介します。

# リソース・マネージャとは
Oracle Cloud Infrastructureリソースをプロビジョニングするプロセスを自動化できるOracle Cloud Infrastructureサービス
「infrastructure-as-code」モデルを使用してリソースをインストール、構成、および管理するのに役立つTerraformのマネージド環境

## リソース・マネージャのメリット
- インフラストラクチャの自動化と標準化、環境のレプリケーションを容易に行う
- OCI プラットフォームとそのサービスとの緊密な統合
- 状態ファイルをシームレスに管理し、チームのコラボレーションを向上
- Terraform エンジンのフルマネージドサービス
- 費用はリソース・マネージャを使用してプロビジョニングする、コンピューティング、ストレージ、ネットワーク、またはその他のリソースに対してのみ
(リソース・マネージャとしての費用は不要)


# Marketplace (App Catalog）からイメージのOCIDを取得するステップ
- キーワードを元にApp Catalog リストとバージョンの取得
    - data     "oci_core_app_catalog_listings“
    - data     "oci_core_app_catalog_listing_resource_versions"
- 取得したリストとバージョンからAppCatalogListingResourceVersionAgreementを作成
    - resource "oci_core_app_catalog_listing_resource_version_agreement“
- AppCatalogListingResourceVersionAgreementからコンパートメントのApp Catalog Subscriptionリソースを生成
    - resource "oci_core_app_catalog_subscription"
- 作成したOCI CoreサービスのApp Catalog Subscriptionリソースからリストを取得
    - data     "oci_core_app_catalog_subscriptions"


# リソース・マネージャサンプル（Terraform v0.11 フォーマット）
## キーワード(変数var.oracleimagenameで指定)を元にApp Catalog リストとバージョンの取得

```app_catalog_subscription.tf
data "oci_core_app_catalog_listings" "test_app_catalog_listings" {
  filter {
    name   = "display_name"
    values = ["${var.oracleimagename}"]
  }
}

data "oci_core_app_catalog_listing_resource_versions" "test_app_catalog_listing_resource_versions" {
  #Required
  listing_id = "${lookup(data.oci_core_app_catalog_listings.test_app_catalog_listings.app_catalog_listings[0],"listing_id")}"
}
```
## 取得したリストとバージョンからAppCatalogListingResourceVersionAgreementを作成
```app_catalog_subscription.tf
(続き)
resource "oci_core_app_catalog_listing_resource_version_agreement" "test_app_catalog_listing_resource_version_agreement" {
  #Required
  listing_id               = "${lookup(data.oci_core_app_catalog_listing_resource_versions.test_app_catalog_listing_resource_versions.app_catalog_listing_resource_versions[0], "listing_id")}"
  listing_resource_version = "${lookup(data.oci_core_app_catalog_listing_resource_versions.test_app_catalog_listing_resource_versions.app_catalog_listing_resource_versions[0], "listing_resource_version")}"
}
```
## AppCatalogListingResourceVersionAgreementからコンパートメントのApp Catalog Subscriptionリソースを生成
```app_catalog_subscription.tf
(続き)
resource "oci_core_app_catalog_subscription" "test_app_catalog_subscription" {
  compartment_id           = "${var.compartment_ocid}"
  eula_link                = "${oci_core_app_catalog_listing_resource_version_agreement.test_app_catalog_listing_resource_version_agreement.eula_link}"
  listing_id               = "${oci_core_app_catalog_listing_resource_version_agreement.test_app_catalog_listing_resource_version_agreement.listing_id}"
  listing_resource_version = "${oci_core_app_catalog_listing_resource_version_agreement.test_app_catalog_listing_resource_version_agreement.listing_resource_version}"
  oracle_terms_of_use_link = "${oci_core_app_catalog_listing_resource_version_agreement.test_app_catalog_listing_resource_version_agreement.oracle_terms_of_use_link}"
  signature                = "${oci_core_app_catalog_listing_resource_version_agreement.test_app_catalog_listing_resource_version_agreement.signature}"
  time_retrieved           = "${oci_core_app_catalog_listing_resource_version_agreement.test_app_catalog_listing_resource_version_agreement.time_retrieved}"

  timeouts {
    create = "20m"
  }
}
```
## 作成したOCI CoreサービスのApp Catalog Subscriptionリソースからリストを取得
```app_catalog_subscription.tf
(続き)
data "oci_core_app_catalog_subscriptions" "test_app_catalog_subscriptions" {
  #Required
  compartment_id = "${var.compartment_ocid}"

  #Optional
  listing_id = "${oci_core_app_catalog_subscription.test_app_catalog_subscription.listing_id}"

  filter {
    name   = "listing_resource_version"
    values = ["${oci_core_app_catalog_subscription.test_app_catalog_subscription.listing_resource_version}"]
  }
}
```
# Computeインスタンス作成時の指定
```compute.tf
resource "oci_core_instance" "TF_Instance" {
        count = "1"
        compartment_id = "${var.compartment_ocid}"
        availability_domain = "${data.oci_identity_availability_domain.ad.name}" 
        display_name = "TF_Instance"
        shape = "${var.headnode_shape}"
        create_vnic_details {
                subnet_id = "${oci_core_subnet.TF_Public_Subnet.id}"
        }
      source_details {
        source_type = "image"
        source_id   = "${lookup(data.oci_core_app_catalog_subscriptions.test_app_catalog_subscriptions.app_catalog_subscriptions[0],"listing_resource_id")}"
      }
        metadata {
            ssh_authorized_keys = "${tls_private_key.key.public_key_openssh}"
        }
}
```

# 環境構築の実行
1. すべてのファイルが用意できたらtfファイルをZIPファイルとして圧縮
2. リソース・マネージャのスタックを作成
3. 計画ジョブ・適用ジョブを実行


# 作成されたインスタンスの確認
- 適用ジョブの出力 Private_keyの値をコピーし、ファイルに保存（ssh 秘密鍵）
- ssh 接続確認

# サンプルファイルは 以下からダウンロード可能
[https://github.com/kenwatan/terraform_OCIRM_sample_marketplace_imae](https://github.com/kenwatan/terraform_OCIRM_sample_marketplace_imae)