This is the second article of these series where I will be covering the use of Terraform with Oracle Cloud Infrastructure from scratch. If you haven’t seen the first article I do recommend you check it out here https://www.techdatabasket.com/2020/10/21/example-of-how-to-use-oracle-cloud-infrastructure-oci-gen-2-with-terraform-macbook-pro-os-part-1/ , before you proceed with the following steps here.
On the first article, how to create your account at Oracle Cloud was shown and a glimpse on Terraform. Now we are going through some examples that show what Terraform can really do while using it with OCI.
So, let’s try to build an infrastructure with the configured script using the command “terraform apply” which “Builds or changes infrastructure” on Terraform considering that the Terraform has started already in the background (see first article). And as we are not creating or adding any resource at this moment, nothing will change as below:
brunotechdatabasket@Brunos-MacBook-Pro Terraform % terraform apply data.oci_identity_availability_domains.ads_2: Refreshing state... An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: Terraform will perform the following actions: Plan: 0 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 Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: show-ads = [ { "compartment_id" = "ocid1.compartment.oc1..aaaaaaaauos74rsl3aymrlbdnr6uocvtofm4s5fh57w4rpdr373qjjdsh47a" "id" = "ocid1.availabilitydomain.oc1..aaaaaaaapjv4p3qtly2fesrig77q4tlmi3wvakeet6fskc7do2fmawz3xctq" "name" = "jfUx:UK-LONDON-1-AD-1" }, { "compartment_id" = "ocid1.compartment.oc1..aaaaaaaauos74rsl3aymrlbdnr6uocvtofm4s5fh57w4rpdr373qjjdsh47a" "id" = "ocid1.availabilitydomain.oc1..aaaaaaaac6kgqnl5eberztbdm2ufhpxohk7cuelajmafpqa3m6rpri4tc2yq" "name" = "jfUx:UK-LONDON-1-AD-2" }, { "compartment_id" = "ocid1.compartment.oc1..aaaaaaaauos74rsl3aymrlbdnr6uocvtofm4s5fh57w4rpdr373qjjdsh47a" "id" = "ocid1.availabilitydomain.oc1..aaaaaaaaw2i3i53quioaywmhx56ss5plwk7bmmeg2266lo7inilhbizeroua" "name" = "jfUx:UK-LONDON-1-AD-3" }, ]
As you can see above, Terraform didn’t do any modification on the structure, “Plan: 0 to add, 0 to change, 0 to destroy.”. In case we wanted to see the action before adding or modification on any resources we would have used the command “terraform plan” instead. So, if you execute the command terraform plan at this moment it will show that there isn’t any configuration now:
brunotechdatabasket@Brunos-MacBook-Pro Terraform % terraform plan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. data.oci_identity_availability_domains.ads_2: Refreshing state... [id=2020-11-10 20:19:21.712269 +0000 UTC] ------------------------------------------------------------------------ No changes. Infrastructure is up-to-date. This means that Terraform did not detect any differences between your configuration and real physical resources that exist. As a result, no actions need to be performed.
To see how terraform can modify an infrastructure, a new compartment will be added, and a new user will be created within this compartment. Therefore, to be able to do that a script called “terraformcomp” with the terraform extesion “.tf” will be created and some resources values from terraform documentation will be used. (You can check more about terraform resources in OCI here :https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/). Then using the same values from the last article with a difference of using variables now, the new script will be like:
brunotechdatabasket@Brunos-MacBook-Pro Terraform % cat terraformcomp.tf # Configure the Oracle Cloud Infrastructure provider with an API Key provider "oci" { tenancy_ocid = var.tenancy_ocid user_ocid = var.user_ocid fingerprint = var.fingerprint private_key_path = var.private_key_path private_key_password=var.private_key_password region = var.region } variable "tenancy_ocid"{ default = "ocid1.tenancy.oc1..aaaaaaaaflrtum2h76ryycq3l3bfiwkqfekinzvji6k4kdqc3wpqp7wzofpq" } variable "user_ocid"{ default = "ocid1.user.oc1..aaaaaaaa5viuloi6zdgjbominnxn3v5irfznwin5r3ybamgfil2fugtrxjya" } variable "fingerprint"{ default = "db:9f:c2:9a:17:cd:34:1c:53:e6:87:4e:8a:b4:6b:0f" } variable "private_key_path"{ default = "/Users/brunotechdatabasket/.oci/oci_api_key.pem" } variable "private_key_password"{ default = “*******” } variable "region"{ default = "uk-london-1" } variable "compartment_ocid"{ default = "ocid1.compartment.oc1..aaaaaaaauos74rsl3aymrlbdnr6uocvtofm4s5fh57w4rpdr373qjjdsh47a" }
After you have added the resources to create a new compartment, an user and a group for both the user and the new compartment when you run the “terraform plan” command, it is possible to see whether running the command “terraform apply” adds some modification which will be done at the OCI as below:
brunotechdatabasket@Brunos-MacBook-Pro Terraform % cat terraformcomp.tf # Configure the Oracle Cloud Infrastructure provider with an API Key provider "oci" { tenancy_ocid = var.tenancy_ocid user_ocid = var.user_ocid fingerprint = var.fingerprint private_key_path = var.private_key_path private_key_password=var.private_key_password region = var.region } variable "tenancy_ocid"{ default = "ocid1.tenancy.oc1..aaaaaaaaflrtum2h76ryycq3l3bfiwkqfekinzvji6k4kdqc3wpqp7wzofpq" } variable "user_ocid"{ default = "ocid1.user.oc1..aaaaaaaa5viuloi6zdgjbominnxn3v5irfznwin5r3ybamgfil2fugtrxjya" } variable "fingerprint"{ default = "db:9f:c2:9a:17:cd:34:1c:53:e6:87:4e:8a:b4:6b:0f" } variable "private_key_path"{ default = "/Users/brunotechdatabasket/.oci/oci_api_key.pem" } variable "private_key_password"{ default = “*******” } variable "region"{ default = "uk-london-1" } variable "compartment_ocid"{ default = "ocid1.compartment.oc1..aaaaaaaauos74rsl3aymrlbdnr6uocvtofm4s5fh57w4rpdr373qjjdsh47a" } ##AFTER RESOURCES resource "oci_identity_compartment" "newcomp" { #Required description = "new compartment created using Terraform" name = "cp-compartmentnew" } output "compartments"{ value= oci_identity_compartment.newcomp.compartment_id } resource "oci_identity_user" "newtest_user" { #Required description = "new user created using Terraform" name = "cp-user-Maria" compartment_id =oci_identity_compartment.newcomp.compartment_id } output "newtest_user"{ value= oci_identity_user.newtest_user.name } resource "oci_identity_ui_password" "newtest_userpassword" { user_id = oci_identity_user.newtest_user.id } output "newtest_password"{ sensitive = true value=oci_identity_ui_password.newtest_userpassword.password } resource "oci_identity_group" "new_group" { name = "cp-newgroup" description="new identity group using Terraform" } resource "oci_identity_user_group_membership" "new_ug" { group_id = oci_identity_group.new_group.id user_id=oci_identity_user.newtest_user.id } brunotechdatabasket@Brunos-MacBook-Pro Terraform % terraform init Initializing the backend... Initializing provider plugins... - Using previously-installed hashicorp/oci v3.97.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, we recommend adding version constraints in a required_providers block in your configuration, with the constraint strings suggested below. * hashicorp/oci: version = "~> 3.97.0" 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. brunotechdatabasket@Brunos-MacBook-Pro Terraform % terraform plan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # oci_identity_compartment.newcomp will be created + resource "oci_identity_compartment" "newcomp" { + compartment_id = (known after apply) + defined_tags = (known after apply) + description = "new compartment created using Terraform" + freeform_tags = (known after apply) + id = (known after apply) + inactive_state = (known after apply) + is_accessible = (known after apply) + name = "cp-compartmentnew" + state = (known after apply) + time_created = (known after apply) } # oci_identity_group.new_group will be created + resource "oci_identity_group" "new_group" { + compartment_id = (known after apply) + defined_tags = (known after apply) + description = "new identity group using Terraform" + freeform_tags = (known after apply) + id = (known after apply) + inactive_state = (known after apply) + name = "cp-newgroup" + state = (known after apply) + time_created = (known after apply) } # oci_identity_ui_password.newtest_userpassword will be created + resource "oci_identity_ui_password" "newtest_userpassword" { + id = (known after apply) + inactive_status = (known after apply) + password = (known after apply) + state = (known after apply) + time_created = (known after apply) + user_id = (known after apply) } # oci_identity_user.newtest_user will be created + resource "oci_identity_user" "newtest_user" { + capabilities = (known after apply) + compartment_id = (known after apply) + defined_tags = (known after apply) + description = "new user created using Terraform" + email = (known after apply) + external_identifier = (known after apply) + freeform_tags = (known after apply) + id = (known after apply) + identity_provider_id = (known after apply) + inactive_state = (known after apply) + name = "cp-user-Maria" + state = (known after apply) + time_created = (known after apply) } # oci_identity_user_group_membership.new_ug will be created + resource "oci_identity_user_group_membership" "new_ug" { + compartment_id = (known after apply) + group_id = (known after apply) + id = (known after apply) + inactive_state = (known after apply) + state = (known after apply) + time_created = (known after apply) + user_id = (known after apply) } Plan: 5 to add, 0 to change, 0 to destroy. Changes to Outputs: + compartments = (known after apply) + newtest_password = (sensitive value) + newtest_user = "cp-user-Maria" - show-ads = [ - { - compartment_id = "ocid1.compartment.oc1..aaaaaaaauos74rsl3aymrlbdnr6uocvtofm4s5fh57w4rpdr373qjjdsh47a" - id = "ocid1.availabilitydomain.oc1..aaaaaaaapjv4p3qtly2fesrig77q4tlmi3wvakeet6fskc7do2fmawz3xctq" - name = "jfUx:UK-LONDON-1-AD-1" }, - { - compartment_id = "ocid1.compartment.oc1..aaaaaaaauos74rsl3aymrlbdnr6uocvtofm4s5fh57w4rpdr373qjjdsh47a" - id = "ocid1.availabilitydomain.oc1..aaaaaaaac6kgqnl5eberztbdm2ufhpxohk7cuelajmafpqa3m6rpri4tc2yq" - name = "jfUx:UK-LONDON-1-AD-2" }, - { - compartment_id = "ocid1.compartment.oc1..aaaaaaaauos74rsl3aymrlbdnr6uocvtofm4s5fh57w4rpdr373qjjdsh47a" - id = "ocid1.availabilitydomain.oc1..aaaaaaaaw2i3i53quioaywmhx56ss5plwk7bmmeg2266lo7inilhbizeroua" - name = "jfUx:UK-LONDON-1-AD-3" }, ] -> null ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.
The command “terraform plan” now is showing the results “Plan: 5 to add, 0 to change, 0 to destroy.” which means that 5 resources can be added after the command “terraform apply -auto-approve” as below:
brunotechdatabasket@Brunos-MacBook-Pro Terraform % terraform apply -auto-approve oci_identity_group.new_group: Creating... oci_identity_compartment.newcomp: Creating... oci_identity_group.new_group: Creation complete after 3s [id=ocid1.group.oc1..aaaaaaaay3ny2q5gp7lsptcuob6tnp5hchjwkqunr4axnqliewcc4m73ugda] oci_identity_compartment.newcomp: Creation complete after 5s [id=ocid1.compartment.oc1..aaaaaaaaafzhugumcz63gffvzunn25k4f7fhbgczngmaz6c6rg4kzrhzcgda] oci_identity_user.newtest_user: Creating... oci_identity_user.newtest_user: Creation complete after 0s [id=ocid1.user.oc1..aaaaaaaahmusibsec7zwlqcamhb63mg7wxqlbuwg4zjojp3b4g6chadgkoeq] oci_identity_ui_password.newtest_userpassword: Creating... oci_identity_user_group_membership.new_ug: Creating... oci_identity_ui_password.newtest_userpassword: Creation complete after 1s [id=ocid1.user.oc1..aaaaaaaahmusibsec7zwlqcamhb63mg7wxqlbuwg4zjojp3b4g6chadgkoeq] oci_identity_user_group_membership.new_ug: Creation complete after 1s [id=ocid1.groupmembership.oc1..aaaaaaaapdx7x7g2ow7vvm2t74ynriamp2lczkvssxzwzgh2ybnualonc4sa] Apply complete! Resources: 5 added, 0 changed, 0 destroyed. Outputs: compartments = ocid1.tenancy.oc1..aaaaaaaaflrtum2h76ryycq3l3bfiwkqfekinzvji6k4kdqc3wpqp7wzofpq newtest_password = <sensitive> newtest_user = cp-user-Maria brunotechdatabasket@Brunos-MacBook-Pro Terraform %
After the resource is added, go to the OCI console, and check the creation of the user and the new compartment as below:
As an overview, during this second article you could see how the use of terraform could add resources on the OCI. On the next article we will learn how it’s possible to create policies and other features of Terraform within OCI.
Hi! I am Bruno, a Brazilian born and bred, and I am also a naturalized Swedish citizen. I am a former Oracle ACE and, to keep up with academic research, I am a Computer Scientist with an MSc in Data Science and another MSc in Software Engineering. I have over ten years of experience working with companies such as IBM, Epico Tech, and Playtech across three different countries (Brazil, Hungary, and Sweden), and I have joined projects remotely in many others. I am super excited to share my interests in Databases, Cybersecurity, Cloud, Data Science, Data Engineering, Big Data, AI, Programming, Software Engineering, and data in general.
(Continue reading)