【やってみた】GitHubとOCI Resource Managerを連携しTerraformからリソース作成

Oracle CloudのOCI Resource Manager（以下、Resource Manager）とGitHubを連係させてTerraformを実行してみました。

## 参考情報
* こちらの記事を実施しています
    * [Oracle Blogs 日本語のまとめ-
クラウドでのIaC：Resource Manager入門／IaC in the Cloud: Getting Started with Resource Manager](https://orablogs-jp.blogspot.com/2021/03/getting-started-with-resource-manager.html)

## Resource Managerとは
* Terraformをクラウドで記述しOCIの各リソースを作成するサービスです
* Resource Manager自体は無償です（作成したリソースに対し課金）
* Resource Managerの基本用語
    * 構成ソース・プロバイダ
        * Terraform設定ファイルのバージョン管理のために使用している外部のソースコントロールシステム。これにより、直接ビルドできる（ファイルをZIP化しアップロードする必要がない）。
    * Statcks
        * ひとつのプランの一部として実行されるスクリプトのグループ
        * ZIPファイルとしてアップロード or 構成ソース・プロバイダから直接プル
    * Job
        * Stacksに対して実行されるもの
        * Plan、Apply、Destoryのジョブ
    *Drift
        * 実際のステートとそのスタックに対して最後に実行したジョブが保存していたステートとの差分
* Resource Managerは以下から利用可能
    * OCIコンソール
    * SDK
    * OCI CLI
 
## 検証の流れ
* Object Storageのバケットを作成するTerraformファイルを作成
* そのファイルをGitHubに連係
* Resource ManagerからGitHub上のファイルを読み込み、バケット作成（terrafrom plan/apply）
* Resource Managerから作成したバケットを削除（terraform destory）

## 1. Gitリポジトリの作成
* テストのため、テスト用のリポジトリを作成
    * リポジトリ名：任意の名前（例：oci-resource-manager-demo）
![git.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/a99b0dfe-deed-6652-9dca-31b33cd65beb.png)

* 作成したGitHubリポジトリをローカルにクローン
```
$ git clone https://github.com/<アカウント名>/oci-resource-manager-demo.git
```

## 2.Configuration Source Providerの設定
* GitHubプロジェクトからスタックを直接ビルドできるようにConfiguration Source Providerを設定する
* GitHubのパーソナルアクセストークンを生成する
    * こちらをクリック　→　https://github.com/settings/tokens
        * **GitHubのホーム画面** → **Settings** → **Developer settings** → **Personal access tokens** からでもいけます
* **Generate new token**をクリック
 ![git2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/f44df440-eb36-4a0a-2ac3-c9910b62e95d.png)
* 以下のように設定しました。
    * Note（トークン名）：任意の名前（例：OCI Resource Manager）
    * Expiration：今回は、デフォルト値（30 days）のまま
    * Select scopes
        * **read:packages** を選択
    *上記を設定し **Generate token** をクリック
![git3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/2ddff59e-e107-35a5-eff8-df42a3560e33.png)
* 作成できたらトークンをコピーしメモしておきます（**コピー忘れに注意！**）
![git4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/833b3e37-4fdc-69a9-19bc-27c992b6de58.png)
* GitHub側の設定はここまでです。
## 3.Resource Managerの設定
* Resouce Managerを開きます
    * **OCIコンソール** → **開発者サービス** → **リソース・マネージャ**
![git5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/d323ed6d-86f8-37ec-77ac-88ea5e0d5d53.png)
* **構成ソース・プロバイダ** をクリック
![git6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/932a5d64-2e24-f822-12ba-f66bdccd8041.png)
* **構成ソース・プロバイダの作成** をクリック（今回は以下の用に設定し作成しています）
    * 名前：任意の名前（例：GitHub source Provider）
    * 説明（オプション）：任意のコメント
        * 例：A configuration source provider for GitHub.
    * コンパートメント：任意のコンパートメント
    * タイプ：GitHub
    * サーバーURL：https://github.com
    * 個人アクセス・トークン：先程作成しコピーしておいたトークン
    * 拡張オプション：タグ・ネームスペース（今回は設定しない）
![git7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/d700f424-0f55-7f35-9174-38ca419b77b5.png)
* これでプロバイダを使う設定が完了
![git8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/3f77ef64-1b5e-17d8-2818-5fc8563ddd74.png)
## 3. テスト用のTerraformスクリプトを作成
* 事前に環境変数を設定
```
export TF_VAR_compartment_ocid=<compartment_OCID>
export TF_VAR_region=<region>
export TF_VAR_namespace=<namespace>
```
* Object Storageのバケットを作成するテスト用のtfファイルを作成
    * **demo.tf**を作成
```
variable "compartment_ocid" {}
variable "region" {}
variable "bucket_name" {
  default = "resource_manager_demo_bucket"
}

provider "oci" {
  region = var.region
}

data "oci_objectstorage_namespace" "namespace" {
  compartment_id = var.compartment_ocid
}

resource "oci_objectstorage_bucket" "create_bucket" {
  # required
  compartment_id = var.compartment_ocid
  name           = var.bucket_name
  namespace      = data.oci_objectstorage_namespace.namespace.namespace

  # optional
  access_type = "NoPublicAccess" # <---- プライベートバケット
}

output "new_bucket" {
  value = oci_objectstorage_bucket.create_bucket
}
```
* ローカルリポジトリの状態確認（git status）
```
$ git status
```
表示例
```
（略）
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        demo.tf

nothing added to commit but untracked files present (use "git add" to track)
```
* 作成したファイルをステージングエリアに登録（git add）
```
$ git add demo.tf
$ git status 
```
表示例
```
（略）
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   demo.tf
```
* コミットを実行（git commit）
```
$ git commit -m "initial commit"   
$ git status 
```
表示例
```
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
```
* ローカルリポジトリの内容をリモートリポジトリに反映（git push）
```
$ git push -u origin main
$ git stauts
```
表示例
```
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean
```
* GitHubを確認すると反映されていることがわかる
![git11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/eb416dc8-f7e0-60fa-559e-ba8ec821ac8a.png)

## 4. Resource ManagerでObject Storageバケットを作成
* OCIコンソールのResource Managerに戻り **スタック** → **スタックの作成**をクリック
    * **スタック構成**を設定し**次へ**
        * ソース・プロバイダ：先程作成したもの（例：GitHub source Provider）
        * リポジトリ：先程作成したもの（例、oci-resource-manager-demo）
        * ブランチ：main
        * 名前（オプション）：例：Stack-bucket-test
        * 説明（オプション）：例：テストバケットの作成
        * コンパートメント：コンパートメントを指定
![git10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/baa93d4f-b162-33ab-e085-dc811db74c28.png)
* 変数の構成を確認し**次へ**
![git12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/f7307b3b-8699-0bbb-709a-c777b298bf61.png)
* 確認画面で **適用の実行** のチェックが外されていることを確認し**作成**
    * 適用の実行：ここにチェックを入れると、リソースのプロビジョニングがはじまります
![git13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/c0a94a73-395a-9b4f-bb5d-9f5ef21f8d80.png)
* スタックが作成されました。**計画**をクリックすると「**terrafrom plan**」が実行されます
![git14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/1fc195f8-66b8-d51c-7a89-5cc864540088.png)
![git15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/3adba9a1-f264-3685-1f3c-f935e5e7f0c4.png)
* 計画が成功すると **ログ**から「**terrafrom plan**」の内容を確認できます
![git16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/cd381888-d0f0-a77f-2971-81ac7f279007.png)
* 上記の内容に問題なければ**スタックの詳細**に戻り　**適用**（**terraform apply**）を実行します
![git17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/b949942b-88ab-fdc7-e767-092c0488c197.png)
![git18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/1da92ac7-3472-27dd-d9c7-4d51f5d21ee1.png)
* 適用に成功すると、ログから適用内容を確認できます
![git19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/61c0fe76-4b4b-e145-c0e1-3909ce3ed69a.png)
* Object Storageを確認します
    * OCIコンソールから「ストレージ → オブジェクト・ストレージとアーカイブ・ストレージ
    * プライベート・バケットとして作成されていることが確認できます
![git20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/1f29a124-34a1-329b-a55d-420e610f0d9b.png)
![git21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/d65647bc-3647-6648-22b6-86a87b4df4b0.png)

## 5. Resource ManagerでObject Storageバケットを削除
* スタックから作成したバケットをクリーンアップして削除します
* Resouce Managerから先程のスタックに戻り、**スタックの詳細**の**破棄**（**terraform destory**）をクリック
>注意: このスタックでデプロイされたすべてのリソースは、即座に破棄されます。このアクションは元に戻せません。後でスタックのリソースを再作成する場合、適用ジョブを実行できます。

![git22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/7c402d98-376a-202a-8f06-80a9d865bcc5.png)
![git23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/42d48958-7f30-b313-4046-09fce4ebedaf.png)
* 削除に成功しました
![git24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/d449b220-6f16-27b7-a436-f39ad661144a.png)
* Object Storageに戻りバケットが削除されいることがわかります
![git25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/ec7f38fb-7ca9-3bd0-b6eb-5350e1642837.png)

# その他参考
* [Terraform-Oracle Cloud Infrastructure Provider](https://registry.terraform.io/providers/hashicorp/oci/latest/docs)
* [OCIドキュメント-リソース・マネージャ](https://docs.oracle.com/ja-jp/iaas/Content/ResourceManager/home.htm)
* [Speakerdeck-IaCでクラウドのインフラ運用を効率化しよう](https://speakerdeck.com/mmarukaw/iacdekuraudofalseinhurayun-yong-woxiao-lu-hua-siyou)
* [OCIチュートリアル-TerraformでOCIの構築を自動化する](https://oracle-japan.github.io/ocitutorials/intermediates/terraforming/)
* [GitHub-Oracle Terraform Modules](https://github.com/oracle-terraform-modules)