Packer
Oracle
@hashicorp
The Oracle multi-component plugin can be used with HashiCorp Packer to create custom images.
- Community
- HCP Ready
Updated 2 years ago
- GitHub(opens in new tab)
Oracle Cloud Infrastructure Classic
Type: oracle-classic
Artifact BuilderId: packer.oracle.classic
The oracle-classic
Packer builder is able to create custom images for use
with Oracle Cloud Infrastructure Classic
Compute. The builder takes a base
image, runs any provisioning necessary on the base image after launching it,
and finally snapshots it creating a reusable custom image.
It is recommended that you familiarise yourself with the Key Concepts and Terminology prior to using this builder if you have not done so already.
The builder does not manage images. Once it creates an image, it is up to you to use it or delete it.
Authorization
This builder authenticates API calls to Oracle Cloud Infrastructure Classic Compute using basic authentication (user name and password). To read more, see the authentication documentation
Configuration Reference
There are many configuration options available for the oracle-classic
builder. This builder currently only works with the SSH communicator.
Required
api_endpoint
(string) - This is your custom API endpoint for sending requests. Instructions for determining your API endpoint can be found heredest_image_list
(string) - Where to save the machine image to once you've provisioned it. If the provided image list does not exist, Packer will create it.identity_domain
(string) - This is your customer-specific identity domain as generated by Oracle. If you don't know what your identity domain is, ask your account administrator. For a little more information, see the Oracle documentation.source_image_list
(string) - This is what image you want to use as your base image. See the documentation for more details. You may use either a public image list, or a private image list. To see what public image lists are available, you can use the CLI, as described heresource_image_list_entry
(string) - The entry identifying the machine image to use in the image list. Defaults to the latest available entry.password
(string) - Your account password.shape
(string) - The template that determines the number of CPUs, amount of memory, and other resources allocated to a newly created instance. For more information about shapes, see the documentation here.username
(string) - Your account username.
Optional
attributes
(string) - (string) - Attributes to apply when launching the instance. Note that you need to be careful about escaping characters due to the templates being JSON. It is often more convenient to useattributes_file
, instead. You may only define eitherattributes
orattributes_file
, not both.attributes_file
(string) - Path to a json file that will be used for the attributes when launching the instance. You may only define eitherattributes
orattributes_file
, not both.image_description
(string) - a description for your destination image list. If you don't provide one, Packer will provide a generic description.ssh_username
(string) - The username that Packer will use to SSH into the instance; required if using SSH. The default oracle user with sudo privileges isopc
, so you may setssh_username
toopc
if you have not yet configured users on your machine. If you have already configured users on your machine, you may prompt Packer to use one of those instead. For more detail, see the documentation.image_name
(string) - The name to assign to the resulting custom image.persistent_volume_size
(int) - Size in gigabytes of the persistent boot storage volume to build the image on. Use this if you want a bigger volume than what instance storage provides. Note that using this option puts the builder into a "persistent volume" mode, which is substantially different than the default snapshot mode. Please see the configuration section below for additional configuration options.snapshot_timeout
(string) - How long to wait for a snapshot to be created. Expects a positive golang Time.Duration string, which is a sequence of decimal numbers and a unit suffix; valid suffixes arens
(nanoseconds),us
(microseconds),ms
(milliseconds),s
(seconds),m
(minutes), andh
(hours). Examples of valid inputs:100ms
,250ms
,1s
,2.5s
,2.5m
,1m30s
. Example:"snapshot_timeout": "15m"
. Default:20m
.
Persistent Volume Build
You will use this type of build if you've set the persistent_volume_size
option. If you need a bigger disk than what you normally get with instance
storage, you'll want to set this.
In the persistent volume mode, things are built a little differently. Normally, we launch an instance, then provision it and take a snapshot, which becomes your machine image. This relies on the disk of the created instance being large enough to perform your entire provisioning process. If that disk size isn't sufficient, we can build with a persistent volume of arbitrary size.
First, we create a persistent volume of the requested size. This volume is bootable and initialized with your image list. We start an instance with this volume as the boot volume. After this instance launches, we provision and terminate it, leaving the persistent volume around.
Next, we create a second instance, the "builder", this time booting from instance storage. We also attach a new persistent volume, making it twice the size of the original. We connect to this instance and copy the contents of the first volume into a tarball file on the second volume. We then upload this file to Object Storage Classic, and create a new machine image with it.
If this is set, a few more options become available.
builder_communicator
(communicator) - This represents anssh communicator
, and can be configured as such. If you use a different builder image, you may need to change thessh_username
, for example. That might look like this:{ "builders": [ { "builder_communicator": { "ssh_username": "soandso" }, "type": "oracle-classic" } ] }
See below for more details on configuring this communicator.
builder_image_list
(string) - This is the image to use for the builder instance. This must be a linux image, and Oracle Linux is recommended. Default:/oracle/public/OL_7.2_UEKR4_x86_64
.builder_image_list_entry
(string) - The entry identifying the machine image to use in the image list. Ifbuilder_image_list
is unset, this defaults to5
, which is a working image as of this time. Otherwise, it defaults to the latest entry. Set this to0
to force it to use the latest entry when using the defaultbuilder_image_list
.builder_shape
(string) - The template that determines the number of CPUs, amount of memory, and other resources allocated to the builder instance. Default:oc3
.builder_upload_image_command
(string) - The command to run to upload the image to Object Storage Classic. This is for advanced users only, and you should consult the default in code to decide on the changes to make. For most users the default should suffice. If you choose to write your own, this command is a template engine and can make use of the following variables:{{ .Username }}
,{{ .Password }}
,{{ .AccountID }}
,{{ .ImageFile }}
, and{{ .SegmentPath }}
.
Communicator Configuration
The builder_communicator
has the following options:
Optional:
communicator
(string) - Packer currently supports three kinds of communicators:none
- No communicator will be used. If this is set, most provisioners also can't be used.ssh
- An SSH connection will be established to the machine. This is usually the default.winrm
- A WinRM connection will be established.
In addition to the above, some builders have custom communicators they can use. For example, the Docker builder has a "docker" communicator that uses
docker exec
anddocker cp
to execute scripts and copy files.pause_before_connecting
(duration string | ex: "1h5m2s") - We recommend that you enable SSH or WinRM as the very last step in your guest's bootstrap script, but sometimes you may have a race condition where you need Packer to wait before attempting to connect to your guest.If you end up in this situation, you can use the template option
pause_before_connecting
. By default, there is no pause. For example if you setpause_before_connecting
to10m
Packer will check whether it can connect, as normal. But once a connection attempt is successful, it will disconnect and then wait 10 minutes before connecting to the guest and beginning provisioning.
ssh_host
(string) - The address to SSH to. This usually is automatically configured by the builder.ssh_port
(int) - The port to connect to SSH. This defaults to22
.ssh_username
(string) - The username to connect to SSH with. Required if using SSH.ssh_password
(string) - A plaintext password to use to authenticate with SSH.ssh_ciphers
([]string) - This overrides the value of ciphers supported by default by Golang. The default value is [ "aes128-gcm@openssh.com", "chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", ]Valid options for ciphers include: "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "chacha20-poly1305@openssh.com", "arcfour256", "arcfour128", "arcfour", "aes128-cbc", "3des-cbc",
ssh_clear_authorized_keys
(bool) - If true, Packer will attempt to remove its temporary key from~/.ssh/authorized_keys
and/root/.ssh/authorized_keys
. This is a mostly cosmetic option, since Packer will delete the temporary private key from the host system regardless of whether this is set to true (unless the user has set the-debug
flag). Defaults to "false"; currently only works on guests withsed
installed.ssh_key_exchange_algorithms
([]string) - If set, Packer will override the value of key exchange (kex) algorithms supported by default by Golang. Acceptable values include: "curve25519-sha256@libssh.org", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha1", and "diffie-hellman-group1-sha1".ssh_certificate_file
(string) - Path to user certificate used to authenticate with SSH. The~
can be used in path and will be expanded to the home directory of current user.ssh_pty
(bool) - Iftrue
, a PTY will be requested for the SSH connection. This defaults tofalse
.ssh_timeout
(duration string | ex: "1h5m2s") - The time to wait for SSH to become available. Packer uses this to determine when the machine has booted so this is usually quite long. Example value:10m
. This defaults to5m
, unlessssh_handshake_attempts
is set.ssh_disable_agent_forwarding
(bool) - If true, SSH agent forwarding will be disabled. Defaults tofalse
.ssh_handshake_attempts
(int) - The number of handshakes to attempt with SSH once it can connect. This defaults to10
, unless assh_timeout
is set.ssh_bastion_host
(string) - A bastion host to use for the actual SSH connection.ssh_bastion_port
(int) - The port of the bastion host. Defaults to22
.ssh_bastion_agent_auth
(bool) - Iftrue
, the local SSH agent will be used to authenticate with the bastion host. Defaults tofalse
.ssh_bastion_username
(string) - The username to connect to the bastion host.ssh_bastion_password
(string) - The password to use to authenticate with the bastion host.ssh_bastion_interactive
(bool) - Iftrue
, the keyboard-interactive used to authenticate with bastion host.ssh_bastion_private_key_file
(string) - Path to a PEM encoded private key file to use to authenticate with the bastion host. The~
can be used in path and will be expanded to the home directory of current user.ssh_bastion_certificate_file
(string) - Path to user certificate used to authenticate with bastion host. The~
can be used in path and will be expanded to the home directory of current user.ssh_file_transfer_method
(string) -scp
orsftp
- How to transfer files, Secure copy (default) or SSH File Transfer Protocol.NOTE: Guests using Windows with Win32-OpenSSH v9.1.0.0p1-Beta, scp (the default protocol for copying data) returns a a non-zero error code since the MOTW cannot be set, which cause any file transfer to fail. As a workaround you can override the transfer protocol with SFTP instead
ssh_file_transfer_protocol = "sftp"
.ssh_proxy_host
(string) - A SOCKS proxy host to use for SSH connectionssh_proxy_port
(int) - A port of the SOCKS proxy. Defaults to1080
.ssh_proxy_username
(string) - The optional username to authenticate with the proxy server.ssh_proxy_password
(string) - The optional password to use to authenticate with the proxy server.ssh_keep_alive_interval
(duration string | ex: "1h5m2s") - How often to send "keep alive" messages to the server. Set to a negative value (-1s
) to disable. Example value:10s
. Defaults to5s
.ssh_read_write_timeout
(duration string | ex: "1h5m2s") - The amount of time to wait for a remote command to end. This might be useful if, for example, packer hangs on a connection after a reboot. Example:5m
. Disabled by default.ssh_remote_tunnels
([]string) -ssh_local_tunnels
([]string) -
ssh_private_key_file
(string) - Path to a PEM encoded private key file to use to authenticate with SSH. The~
can be used in path and will be expanded to the home directory of current user.
Basic Example
Here is a basic example. Note that account specific configuration has been
obfuscated; you will need to add a working username
, password
,
identity_domain
, and api_endpoint
in order for the example to work.
HCL2
locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }
source "oracle-classic" "basic" {
api_endpoint = "https://api-###.compute.###.oraclecloud.com/"
attributes = "{\"userdata\": {\"pre-bootstrap\": {\"script\": [\"...\"]}}}"
dest_image_list = "Packer_Builder_Test_List"
identity_domain = "#######"
image_name = "Packer_Builder_Test_${local.timestamp}"
password = "supersecretpasswordhere"
shape = "oc3"
source_image_list = "/oracle/public/OL_7.2_UEKR4_x86_64"
username = "myuser@myaccount.com"
}
build {
sources = ["source.oracle-classic.basic"]
provisioner "shell" {
inline = ["echo hello"]
}
}
JSON
{
"builders": [
{
"type": "oracle-classic",
"username": "myuser@myaccount.com",
"password": "supersecretpasswordhere",
"identity_domain": "#######",
"api_endpoint": "https://api-###.compute.###.oraclecloud.com/",
"source_image_list": "/oracle/public/OL_7.2_UEKR4_x86_64",
"shape": "oc3",
"image_name": "Packer_Builder_Test_{{timestamp}}",
"attributes": "{\"userdata\": {\"pre-bootstrap\": {\"script\": [\"...\"]}}}",
"dest_image_list": "Packer_Builder_Test_List"
}
],
"provisioners": [
{
"type": "shell",
"inline": ["echo hello"]
}
]
}
Basic Example -- Windows
Attributes file is optional for connecting via ssh, but required for winrm.
The following file contains the bare minimum necessary to get winRM working; you have to give it the password to give to the "Administrator" user, which will be the one winrm connects to. You must also whitelist your computer to connect via winRM -- the empty braces below whitelist any computer to access winRM but you can make it more secure by only allowing your build machine access. See the docs for more details on how to define a trusted host.
Save this file as windows_attributes.json
:
{
"userdata": {
"administrator_password": "password",
"winrm": {}
}
}
Following is a minimal but working Packer config that references this attributes file:
HCL2
variable "opc_api_endpoint" {
type = string
default = "${env("OPC_ENDPOINT")}"
}
variable "opc_identity_domain" {
type = string
default = "${env("OPC_IDENTITY_DOMAIN")}"
}
variable "opc_password" {
type = string
default = "${env("OPC_PASSWORD")}"
}
variable "opc_username" {
type = string
default = "${env("OPC_USERNAME")}"
}
locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }
source "oracle-classic" "windows_attrs" {
api_endpoint = "${var.opc_api_endpoint}"
attributes_file = "./windows_attributes.json"
communicator = "winrm"
dest_image_list = "Packer_Windows_Demo"
identity_domain = "${var.opc_identity_domain}"
image_name = "Packer_Windows_Demo_${local.timestamp}"
password = "${var.opc_password}"
shape = "oc3"
source_image_list = "/Compute-${var.opc_identity_domain}/${var.opc_username}/Microsoft_Windows_Server_2012_R2-17.3.6-20170930-124649"
username = "${var.opc_username}"
winrm_password = "password"
winrm_username = "Administrator"
}
build {
sources = ["source.oracle-classic.windows_attrs"]
provisioner "powershell" {
inline = "Write-Output(\"HELLO WORLD\")"
}
}
JSON
{
"variables": {
"opc_username": "{{ env `OPC_USERNAME`}}",
"opc_password": "{{ env `OPC_PASSWORD`}}",
"opc_identity_domain": "{{env `OPC_IDENTITY_DOMAIN`}}",
"opc_api_endpoint": "{{ env `OPC_ENDPOINT`}}"
},
"builders": [
{
"type": "oracle-classic",
"username": "{{ user `opc_username`}}",
"password": "{{ user `opc_password`}}",
"identity_domain": "{{ user `opc_identity_domain`}}",
"api_endpoint": "{{ user `opc_api_endpoint`}}",
"source_image_list": "/Compute-{{ user `opc_identity_domain` }}/{{ user `opc_username`}}/Microsoft_Windows_Server_2012_R2-17.3.6-20170930-124649",
"attributes_file": "./windows_attributes.json",
"shape": "oc3",
"image_name": "Packer_Windows_Demo_{{timestamp}}",
"dest_image_list": "Packer_Windows_Demo",
"communicator": "winrm",
"winrm_username": "Administrator",
"winrm_password": "password"
}
],
"provisioners": [
{
"type": "powershell",
"inline": "Write-Output(\"HELLO WORLD\")"
}
]
}
Persistent Volume Example
Here is an example using a persistent volume. Note the persistent_volume_size
setting.
HCL2
variable "opc_api_endpoint" {
type = string
default = "${env("OPC_ENDPOINT")}"
}
variable "opc_identity_domain" {
type = string
default = "${env("OPC_IDENTITY_DOMAIN")}"
}
variable "opc_password" {
type = string
default = "${env("OPC_PASSWORD")}"
}
variable "opc_username" {
type = string
default = "${env("OPC_USERNAME")}"
}
locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }
source "oracle-classic" "persistent" {
api_endpoint = "${var.opc_api_endpoint}"
dest_image_list = "Packer_Builder_Test_List"
identity_domain = "${var.opc_identity_domain}"
image_name = "Packer_Builder_Test_${local.timestamp}"
password = "${var.opc_password}"
persistent_volume_size = 15
shape = "oc3"
source_image_list = "/oracle/public/OL_7.2_UEKR4_x86_64"
ssh_username = "opc"
username = "${var.opc_username}"
}
build {
sources = ["source.oracle-classic.persistent"]
provisioner "shell" {
inline = ["echo hello"]
}
}
JSON
{
"variables": {
"opc_username": "{{ env `OPC_USERNAME`}}",
"opc_password": "{{ env `OPC_PASSWORD`}}",
"opc_identity_domain": "{{env `OPC_IDENTITY_DOMAIN`}}",
"opc_api_endpoint": "{{ env `OPC_ENDPOINT`}}"
},
"builders": [
{
"type": "oracle-classic",
"username": "{{ user `opc_username`}}",
"password": "{{ user `opc_password`}}",
"identity_domain": "{{ user `opc_identity_domain`}}",
"api_endpoint": "{{ user `opc_api_endpoint`}}",
"source_image_list": "/oracle/public/OL_7.2_UEKR4_x86_64",
"persistent_volume_size": 15,
"image_name": "Packer_Builder_Test_{{timestamp}}",
"dest_image_list": "Packer_Builder_Test_List",
"ssh_username": "opc",
"shape": "oc3"
}
],
"provisioners": [
{
"type": "shell",
"inline": ["echo hello"]
}
]
}