Showing posts with label terraform. Show all posts
Showing posts with label terraform. Show all posts

Friday, 15 March 2019

Use Terraform in the Oracle Cloud with Stacks

I already described how to use Terraform with the Oracle Cloud Infrastructure (OCI) from on-premise. But with the Resource Manager Stacks, Oracle offers a smart alternative to use Terraform with OCI.


The Resource Manager can be found in the Hamburger menu on the left side.


Click on 'Create Stack' to do so.


The Terraform files are needed in a single zip file, so we need to create some. Find my examples on GitHub.

network.tf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
resource "oci_core_virtual_network" "VCN-Demo" {
  cidr_block     = "${var.VCN_SEDEMO_CIDR}"
  compartment_id = "${var.compartment_ocid}"
  display_name   = "VCN-Demo"
  dns_label      = "demovcn"
}

resource "oci_core_subnet" "SN_Bastion" {
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[0],"name")}"
  cidr_block          = "${var.SN_BASTION_CIDR}"
  display_name        = "SN_Bastion"
  compartment_id      = "${var.compartment_ocid}"
  vcn_id              = "${oci_core_virtual_network.VCN-SE-Demo.id}"
  dns_label           = "snbastion"
}

I like to start with a Virtual Cloud Network (VCN) and a subnet, as these require minimal parameters.

data.tf
1
2
3
data "oci_identity_availability_domains" "ADs" {
  compartment_id = "${var.compartment_ocid}"
}

To avoid hard coding the ocid's of the Availbility Domains (ADs), I query the ADs from the compartment.

variables.tf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
variable "compartment_ocid" {}
variable "region" {}

#########   CIDR  #################

variable "VCN_SEDEMO_CIDR" {
  default = "10.0.0.0/16"
}

variable "SN_BASTION_CIDR" {
  default = "10.0.1.0/24"
}

As with a standard Terraform script, I query the compartment_ocid and region from the environment and set two CIDR blocks for the VCN and the subnet.

provider.tf

1
2
3
provider "oci" {
  region = "${var.region}"
}

Now for the provider.tf, this one gets rather short. As we are already logged into oci, we do not need to handle the key file or user_ocid.


Pack those four files into a zip archive and upload them to the create Stack dialog.


We cannot source the variables via shell, but we can add these to the create dialog and we are done here.


To use the newly created Stack, click on its name or from the menu choose Edit.


Here you can do the usual Terraform plan, apply and destroy actions. Click on Plan and confirm the dialog.


In the Jobs list, you will see a new Terraform Job. Click on its name to see the details. It should succeed and on the bottom you will see the Terraform output.
After that, use Terraform Actions | Apply to create the resources, which should result in a


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

So this is a smart option to use Terraform with OCI without the need of a client software installation or a seperate vm to run the scripts, which could save time and money.

Friday, 3 November 2017

Oracle Cloud Infrastructure and Terraform first steps on Windows

Oracle has released the 'Terraform provider for Oracle Cloud Infrastructure'. This tutorial is written to help with the first steps with Terraform and OCI on Windows.
In contrast to procedural tools like Oracle's ocicli, Terraform implements a declarative approach. That means, the user declares how the resulting architecture should look like and not how to get there. To do all the footwork, Terraform needs to know how to work with the target environment. That is what the Terraform provider for OCI is for.
To start with Terraform on OCI, you need to install Terraform first from releases.hashicorp.com/terraform and put it in your Path.


Check it with terraform -version. Next get the Terraform Provider for OCI from github.com/oracle/terraform-provider-oci. According to Oracle's documentation on GitHub, the windows_amd64 folder found in the windows.zip file must be placed in %APPDATA%/terraform.d/plugins/. A %APPDATA%/terraform.rc would only be needed for compatibility with Terraform 0.9, so that can be skipped if not needed.

Now for the first steps with Terraform and OCI, we need at least the Tenancy OCID and the User OCID from our OCI environment as well as an private/public API key pair, the hash of the public key and the region name. For creating a VCN, we also need the compartment OCID.


The name of the region is on the top and the Tenancy OCID can be copied from the bottom of the the OCI welcome page.


The User OCID is found on the users settings page.


The Compartment OCID is found under Identity/Compartments. Make sure to pick the right compartment.

The API key we need is best created with openssl. Under Windows, get Git Bash with Git for Windows from git-for-windows.github.io and install it. Open Git Bash and run

