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