ねら~ITエンジニア雑記

やきうのお兄ちゃんが綴るOracle Databaseメインのブログ

検証によく使う Oracle Cloud Infrastructure(OCI)環境を Terraform で作成してみる。

下記の記事で整理した OCI環境 を Terraform で作成してみるやで彡(゚)(゚)

検証によく使う Oracle Cloud Infrastructure(OCI) の 環境構成(VCN, Seculity List, 各種Gateway, Route Table, Subnet, Compute)まとめ
https://qiita.com/ora_gonsuke777/items/08e4781af8c4f7e114ff

1. 構成図(再掲)

下記構成図の環境を Terraform で作成してみます。(再掲載)
a_Networking.jpg

2. Terraform の事前準備

下記の記事で Terraform のインストールや動作確認は済ませておきます。

Windows端末(PC) に Terraform をインストールして OCI(Oracle Cloud Infrastructure) で動作させるための準備
https://qiita.com/ora_gonsuke777/items/fb2abfbb7d76de2afc93

3. Compute Instance用の キーペア(*.pub + *.pem or *.ppk) を 2セット作成

Compute Instance用 の SSHキーペア(*.pub + *.pem or *.ppk) を Public Compute用 と Private Compute用に 2セット作成しておきます。puttygen や ssh-keygen のどちらでも。

Linuxインスタンスでのキー・ペアの管理
https://docs.oracle.com/cd/E97706_01/Content/Compute/Tasks/managingkeypairs.htm

4. Terraform の定義ファイル(*.tf)サンプルのダウンロード

下記にTerraform定義ファイル(*.tf)のサンプルをアップロードしています。Network, Compute, Object Storage を作成するサンプルです。任意のディレクトリに git clone するか Download して下さい。

https://github.com/gonsuke777/terraform/tree/master/oci_test_env1

git clone https://github.com/gonsuke777/terraform

5. 変数定義ファイル(vars.tf) の 編集

vars.tf に変数を集約しています。下記の通り編集して下さい。

変数名 説明
os_image_source_id OSイメージIDを記述します。このIDはリージョンごとに異なります。https://docs.cloud.oracle.com/iaas/images/ をご覧ください。
public_compute_ssh_key
private_compute_ssh_key
Public Compute と Private Compute の SSH鍵(*.pub, 公開鍵) のパスを記述して下さい。
public_compute_ad_num
private_compute_ad_num
Public Compute と Private Compute を 作成する AD(Availability Domain) の番号を記述して下さい。1AD のリージョンの場合は 1 のみ記述可能です。
oci_resource_prefix リソースのプレフィックス名を 4文字以内 で記述して下さい。

上記以外の変数については下記記事を参照して下さい。

Windows端末(PC) に Terraform をインストールして OCI(Oracle Cloud Infrastructure) で動作させるための準備
https://qiita.com/ora_gonsuke777/items/fb2abfbb7d76de2afc93

6. terraform の実行(init, plan, apply)

terraform を実行します。下記コマンドを実行します。

cd <tfファイルを格納したディレクトリ>
terraform init
terraform plan
terraform apply
(確認が求められるので) yes

ログは以下の通り、上手くいってるやで彡(^)(^)

> terraform init

Initializing the backend...
:
Terraform has been successfully initialized!
:

> terraform plan
Refreshing Terraform state in-memory prior to plan...
:
Plan: 13 to add, 0 to change, 0 to destroy.
:

> terraform apply
data.oci_identity_availability_domains.ads: Refreshing state...
:
Apply complete! Resources: 13 added, 0 changed, 0 destroyed.
:

7. OCIリソースの確認 と 接続

OCI Console から作成されたリソースを確認してみます。 01_pub_subnet.jpg 02_pub_compute.jpg 03_ObjectStorage.jpg

出来てますね!Compute の ssh接続も確認

04_ssh_connection.jpg

Compute に上手く接続できたやで!彡(^)(^)

8. 後始末(terraform destroy)

terraform destroy すると、terraform で作成したリソースを削除できます。

cd <tfファイルを格納したディレクトリ>
terraform destroy
(確認が求められるので) yes

ログは下記の通り

> terraform destroy
data.oci_objectstorage_namespace.export_ns: Refreshing state...
:
oci_core_vcn.export_VCN1: Destruction complete after 1s

Destroy complete! Resources: 13 destroyed.
> 

上手く削除できたもよう。

9. 工夫した、というか困った箇所

様々なリージョンで汎用的に使える Terraform定義 にしようとした場合、AD名(Avilability Domain) や Service Gatewayのサービス名 を動的に解決する必要がありました。下記のあたり。
彡(゚)(゚)

# availability_domain.tf
:
# Get a list of Availability Domains, this code from https://www.terraform.io/docs/providers/oci/guides/best_practices.html
data "oci_identity_availability_domains" "ads" {
  compartment_id = "${var.tenancy_ocid}"
}
:
# compute.tf
:
resource oci_core_instance export_BASTION1 {
  compartment_id      = "${var.compartment_ocid}"
  display_name        = "${upper(var.oci_resourcel_prefix)}-BASTION1"
  # This code from https://www.terraform.io/docs/providers/oci/guides/best_practices.html
  # It to get a single AD name based on the index:
  availability_domain = "${lookup(data.oci_identity_availability_domains.ads.availability_domains[var.public_compute_ad_num - 1], "name")}"
:
# networking.tf
:
data "oci_core_services" "sgw_services" {
  filter {
    name   = "name"
    values = ["All .* Services In Oracle Services Network"]
    regex  = true
  }
}
:
  # Get the service id dynamically. this code from github examples.
  services {
    service_id = "${lookup(data.oci_core_services.sgw_services.services[0], "id")}"
  }
:

下記のサンプル群を参考にしつつ書いて期待通りの動作はしたものの、何故この書き方で動くのかイマイチ理解できない……
彡(-)(-)

OCI - Terraform Provider Best Practices
https://www.terraform.io/docs/providers/oci/guides/best_practices.html

terraform-provider-oci/examples/networking/service_gateway/service_gateway.tf
https://github.com/terraform-providers/terraform-provider-oci/blob/master/examples/networking/service_gateway/service_gateway.tf

10. OCIリソース の Terraform定義 を export する機能(terraform-provider-oci)

terraform-provider-oci という機能で OCIリソースの Terraform定義 をエクスポートできます。下記記事が参考になります。tfファイル を ゼロ から作り上げるのは相当キツいので、この機能でエクスポートした tfファイル を参考にしながら書いてみるとエエと思います。使い方も簡単
彡(^)(^)

terraform-provider-ociのエクスポート機能がとても便利
https://qiita.com/yamada-hakase/items/5c224c5a3343b1f2f27e

11. まとめ

Terraform で 環境を作成できたやで!彡(^)(^) しかし Terraform を プログラミング言語 と捉えた場合、main に相当する機能が無かったり、前述の通りAD名やSGW Service名を動的に解決する辺りのブラックボックス感が中々に凄い……要修行や!
彡(゚)(゚)