$ mkdir ~/.oraclebmc (or any directory that is fine for you)
$ openssl genrsa -out ~/.oraclebmc/bmcs_api_key.pem 2048
$ chmod 0700 ~/.oraclebmc
$ chmod 0600 ~/.oraclebmc/bmcs_api_key.pem
$ openssl rsa -pubout -in ~/.oraclebmc/bmcs_api_key.pem -out ~/.oraclebmc/bmcs_api_key_public.pem
$ cat ~/.oraclebmc/bmcs_api_key_public.pem
$ openssl rsa -pubout -outform DER -in ~/.oraclebmc/bmcs_api_key.pem | openssl md5
$ openssl rsa -pubout -outform DER -in ~/.oraclebmc/bmcs_api_key.pem | openssl md5 > ~/.oraclebmc/bmcs_api_key_fingerprint

That should result in the following files:


The public key needs to be copied to the OCI UI, so copy the output from the cat command above ...


... click on Add Public Key and paste your key.


After adding the key, the OCI displays your keys fingerprint information. That should be the same as in bmcs_api_key.pem. If not, retake the steps from the first openssl command.

We need a few environment variables to pass these parameters to terraform. Create a working directory (eg. D:\Terraform-OCI), there create a batch file such as terraform-env.cmd and set the following

setx TF_VAR_tenancy_ocid "<your tenancy ocid>"
setx TF_VAR_user_ocid "<your user ocid>"
setx TF_VAR_fingerprint "<your api key fingerprint from bmcs_api_key.pem>"
setx TF_VAR_private_key_path "d:\Arnes\oraclebmc\bmcs_api_key.pem"
setx TF_VAR_compartment_ocid "<your compartment ocid>"
setx TF_VAR_region "us-phoenix-1"

Setx requires to close the shell and open a new one. Now we need to pass these variables to Terraform, so create a variables.tf with the following:

variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "region" {}

variable "compartment_ocid" {}

variable "VPC-CIDR" {
  default = "10.0.0.0/16"
}

The first six variables are for Terraform to take our according environment variables. Every environment variable beginning with TF_VAR_ will automatically be mapped. We don't need the  CIDR variable right now, but later.
Next we need to pass the mandatory variables to the OCI provider. Create a provider.tf with the following:

provider "oci" {
  tenancy_ocid     = "${var.tenancy_ocid}"
  user_ocid        = "${var.user_ocid}"
  fingerprint      = "${var.fingerprint}"
  private_key_path = "${var.private_key_path}"
  region           = "${var.region}"
} 

Now we are ready for a first run to see if everything is set up correctly. In the working directory run a terraform init.


The OCI provider has been correctly initialized. With terraform plan we can check what Terraform is planning to do: 


Nothing of course, as we don't gave it any instructions on what to build. So let's create something. First we need to create a Virtual Cloud Network (VCN), so create a network.tf with the following

resource "oci_core_virtual_network" "Arne-VCN" {
  cidr_block     = "${var.VPC-CIDR}"
  compartment_id = "${var.compartment_ocid}"
  display_name   = "Arne-VCN"
  dns_label      = "arnevcn"
}

That will define a simple VCN using the CIDR block defined in VPC-CIDR. To see what Terraform will do with that, re-run terraform plan.


This time, Terraform displays, that it wants to create the VCN we defined. Looks good, so let Terraform execute that plan with terraform apply.


That should be done in seconds. Double-check that with the OCI web UI.


If everything worked, the newly created VCN should be shown here. Re-running terraform plan should show no changes. 
For a little more complex example, add the following to network.tf to add an internet gateway and a routing roule to the VCN.

resource "oci_core_internet_gateway" "Arne-IGW" {
  compartment_id = "${var.compartment_ocid}"
  display_name   = "Arne-IGW"
  vcn_id         = "${oci_core_virtual_network.Arne-VCN.id}"
}

resource "oci_core_route_table" "Arne-RT" {
  compartment_id = "${var.compartment_ocid}"
  vcn_id         = "${oci_core_virtual_network.Arne-VCN.id}"
  display_name   = "Arne-RT"

  route_rules {
    cidr_block        = "0.0.0.0/0"
    network_entity_id = "${oci_core_internet_gateway.Arne-IGW.id}"
  }
}

Terraform plan should show, that the VCN won't be touched, as it already exists. But the internet gateway and the routing table with the rule will be created.
This is a very simple example, but the basic setup for using Terraform with OCI is done.