Automating Instance Initialization with Terraform on Oracle's Compute Cloud

This article outlines the different approaches that can be used to automate instance initialization as part of the initial Oracle Cloud Infrastructure Compute Classic instance resource provisioning using Terraform.

Specifically we will cover two distinct options for instance initialization and provisioning on top of the initial instance resource creation

  • using OS specific opc-init or cloud-init configuration during instance creation
  • using Terraform Provisioners as part of the resource provisioning

The choice of which approach to use will depended on the specific provisioning requirements. Each approach has its merits and drawbacks, a key distinction between the two approaches is that the opc-init/cloud-init approach passes the initialization configuration directly to the instances during creation and startup through the cloud infrastructure control plane, enabling the instances to handle the initialization autonomously, whereas the Terraform Provisioner has to connect into the running instances to perform the additional provisioning tasks after initial instance creation. Both approaches can be combined as part of the overall provisioning process.

Instance Initialization using opc-init

opc-init support is included by default in Oracle-provided Oracle Linux and Microsoft Windows machine images for Oracle Compute Cloud, and may be incorporated into custom images. The opc-init scripts query the meta-data service during startup for user-data that is then used to perform the required pre-bootstrap tasks, including:

  • Linux — set the http and https proxies, execute pre-bootstrap scripts, installing yum packages, execute Chef provisioning tasks
  • Windows — configure the Administrator account, create users, execute pre-bootstrap scripts, enable remote management, enable remote desktop

For full details of the supported opc-init instance initialization capabilities see the documentation Automating Instance Initialization Using opc-init

Example: Oracle Linux instance with opc-init pre-bootstrap

The opc_compute_instance instance_attributes is a JSON payload that is passed directly to the OPC Cloud Launch Plan that Terraform uses to create the instance. Heredoc notation is used embed the JSON content within the Terraform HCL configuration.

This example demonstrates a simple pre-bootstrap provisioning script that appends to the instance motd (message of the day).

Example: Windows Server instance with opc-init pre-bootstrap

This example configures the userdata with the image options to set the initial Administrator Password, enable Remote Desktop, and execute a pre-bootstrap scripts that is dynamically fetched from a remote URL.

Rather than creating the JSON payload string directly in the instance resource, for this example we use a template_file Data Source to demonstrate how variables can be passed in to dynamically construct a custom payload.

Instance Initialization using cloud-init

cloud-init support is provided with several of the third party provided base OS and application images available from the Oracle Cloud Marketplace. Similar to the opc-init examples above, additional initialization configuration is defined in the instance_attributes which are passed though to the launch plan when creating the instance resource. The cloud-init cloud-config data is in YAML format which and passed in the userdata attribute.

Refer to image vendors documentation and general cloud-init specification for full details on the supported cloud-config options.

Note that as the instance_attributes expects a string containing JSON, so it's important the ensure the cloud-init cloud-config YAML is properly encoded/escaped for passing as a JSON string in the userdata field.

Example: Ubuntu instance with cloud-init

Again we’ll use a simple example for demonstration purposes to update the system motd.

The userdata and cloud-config are separated into two separate templates in this example to aid readability.

Instance Initialization using Terraform Provisioners

Terraform supports several Provisioners that enable coordination of additional provisioning steps after the initial instance resource creation.

Example: Oracle Linux instance with remote-exec provisioner

Taking the same example from above, this time we use the Terraform Provisioner to execute a remote command that updates the motd message of the day.

Note that the connection block defines how Terraform will connect to the newly created instance. For simplicity the above example is using a publicly assigned IP address reservation so the host is accessible, and assumes the For-SSH-access security list has already been defined to allow SSH access to the instance.

For instances that are being created without a public IP address Terraform also supports connecting through a Bastion Host with SSH. If Terraform in running within the same compute domain or has access via VPN to the domains shared private network then the instances self.private_ip could be used, or the private IP assigned to the vnic if the instance is launched with an interface on a private IP Network.

Example: Windows Server instance with remote-exec provisioner

Terraform supports winrm connections for provisioning Windows based instances. Note that for the Oracle provided Microsoft Windows images for Oracle Compute Cloud we need combine with the use of the opc-init configuration in order to set the initial Administrator password and configure the winrm

Similar to the “Example: Windows Server instance with opc-init pre-bootstrap” above this examples demonstrates how to run a bootstrap script. Instead of having the instance download the bootstrap script via a remote URL this example uploads the script from the local environment to the new instance and then executes it.

The For-WinRM-access security list must be defined to enabled remote management. The default ports used for WS-Management and PowerShell remoting are 5985 and 5986 for connections over HTTP and HTTPS, respectively

Continue reading with Part 2