OCI DevOps ProfessionalのLeaning Pathを確認する 2

# はじめに
[1に続いて、](https://qiita.com/dingtianhongjie/items/19d0ee610c2d697b2b31)OCI DevOps ProfessionalのLeaning PathにあるLabを実際にやってみて、OCIにおけるDevOpsの設定や動作を確認します。

https://mylearn.oracle.com/ou/learning-path/become-an-oci-devops-professional-2023/121756

今回はIaCに関する以下2つのLabになります。

[07. Ansible](#07-ansible)
[08. TerraformとResource Manager](#08-terraformとresource-manager)

# 07. Ansible
Ansibleコレクションを用いてOCIのCompute Instanceをプロビジョニングする手順を確認します。

https://docs.oracle.com/ja-jp/iaas/Content/API/SDKDocs/ansible.htm

## ポリシーの設定
以下のポリシーを設定します。

```
Allow dynamic-group <動的グループ名> to manage virtual-network-family in compartment <コンパートメント名>
Allow dynamic-group <動的グループ名> to manage volume-family in compartment <コンパートメント名>
Allow dynamic-group <動的グループ名> to manage instance-family in compartment <コンパートメント名>
```

<!--
## Ansibleのインストール

```
$ sudo yum install ansible
This system is receiving updates from OSMS server.
Last metadata expiration check: 15:53:18 ago on Wed Jun 21 12:49:38 2023.
Dependencies resolved.
=========================================================================================================================================================================
 Package                            Architecture                      Version                                   Repository                                          Size
=========================================================================================================================================================================
Installing:
 ansible                            noarch                            2.9.27-1.el8                              ol8_oci_included-x86_64                             17 M
Installing dependencies:
 sshpass                            x86_64                            1.09-4.el8                                ol8_appstream-x86_64                                30 k

Transaction Summary
=========================================================================================================================================================================
Install  2 Packages

Total download size: 17 M
Installed size: 96 M
Is this ok [y/N]: y
Downloading Packages:
(1/2): sshpass-1.09-4.el8.x86_64.rpm                                                                                                     145 kB/s |  30 kB     00:00    
(2/2): ansible-2.9.27-1.el8.noarch.rpm                                                                                                    25 MB/s |  17 MB     00:00    
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                     25 MB/s |  17 MB     00:00     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                                 1/1 
  Installing       : sshpass-1.09-4.el8.x86_64                                                                                                                       1/2 
  Installing       : ansible-2.9.27-1.el8.noarch                                                                                                                     2/2 
  Running scriptlet: ansible-2.9.27-1.el8.noarch                                                                                                                     2/2 
  Verifying        : sshpass-1.09-4.el8.x86_64                                                                                                                       1/2 
  Verifying        : ansible-2.9.27-1.el8.noarch                                                                                                                     2/2 

Installed:
  ansible-2.9.27-1.el8.noarch                                                          sshpass-1.09-4.el8.x86_64                                                         

Complete!
```

## Ansible Collectionのインストール

```
$ ansible-galaxy collection install oracle.oci
Process install dependency map
Starting collection install process
Installing 'oracle.oci:4.24.0' to '/home/opc/.ansible/collections/ansible_collections/oracle/oci'
$ ansible localhost -m oracle.oci.oci_object_storage_namespace_facts
localhost | SUCCESS => {
    "changed": false,
    "namespace": "orasejapan"
}
```

```
$ git clone https://github.com/oracle/oci-ansible-collection.git
Cloning into 'oci-ansible-collection'...
remote: Enumerating objects: 138684, done.
remote: Counting objects: 100% (33324/33324), done.
remote: Compressing objects: 100% (221/221), done.
remote: Total 138684 (delta 33110), reused 33238 (delta 33081), pack-reused 105360
Receiving objects: 100% (138684/138684), 304.68 MiB | 24.66 MiB/s, done.
Resolving deltas: 100% (137380/137380), done.
```

```
$ ls -l　oci-ansible-collection/
total 288
-rw-rw-r--.  1 opc opc 87402 Jun 22 04:48 CHANGELOG.md
-rw-rw-r--.  1 opc opc  3153 Jun 22 04:48 COMMON_ISSUES.md
-rw-rw-r--.  1 opc opc  2129 Jun 22 04:48 CONTRIBUTING.md
-rw-rw-r--.  1 opc opc  1148 Jun 22 04:48 FAQ.md
-rw-rw-r--.  1 opc opc  6113 Jun 22 04:48 InstallationGuide.md
-rw-rw-r--.  1 opc opc  3140 Jun 22 04:48 KNOWN_ISSUES.md
-rw-rw-r--.  1 opc opc 41869 Jun 22 04:48 LICENSE.txt
-rw-rw-r--.  1 opc opc 85763 Jun 22 04:48 MigrationGuide.md
-rw-rw-r--.  1 opc opc  5685 Jun 22 04:48 README.md
-rw-rw-r--.  1 opc opc  1737 Jun 22 04:48 SECURITY.md
-rw-rw-r--.  1 opc opc 12062 Jun 22 04:48 THIRD_PARTY_LICENSES.txt
-rw-rw-r--.  1 opc opc  5994 Jun 22 04:48 UserGuide.md
drwxrwxr-x.  7 opc opc   170 Jun 22 04:48 docs
-rw-rw-r--.  1 opc opc  2540 Jun 22 04:48 galaxy.yml
drwxrwxr-x.  2 opc opc    25 Jun 22 04:48 meta
drwxrwxr-x.  7 opc opc    93 Jun 22 04:48 plugins
-rw-rw-r--.  1 opc opc    26 Jun 22 04:48 requirements.txt
drwxrwxr-x. 15 opc opc  4096 Jun 22 04:48 samples
-rw-rw-r--.  1 opc opc   634 Jun 22 04:48 sbom_generation.yaml
drwxrwxr-x.  2 opc opc    42 Jun 22 04:48 scripts
drwxrwxr-x.  4 opc opc    48 Jun 22 04:48 solutions
```

## Instanceの作成

```
$ mkdir -p ansible/playbooks
$ cd ansible/playbooks/
$ cp -r ../../oci-ansible-collection/samples/compute/launch_compute_instance/ .
```

```
$ cd launch_compute_instance/
$ ls
README.md  sample.yaml  setup.yaml  teardown.yaml  templates
```

https://docs.oracle.com/en-us/iaas/images/image/3baec0b4-4bac-4cb0-ac1d-621846621396/

```
$ export SAMPLE_IMAGE_OCID=ocid1.image.oc1.ap-osaka-1.aaaaaaaas44neqcvhbqf6yuet5nfu4jb5iqmiczl44ktdzh26mdeiybvm33a
$ export SAMPLE_COMPARTMENT_OCID=ocid1.compartment.oc1..aaaaaaaamyemvazvbgl42f5pi7gzlpgq5tcmxlipjm2uitoihfschylliy5a
$ export SAMPLE_AD_NAME=TGjA:AP-OSAKA-1-AD-1
```
-->

## Ansibleコレクションのインストール
Cloud Shellを開いてOCIのAnsibleコレクションをインストールして、動作を確認します。

```
$ ansible-galaxy collection install oracle.oci
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Downloading https://galaxy.ansible.com/download/oracle-oci-4.24.0.tar.gz to /home/kosuke_mac/.ansible/tmp/ansible-local-1958eue90_vo/tmp9v13_3yx/oracle-oci-4.24.0-0m7juv7k
Installing 'oracle.oci:4.24.0' to '/home/kosuke_mac/.ansible/collections/ansible_collections/oracle/oci'
oracle.oci:4.24.0 was installed successfully

$ ansible localhost -m oracle.oci.oci_object_storage_namespace_facts
localhost | SUCCESS => {
    "changed": false,
    "namespace": "orasejapan"
}
```

## サンプルのダウンロード
GitHubからサンプルコードをCloneします。

```
$ git clone https://github.com/oracle/oci-ansible-collection.git
Cloning into 'oci-ansible-collection'...
remote: Enumerating objects: 138684, done.
remote: Counting objects: 100% (33324/33324), done.
remote: Compressing objects: 100% (221/221), done.
remote: Total 138684 (delta 33110), reused 33238 (delta 33081), pack-reused 105360
Receiving objects: 100% (138684/138684), 304.69 MiB | 33.98 MiB/s, done.
Resolving deltas: 100% (137380/137380), done.
```

```
$ ls -l oci-ansible-collection/
total 292
-rw-r--r--.  1 kosuke_mac oci 87402 Jun 22 05:38 CHANGELOG.md
-rw-r--r--.  1 kosuke_mac oci  3153 Jun 22 05:38 COMMON_ISSUES.md
-rw-r--r--.  1 kosuke_mac oci  2129 Jun 22 05:38 CONTRIBUTING.md
drwxr-xr-x.  7 kosuke_mac oci  4096 Jun 22 05:38 docs
-rw-r--r--.  1 kosuke_mac oci  1148 Jun 22 05:38 FAQ.md
-rw-r--r--.  1 kosuke_mac oci  2540 Jun 22 05:38 galaxy.yml
-rw-r--r--.  1 kosuke_mac oci  6113 Jun 22 05:38 InstallationGuide.md
-rw-r--r--.  1 kosuke_mac oci  3140 Jun 22 05:38 KNOWN_ISSUES.md
-rw-r--r--.  1 kosuke_mac oci 41869 Jun 22 05:38 LICENSE.txt
drwxr-xr-x.  2 kosuke_mac oci    25 Jun 22 05:38 meta
-rw-r--r--.  1 kosuke_mac oci 85763 Jun 22 05:38 MigrationGuide.md
drwxr-xr-x.  7 kosuke_mac oci    93 Jun 22 05:38 plugins
-rw-r--r--.  1 kosuke_mac oci  5685 Jun 22 05:38 README.md
-rw-r--r--.  1 kosuke_mac oci    26 Jun 22 05:38 requirements.txt
drwxr-xr-x. 15 kosuke_mac oci  4096 Jun 22 05:38 samples
-rw-r--r--.  1 kosuke_mac oci   634 Jun 22 05:38 sbom_generation.yaml
drwxr-xr-x.  2 kosuke_mac oci    42 Jun 22 05:38 scripts
-rw-r--r--.  1 kosuke_mac oci  1737 Jun 22 05:38 SECURITY.md
drwxr-xr-x.  4 kosuke_mac oci    48 Jun 22 05:38 solutions
-rw-r--r--.  1 kosuke_mac oci 12062 Jun 22 05:38 THIRD_PARTY_LICENSES.txt
-rw-r--r--.  1 kosuke_mac oci  5994 Jun 22 05:38 UserGuide.md
```

Working Directoryを作成して、サンプルコードをコピーします。

```
$ mkdir -p ansible/playbooks
$ cd ansible/playbooks/
$ cp -r ../../oci-ansible-collection/samples/compute/launch_compute_instance/ .
```

```
$ cd launch_compute_instance/
$ ls
README.md  sample.yaml  setup.yaml  teardown.yaml  templates
```

## Ansibleの実行
以下3つの環境変数を定義します。

```
$ export SAMPLE_IMAGE_OCID=ocid1.image.oc1.iad.aaaaaaaaox73mjjcopg6damp7tssjccpp5opktr3hwgr63u2lacdt2nver5a
$ export SAMPLE_COMPARTMENT_OCID=ocid1.compartment.oc1..aaaaaaaamyemvazvbgl42f5pi7gzlpgqxxxxxxxxxx
$ export SAMPLE_AD_NAME=TGjA:US-ASHBURN-AD-3
```

`SAMPLE_IMAGE_OCID`はリージョンに合わせて、以下のURLで使用するOCIDを確認します。

https://docs.oracle.com/en-us/iaas/images/image/501c6e22-4dc6-4e99-b045-cae47aae343f/

実行します。

```
$ ansible-playbook sample.yaml 
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [Launch a compute instance and connect to it using SSH] *****************************************************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Check pre-requisites] **************************************************************************************************************************************************************************************************************
skipping: [localhost] => (item=SAMPLE_COMPARTMENT_OCID) 
skipping: [localhost] => (item=SAMPLE_IMAGE_OCID) 
skipping: [localhost] => (item=SAMPLE_AD_NAME) 

TASK [Create a temporary directory to house a temporary SSH keypair we will later use to connect to instance] ****************************************************************************************************************************
changed: [localhost]

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Generate a Private Key] ************************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Generate a Public Key] *************************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [Create a VCN] **********************************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Create a new Internet Gateway] *****************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Create route table to connect internet gateway to the VCN] *************************************************************************************************************************************************************************
changed: [localhost]

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [create ingress rules yaml body] ****************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [create egress yaml body] ***********************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [load the variables defined in the ingress rules yaml body] *************************************************************************************************************************************************************************
ok: [localhost]

TASK [print loaded_ingress] **************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "loaded ingress is {'instance_ingress_security_rules': [{'source': '0.0.0.0/0', 'protocol': '6', 'tcp_options': {'destination_port_range': {'min': 22, 'max': 22}}}]}"
}

TASK [load the variables defined in the egress rules yaml body] **************************************************************************************************************************************************************************
ok: [localhost]

TASK [print loaded_egress] ***************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "loaded egress is {'instance_egress_security_rules': [{'destination': '0.0.0.0/0', 'protocol': '6', 'tcp_options': {'destination_port_range': {'min': 22, 'max': 22}}}]}"
}

TASK [Create a security list for allowing access to public instance] *********************************************************************************************************************************************************************
changed: [localhost]

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Create a subnet to host the public instance. Link security_list and route_table.] **************************************************************************************************************************************************
changed: [localhost]

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Launch an instance] ****************************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [Print instance details] ************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Launched a new instance {'changed': True, 'instance': {'availability_domain': 'TGjA:US-ASHBURN-AD-3', 'capacity_reservation_id': None, 'compartment_id': 'ocid1.compartment.oc1..aaaaaaaamyemvazvbgl42f5pi7gzlpgq5tcmxlipjm2uitoihfschylliy5a', 'dedicated_vm_host_id': None, 'defined_tags': {}, 'display_name': 'my_test_instance', 'extended_metadata': {}, 'fault_domain': 'FAULT-DOMAIN-3', 'freeform_tags': {}, 'id': 'ocid1.instance.oc1.iad.anuwcljrssl65iqcolxmlkgjea6pq5jscm3jqt6amlulhg5xxufgveimqspq', 'image_id': 'ocid1.image.oc1.iad.aaaaaaaaox73mjjcopg6damp7tssjccpp5opktr3hwgr63u2lacdt2nver5a', 'ipxe_script': None, 'launch_mode': 'NATIVE', 'launch_options': {'boot_volume_type': 'PARAVIRTUALIZED', 'firmware': 'UEFI_64', 'network_type': 'PARAVIRTUALIZED', 'remote_data_volume_type': 'PARAVIRTUALIZED', 'is_pv_encryption_in_transit_enabled': False, 'is_consistent_volume_naming_enabled': True}, 'instance_options': {'are_legacy_imds_endpoints_disabled': False}, 'availability_config': {'is_live_migration_preferred': None, 'recovery_action': 'RESTORE_INSTANCE'}, 'preemptible_instance_config': None, 'lifecycle_state': 'RUNNING', 'metadata': {'ssh_authorized_keys': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCWvJmG9y/ttGDvJUMJV5FEPbHSigpuGBGGO8WVyl7TnBsAXNfBPb8kZ/X9IaUZM9qMnuKNJQlMblzTN/XfOrB1s9hi6hdtQlVMbIO8Vv+bwZ9jVfZ63WBctA/W8zigcax7OKGOyy8kY24pJnBDkFUBAwmJxkLI/W4UywpTdYByqtcEVNaKMZ5U34wtf+N5u6zHus+VniRW2gUT9nLUVcsTWEeg3IjYeyZTt0HYnzI4FmS6tMjDoyW0VTCvpLihJtJHSfGh+AS7F4ktl7D/k9gjRcU8Bm8/ZUZmnwegFvRBotkz3f4As3kiA1ihjmvp2b44y6xCFWUvEOquMwwe3hmd'}, 'region': 'iad', 'shape': 'VM.Standard2.1', 'shape_config': {'ocpus': 1.0, 'memory_in_gbs': 15.0, 'baseline_ocpu_utilization': None, 'processor_description': '2.0 GHz Intel® Xeon® Platinum 8167M (Skylake)', 'networking_bandwidth_in_gbps': 1.0, 'max_vnic_attachments': 2, 'gpus': 0, 'gpu_description': None, 'local_disks': 0, 'local_disks_total_size_in_gbs': None, 'local_disk_description': None}, 'is_cross_numa_node': False, 'source_details': {'source_type': 'image', 'boot_volume_size_in_gbs': None, 'image_id': 'ocid1.image.oc1.iad.aaaaaaaaox73mjjcopg6damp7tssjccpp5opktr3hwgr63u2lacdt2nver5a', 'kms_key_id': None, 'boot_volume_vpus_per_gb': None}, 'system_tags': {}, 'time_created': '2023-06-22T05:44:26.236000+00:00', 'agent_config': {'is_monitoring_disabled': False, 'is_management_disabled': False, 'are_all_plugins_disabled': False, 'plugins_config': None}, 'time_maintenance_reboot_due': None, 'platform_config': None, 'primary_public_ip': '129.213.29.146', 'primary_private_ip': '10.0.0.58'}, 'failed': False}"
}

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Get the VNIC attachment details of instance] ***************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Get details of the VNIC] ***********************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Print the public ip of the newly launched instance] ********************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Public IP of launched instance 129.213.29.146"
}

TASK [Wait (upto 10 minutes) for port 22 to become open] *********************************************************************************************************************************************************************************
ok: [localhost]

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [set_fact] **************************************************************************************************************************************************************************************************************************
skipping: [localhost]

TASK [Attempt a ssh connection to the newly launched instance] ***************************************************************************************************************************************************************************
changed: [localhost]

TASK [Print SSH response from launched instance] *****************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "SSH response from instance -> ['Linux mytestinstance 4.14.35-1902.7.3.el7uek.x86_64 #2 SMP Thu Oct 31 10:06:41 PDT 2019 x86_64 x86_64 x86_64 GNU/Linux']"
}

TASK [Terminate the instance] ************************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [Delete the subnet] *****************************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [Delete the security list] **********************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [Delete the route table] ************************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [Delete the Internet Gateway] *******************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [Delete the VCN] ********************************************************************************************************************************************************************************************************************
changed: [localhost]

PLAY RECAP *******************************************************************************************************************************************************************************************************************************
localhost                  : ok=40   changed=18   unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   
```

サンプルはインスタンスをプロビジョニングして、すぐに削除するようになっています。
コンソールでは削除後のインスタンスを確認できます。


![スクリーンショット 2023-06-22 14.55.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/cb629118-29b7-483e-2eb8-041abd865323.png)

# 08. TerraformとResource Manager
TerraformとそのマネージドサービスであるResource Managerの手順を確認します。

## ポリシーの設定
以下のポリシーを追加します。

```
Allow dynamic-group member-kosuke.machida_dynamic_group to manage orm-jobs in compartment kosuke.machida
Allow dynamic-group member-kosuke.machida_dynamic_group to manage orm-stacks in compartment kosuke.machida
```

## Terraform
（マネージドではない）Terraformを利用して、OCIのVCNを作成します。

### サンプルコードのダウンロード
GitHubからサンプルコードをCloneします。

```
$ git clone https://github.com/ou-developers/devops-lab03-terraform.git
Cloning into 'devops-lab03-terraform'...
remote: Enumerating objects: 20, done.
remote: Counting objects: 100% (20/20), done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 20 (delta 4), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (20/20), 4.91 KiB | 4.91 MiB/s, done.
Resolving deltas: 100% (4/4), done.
$ ls -l devops-lab03-terraform/
total 16
-rw-rw-r--. 1 opc opc 993 Jun 22 07:13 README.md
-rw-rw-r--. 1 opc opc  35 Jun 22 07:13 terraform.tfvars
-rw-rw-r--. 1 opc opc  46 Jun 22 07:13 variables.tf
-rw-rw-r--. 1 opc opc 556 Jun 22 07:13 vcn.tf
```

### 初期化

```
$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding oracle/oci versions matching ">= 4.67.3"...
- Installing oracle/oci v5.2.1...
- Installed oracle/oci v5.2.1 (signed by a HashiCorp partner, key ID 1533A49284137CEB)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

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`ディレクトリが作られます。

```
$ ls -la
total 32
drwxrwxr-x. 4 opc opc 4096 Jun 22 08:11 .
drwxrwxr-x. 3 opc opc   36 Jun 22 07:13 ..
drwxrwxr-x. 8 opc opc  163 Jun 22 07:13 .git
drwxr-xr-x. 3 opc opc   23 Jun 22 08:06 .terraform
-rw-r--r--. 1 opc opc 1405 Jun 22 08:06 .terraform.lock.hcl
-rw-rw-r--. 1 opc opc  993 Jun 22 07:13 README.md
-rw-rw-r--. 1 opc opc 4028 Jun 22 08:11 terraform.tfstate
-rw-rw-r--. 1 opc opc  375 Jun 22 08:11 terraform.tfstate.backup
-rw-rw-r--. 1 opc opc  103 Jun 22 08:09 terraform.tfvars
-rw-rw-r--. 1 opc opc   46 Jun 22 07:13 variables.tf
-rw-rw-r--. 1 opc opc  515 Jun 22 08:09 vcn.tf
```

### ファイルの編集
サンプルファイルを以下のように編集します。

VCNを作成するコードです。
`compartment_id`は変数にして、別ファイルで管理するようにします。

```vcn.tf
terraform {
  required_providers {
    oci = {
      source  = "oracle/oci"
      version = ">=4.67.3"
    }
  }
  required_version = ">= 1.0.0"
}

resource "oci_core_vcn" "example_vcn" {
    compartment_id = var.compartment_id
    display_name = "IAD-DOP-LAB03-1-VCN-01"
    cidr_blocks = ["10.0.0.0/16"]
}


resource "oci_core_subnet" "example_subnet" {
    compartment_id = var.compartment_id
    display_name = "IAD-DOP-LAB03-1-SNT-01"
    vcn_id = oci_core_vcn.example_vcn.id
    cidr_block = "10.0.0.0/24"
}
```

変数を定義するファイルです。サンプルから変更はありません。
`compartment_id`をstring型の変数として定義しています。

```variables.tf
variable "compartment_id" {
  type = string
}
```

変数に値を定義します。ここでは環境に合わせてコンパートメントIDを設定します。

```terraform.tfvars
compartment_id = "ocid1.compartment.oc1..aaaaaaaamyemvazvbgl42f5pi7gzlpXXXXXXXXX"
```

### plan
実行計画を作成します。

```
$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # oci_core_subnet.example_subnet will be created
  + resource "oci_core_subnet" "example_subnet" {
      + availability_domain        = (known after apply)
      + cidr_block                 = "10.0.0.0/24"
      + compartment_id             = "ocid1.compartment.oc1..aaaaaaaamyemvazvbgl42f5pi7gzlpgq5xxxxxxxxxxx"
      + defined_tags               = (known after apply)
      + dhcp_options_id            = (known after apply)
      + display_name               = "IAD-DOP-LAB03-1-SNT-01"
      + dns_label                  = (known after apply)
      + freeform_tags              = (known after apply)
      + id                         = (known after apply)
      + ipv6cidr_block             = (known after apply)
      + ipv6cidr_blocks            = (known after apply)
      + ipv6virtual_router_ip      = (known after apply)
      + prohibit_internet_ingress  = (known after apply)
      + prohibit_public_ip_on_vnic = (known after apply)
      + route_table_id             = (known after apply)
      + security_list_ids          = (known after apply)
      + state                      = (known after apply)
      + subnet_domain_name         = (known after apply)
      + time_created               = (known after apply)
      + vcn_id                     = (known after apply)
      + virtual_router_ip          = (known after apply)
      + virtual_router_mac         = (known after apply)
    }

  # oci_core_vcn.example_vcn will be created
  + resource "oci_core_vcn" "example_vcn" {
      + byoipv6cidr_blocks               = (known after apply)
      + cidr_block                       = (known after apply)
      + cidr_blocks                      = [
          + "10.0.0.0/16",
        ]
      + compartment_id                   = "ocid1.compartment.oc1..aaaaaaaamyemvazvbgl42f5pi7gzlpgq5tcmxxxxxxxxxxxxxx"
      + default_dhcp_options_id          = (known after apply)
      + default_route_table_id           = (known after apply)
      + default_security_list_id         = (known after apply)
      + defined_tags                     = (known after apply)
      + display_name                     = "IAD-DOP-LAB03-1-VCN-01"
      + dns_label                        = (known after apply)
      + freeform_tags                    = (known after apply)
      + id                               = (known after apply)
      + ipv6cidr_blocks                  = (known after apply)
      + ipv6private_cidr_blocks          = (known after apply)
      + is_ipv6enabled                   = (known after apply)
      + is_oracle_gua_allocation_enabled = (known after apply)
      + state                            = (known after apply)
      + time_created                     = (known after apply)
      + vcn_domain_name                  = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
```

### apply
適用してVCNを作成します。

```
$ terraform apply 

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # oci_core_subnet.example_subnet will be created
  + resource "oci_core_subnet" "example_subnet" {
      + availability_domain        = (known after apply)
      + cidr_block                 = "10.0.0.0/24"
      + compartment_id             = "ocid1.compartment.oc1..aaaaaaaamyemvazvbgl42f5pi7gzlpgq5tcmxlxxxxxxxxxxxxxxx"
      + defined_tags               = (known after apply)
      + dhcp_options_id            = (known after apply)
      + display_name               = "IAD-DOP-LAB03-1-SNT-01"
      + dns_label                  = (known after apply)
      + freeform_tags              = (known after apply)
      + id                         = (known after apply)
      + ipv6cidr_block             = (known after apply)
      + ipv6cidr_blocks            = (known after apply)
      + ipv6virtual_router_ip      = (known after apply)
      + prohibit_internet_ingress  = (known after apply)
      + prohibit_public_ip_on_vnic = (known after apply)
      + route_table_id             = (known after apply)
      + security_list_ids          = (known after apply)
      + state                      = (known after apply)
      + subnet_domain_name         = (known after apply)
      + time_created               = (known after apply)
      + vcn_id                     = (known after apply)
      + virtual_router_ip          = (known after apply)
      + virtual_router_mac         = (known after apply)
    }

  # oci_core_vcn.example_vcn will be created
  + resource "oci_core_vcn" "example_vcn" {
      + byoipv6cidr_blocks               = (known after apply)
      + cidr_block                       = (known after apply)
      + cidr_blocks                      = [
          + "10.0.0.0/16",
        ]
      + compartment_id                   = "ocid1.compartment.oc1..aaaaaaaamyemvazvbgl42f5pi7gzlpgq5tcmxlxxxxxxxxxxxxxxx"
      + default_dhcp_options_id          = (known after apply)
      + default_route_table_id           = (known after apply)
      + default_security_list_id         = (known after apply)
      + defined_tags                     = (known after apply)
      + display_name                     = "IAD-DOP-LAB03-1-VCN-01"
      + dns_label                        = (known after apply)
      + freeform_tags                    = (known after apply)
      + id                               = (known after apply)
      + ipv6cidr_blocks                  = (known after apply)
      + ipv6private_cidr_blocks          = (known after apply)
      + is_ipv6enabled                   = (known after apply)
      + is_oracle_gua_allocation_enabled = (known after apply)
      + state                            = (known after apply)
      + time_created                     = (known after apply)
      + vcn_domain_name                  = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

oci_core_vcn.example_vcn: Creating...
oci_core_vcn.example_vcn: Creation complete after 1s [id=ocid1.vcn.oc1.ap-osaka-1.amaaaaaassl65iqae5f74wnzxaxn2l5fjui5k5xm5xnuk72v7ai5uqhqyaka]
oci_core_subnet.example_subnet: Creating...
oci_core_subnet.example_subnet: Creation complete after 7s [id=ocid1.subnet.oc1.ap-osaka-1.aaaaaaaao4uh3woo2num34bb7h57yrz4awl743dnhzcp5tjbbt2bgcfjgbxq]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
```

コンソール画面で作成できていることを確認します。

![スクリーンショット 2023-06-22 17.19.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/a481f447-4a71-13f3-47ab-daf698546265.png)

### destroy
削除します。

```
$ terraform destroy
oci_core_vcn.example_vcn: Refreshing state... [id=ocid1.vcn.oc1.ap-osaka-1.amaaaaaassl65iqae5f74wnzxaxn2l5fjui5k5xm5xnuk72v7ai5uqhqyaka]
oci_core_subnet.example_subnet: Refreshing state... [id=ocid1.subnet.oc1.ap-osaka-1.aaaaaaaao4uh3woo2num34bb7h57yrz4awl743dnhzcp5tjbbt2bgcfjgbxq]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # oci_core_subnet.example_subnet will be destroyed
  - resource "oci_core_subnet" "example_subnet" {
      - cidr_block                 = "10.0.0.0/24" -> null
      - compartment_id             = "ocid1.compartment.oc1..aaaaaaaamyemvazvbgl42f5pi7gzlpgq5tcxxxxxxxxxxxxxxxxxxxx" -> null
      - defined_tags               = {} -> null
      - dhcp_options_id            = "ocid1.dhcpoptions.oc1.ap-osaka-1.aaaaaaaaety7enj2mcpslyqq5r2m42qekfmrirv44g6bp3ar2mbdk7r4j2xq" -> null
      - display_name               = "IAD-DOP-LAB03-1-SNT-01" -> null
      - freeform_tags              = {} -> null
      - id                         = "ocid1.subnet.oc1.ap-osaka-1.aaaaaaaao4uh3woo2num34bb7h57yrz4awl743dnhzcp5tjbbt2bgcfjgbxq" -> null
      - ipv6cidr_blocks            = [] -> null
      - prohibit_internet_ingress  = false -> null
      - prohibit_public_ip_on_vnic = false -> null
      - route_table_id             = "ocid1.routetable.oc1.ap-osaka-1.aaaaaaaavddpgnb6a3mg32iilrs4ajuz5qh2rv7kviskvcbpdnaclm734xbq" -> null
      - security_list_ids          = [
          - "ocid1.securitylist.oc1.ap-osaka-1.aaaaaaaao3qw7aestdk6jfudem73hmprrivfpebwnlw2rdqkxn33splgwbda",
        ] -> null
      - state                      = "AVAILABLE" -> null
      - time_created               = "2023-06-22 08:11:47.081 +0000 UTC" -> null
      - vcn_id                     = "ocid1.vcn.oc1.ap-osaka-1.amaaaaaassl65iqae5f74wnzxaxn2l5fjui5k5xm5xnuk72v7ai5uqhqyaka" -> null
      - virtual_router_ip          = "10.0.0.1" -> null
      - virtual_router_mac         = "00:00:17:EB:DB:84" -> null
    }

  # oci_core_vcn.example_vcn will be destroyed
  - resource "oci_core_vcn" "example_vcn" {
      - byoipv6cidr_blocks       = [] -> null
      - cidr_block               = "10.0.0.0/16" -> null
      - cidr_blocks              = [
          - "10.0.0.0/16",
        ] -> null
      - compartment_id           = "ocid1.compartment.oc1..aaaaaaaamyemvazvbgl42f5pi7gzlpgq5tcmxxxxxxxxxxxxxxxxxxxxx" -> null
      - default_dhcp_options_id  = "ocid1.dhcpoptions.oc1.ap-osaka-1.aaaaaaaaety7enj2mcpslyqq5r2m42qekfmrirv44g6bp3ar2mbdk7r4j2xq" -> null
      - default_route_table_id   = "ocid1.routetable.oc1.ap-osaka-1.aaaaaaaavddpgnb6a3mg32iilrs4ajuz5qh2rv7kviskvcbpdnaclm734xbq" -> null
      - default_security_list_id = "ocid1.securitylist.oc1.ap-osaka-1.aaaaaaaao3qw7aestdk6jfudem73hmprrivfpebwnlw2rdqkxn33splgwbda" -> null
      - defined_tags             = {} -> null
      - display_name             = "IAD-DOP-LAB03-1-VCN-01" -> null
      - freeform_tags            = {} -> null
      - id                       = "ocid1.vcn.oc1.ap-osaka-1.amaaaaaassl65iqae5f74wnzxaxn2l5fjui5k5xm5xnuk72v7ai5uqhqyaka" -> null
      - ipv6cidr_blocks          = [] -> null
      - ipv6private_cidr_blocks  = [] -> null
      - is_ipv6enabled           = false -> null
      - state                    = "AVAILABLE" -> null
      - time_created             = "2023-06-22 08:11:46.336 +0000 UTC" -> null
    }

Plan: 0 to add, 0 to change, 2 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

oci_core_subnet.example_subnet: Destroying... [id=ocid1.subnet.oc1.ap-osaka-1.aaaaaaaao4uh3woo2num34bb7h57yrz4awl743dnhzcp5tjbbt2bgcfjgbxq]
oci_core_subnet.example_subnet: Destruction complete after 0s
oci_core_vcn.example_vcn: Destroying... [id=ocid1.vcn.oc1.ap-osaka-1.amaaaaaassl65iqae5f74wnzxaxn2l5fjui5k5xm5xnuk72v7ai5uqhqyaka]
oci_core_vcn.example_vcn: Destruction complete after 1s

Destroy complete! Resources: 2 destroyed.
```

## Resource Manager
Terraformと同様にVCNをResource Managerで作成します。

### Stackの作成
Stackとは複数のTerraformの設定ファイルをまとめたOCIのリソースです。Resource Managerでは、Stackという単位でTerraform構成ファイルを管理します。

Terraformで使用した以下3つのファイルをローカルPCにダウンロードしておきます。

```
% ls terraform_vcn 
terraform.tfvars        variables.tf            vcn.tf
```

OCIコンソールから`スタックの作成`をクリック

![スクリーンショット 2023-06-27 9.44.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/5434aa45-95d9-098c-7f8c-614794716a07.png)

以下の画面の`Terraform構成ソース`で、`フォルダ`を選択し、ローカルPCにダウンロードしたファイルを保存しているフォルダを選択します。

![スクリーンショット 2023-06-27 9.53.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/c6c1bc64-ca68-d2ff-ed81-8236f7c29450.png)

続き。

![スクリーンショット 2023-06-27 9.54.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/a9124a63-7ebf-ed03-47d7-7d997a0fc6a7.png)

`terraform.tfvars`ファイルで指定されている変数（コンパートメントOCID）が表示されます。

![スクリーンショット 2023-06-27 9.55.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/1caf71c7-cd69-02d9-7fcf-5cf77d078bb5.png)

`作成`をクリック

![スクリーンショット 2023-06-27 9.55.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/282c1f85-2ef8-973e-8e4c-dcee56d346e6.png)

このようにアイコンがグリーンになれば完了です。

![スクリーンショット 2023-06-27 9.56.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/6ad15211-7c4c-71a5-e1ac-93bad51133f3.png)

### 計画
実行計画を作成します。`terraform plan`に相当します。

スタックの画面から`計画`をクリックし、以下の画面で`計画`をクリックします。

![スクリーンショット 2023-06-27 9.59.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/be8f556b-f7b1-9319-c378-7d7d27b1b868.png)

以下のような画面になります。
ログには`terraform plan`コマンドを実行した時と同様のログが表示されます。

![スクリーンショット 2023-06-27 10.01.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/20c89348-a636-b8fa-b698-3693f65b2489.png)

### 適用
`terraform apply`に相当します。stackを実行して、リソースを作成します。

スタックの画面から`適用`をクリックします。
以下の画面で`適用ジョブの計画解決`では、`計画`で作成したジョブを選択し、`適用`をクリックします。

![スクリーンショット 2023-06-27 10.04.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/6d01de69-c853-c82a-77e5-b2c00c65c52e.png)

このような画面になれば成功です。計画と同様にログが表示されます。

![スクリーンショット 2023-06-27 10.13.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/0339ad05-3692-f286-1668-10cece9bd5ff.png)

VCNが作成されていることを確認します。

![スクリーンショット 2023-06-27 10.13.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/6454c312-4b79-8fa6-1925-a0b1bff0d0e0.png)

### 破棄
作成したリソースを削除します。`terraform destroy`に相当します。

スタックの画面から`破棄`をクリックし、以下の画面で`破棄`をクリックします。

![スクリーンショット 2023-06-27 10.15.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/170b02e9-80e0-a76e-0656-578e29c28e56.png)

計画や適用と同様に以下のような画面になれば破棄は完了です。

![スクリーンショット 2023-06-27 10.19.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/9d6e7061-ce90-6511-e4bd-b2554b466c3f.png)