mintpress-infrastructure-oci
Repository to provider helper functions for Oracle OCI infrastructure
Required Reading
If you haven’t read the introductory documentation for the Mintpress Infrastructure Framework, a lot of this won’t make a whole lot of sense. [link]
What Services Are Provided
-
OciPlatform - the Platform provider
-
OciHost - Compute Hosts
-
OciStorage - iSCSI block storage
What other resources are provided?
-
OciSecurityGroup
-
OciSecurityGroupRule
-
OciSecurityListRule
Limitations
-
Disks MUST be 50gbytes of greater - this is a platform limitations. Practically, this means you can NOT create, for example, a 4gb swap disk and expect that to work. (In the legacy mintpress platform, disks smaller than this will automatically be grown to this size for compatibility reasons).
Getting Started
To use the OCI controller, you will require:
-
OCI Credentials. This consist of a user, a keyfile, a fingerprint, a tennancy, and a compartment
-
A public/private keypair for the VMs you wish to create
-
A region and availability domain within that region
Most resources work better if you declare your platform first - this is done in the usual way (see the mintpress-infrastructure documentation for details about Using
resources)
require 'mintpress-infrastructure-oci'
include MintPress::InfrastructureOci
# Setup the provider - this provider does not uses dnslabels provided by OCI
# This provider will attach a public IP to the VMs along with a private IP
# You can also do this without specifying the name property of the provider, if you do that, the VMHost initialization should remove the provider property as well
UsingOciPlatform.new(name: 'public_subnet',
all_platform_services: true,
fingerprint: 'redacted'
key_file: '/home/mintpress/.oci/oci_api_key.pem',
region: 'ap-sydney-1',
tenancy: 'ocid1.tenancy.oc1..redacted',
compartment: 'ocid1.tenancy.oc1..redacted',
availability_domain: 'BTaG:AP-SYDNEY-1-AD-1',
user: 'ocid1.user.oc1..redacted',
subnet_id: 'ocid1.subnet.oc1.ap-sydney-1.redacted',
assign_public_ip: true,
preserve_hostinfo: 2,
admin_connect_user: 'opc',
admin_final_user: 'root',
keys: ['/home/mintpress/oci-ssh-key'],
public_key: 'ssh-rsa redacted')
Flexable Shapes
The provider now supports flexable shapes - these will maek the VM match cpu_count and ram_gb. To use this: * Set the use_flex
property to true * Set your flexable shape type in the flex_shape
property - this defaults to VM.Standard.E4.Flex
.
Image Selection
OCI implements a facility for searching for images by OS type and revision, rather than just via direct image IDs. This is controlled by the operating_system
and operating_system_version
parameters on either of OciHost(VMHost) or OciPlatform
For example:
# As always, we use OCIHost directly if we're going to use OCI specific parameters - this could be VMHost.new if you were not!
info 'Creating Latest Oracle Linux Version 6'
host_oel6latest = OCIHost.new(name: 'oel6latest.mintpress.io', native_instance_type: 'VM.Standard.E2.4', operating_system: 'Oracle Linux', operating_system_version: 6)
host_oel6latest.create
Will find an Oracle Linux 6 image to use. Note that, on the OCI platform, images are tied to shapes, which is the OCI term for compute sizes - hence for the general case, it makes sense to specify semantically if at all possible.
The search semantics are: * If you specified the name of the image, e.g. Oracle-Linux-7.7-2019.09.25-0 we search directly against that image, if the image is not found, we raise error * Otherwise, we select the newest image based on shape, operating_system, and operating_system_version
For the OS search, you can specify either a major version only (i.e 7), or a major/minor pair (i.e. 7.5)
Block Storage
From the end user perspective, block storage works the same as it does on any other platform - i.e by using add_block_device
on the ost, by attaching the OCIStorage resource to the hosts block_devices
property, or by using the UsingExtraOCIStorage
resources.
# One way to create a vm with a 50gbyte /opt
UsingExtraOCIStorage(name: "opt_disk", mount_point: "/opt", size_mb: 50000)
VMHost.new(name: 'oel7latest.mintpress.io', native_instance_type: 'VM.Standard.E2.4', operating_system: 'Oracle Linux', operating_system_version: 7).create
# Another way - add it directly
h = VMHost.new(name: 'oel7latest.mintpress.io', native_instance_type: 'VM.Standard.E2.4', operating_system: 'Oracle Linux', operating_system_version: 7)
h.add_block_device(name: "opt_disk", mount_point: "/opt", size_mb: 50000)
# Or in chef - lets use the native OCI resources so we can specify OCI specific things
infrastructure_oci_oci_host 'oel7latest.mintpress.io' do
native_instance_type "VM.Standard.E2.4"
"Oracle Linux"
7
action :create
end
# Note the shorthand here for the host link - see the main Infrastructure Framework for details on that. The
# usual chef syntax of "infrastructure_oci_oci_host[oel7latest.mintpress.io]" will also work!
infrastructure_oci_oci_storage 'opt_disk' do
mount_point "/opt"
size_mb 50000
host 'oel7latest.mintpress.io'
end
Internally, all OCI block devices are iSCSI luns - behind the scenes, the mintpress bootstrapper will correctly prepare these for use, but be careful not to adjust the fstab entries, particulary the _netdev
argument - if you remove this, the systems will not return after a reboot.
OCI Hostinfo
The OCI boot process involves resetting hostnames and such - this is controlled by the preserve_hostinfo attribute in mintpress.
* A setting of 0 will reset the hostname, /etc/hosts, and /etc/resolv.conf on every reboot.
* A setting of 1 will preserve the hostname, but nothing more * A setting of 2 will preserve all of your changes to hostname, /etc/hosts, and /etc/resolv.conf. This is the default. * A setting of 3 will preserve the hostname and /etc/hosts, but not /etc/resolv.conf
Note that changing this setting will require a reboot - mintpress will handle that reboot on a new create, howeever
Updating live system configuration
OCI implements the update action on hosts, which will reconfigure the network security groups of the system. It will also ensure that any block devices are configured and attached, however at this time it will not remove block devices which have been removed from the configuration.
Additionally, OCI provides the attach_storage
action, to ensure all storage is attached, and the harvest
action, to retrieve the current state of storage and security groups
Security Groups
We support both adding rules to existing Security Lists and Security Groups, as well as creating new security groups. When attaching to hosts, security groups can be specified as either string names (i.e. “testgroup” or OciSecurityGroup objects.
Security Group Rules can be attached via either the group name, group object, or group OCID. The VCN can also be specified, however it is only required if the subnet is not available in the platform definition, or a host that the security group is attached to.
Meaning: This will work:
sec_group = OCINetworkSecurityGroup.new(display_name: "jjtestgroup")
host = OCIHost.new(name: "testhost.mintpress.io", native_instance_type: 'VM.Standard.E2.8', operating_system: 'Oracle Linux', operating_system_version: 7,subnet: my_subnet, network_security_groups: sec_group)
# This works because host and sec_group are linked
sec_group.create
host.create
but this will not, assuming youj don’t have a subnet_id specified in your platform:
sec_group = OCINetworkSecurityGroup.new(display_name: "jjtestgroup")
# This will error because it does not know which VCN to associate the security group with
sec_group.create
See the resources OCINetworkSecurityGroup, OCINetworkSecurityGroupRule, and OCISecurityListRule for full parameter details
infrastructure_oci_security_list_rule "port26,27" do
security_list_id "ocidxxx"
destination_type "CIDR_BLOCK"
destination "0.0.0.0/0"
source "0.0.0.0/0"
direction "INGRESS"
tcp_dport_range_low 26
tcp_dport_range_high 27
protcol 6
end
# Create teh group first
infrastructure_oci_network_security_group "jjgroup" do
display_name "jjgroup"
action :create
end
infrastructure_oci_security_group_rule "port26,27" do
# This can just be OCID as well
network_security_group "infrastructure_oci_network_security_group[jjgroup]"
description "jjrule"
destination_type "CIDR_BLOCK"
destination "0.0.0.0/0"
source "0.0.0.0/0"
direction "INGRESS"
tcp_dport_range_low 26
tcp_dport_range_high 27
protcol 6
action :create
end
# a host can use the groups by resource too, or by ocid
# Create the VM
infrastructure_vm_host osi_fqdn do
network_security_groups "infrastructure_oci_network_security_group[jjgroup]"
bootstrapper "infrastructure_chef_bootstrapper[#{osi_fqdn}]"
specs_cpu_count 4
specs_ram_gb 16
action :create
keys keys
admin_keys keys
admin_connect_user connect_user
admin_final_user 'root'
connect_user connect_user
final_user 'oracle'
action :create
end
Ruby Helper functions for Network Security Groups
We added some ruby helper functions for adding/removing network security groups to/from the list. The update action is also available from other devops tools (such as chef), however the update function will always replace the entire group list, in order to ensure that items can be removed.
# find a VM
testhost = MintPress::Infrastructure::VMHost.new(provider: 'public_subnet', name: 'ol7latest.mintpress.io')
# get the list of existing attached groups
testhost.harvest
# and remove jjtestgroup specifically
testhost.remove_network_security_group_by_display_name('testgroup')
# update
testhost.update
# add a group by name specifically
testhost.add_network_security_group_by_display_name('testgroup')
testhost.update
Examples
# Set up the provider
using_oci_platform "oci_platform" do
all_platform_services true
fingerprint fingerprint
key_file key_file
tenancy tenancy
user user
region region
subnet_id subnet_id
admin_connect_user connect_user
admin_final_user 'root'
connect_user connect_user
final_user 'oracle'
keys keys
admin_keys keys
public_key public_key
public_postfix ext_postfix
private_postfix postfix
assign_public_ip true
display_name display_name
availability_domain availability_domain
compartment compartment
preserve_hostinfo preserve_hostinfo
image image
subnet_id subnet_id
end
# Use chef to bootstrap this
using_chef_bootstrapper osi_fqdn do
chef_environment "new_env"
run_list run_list
node_attributes local_attrs
end
# Create the VM - this is using the generic infrastructrure_vm_host stanza, which does
# NOT allow for OCI specific attributes - if you want to specify OCI specific attributes, you'll
# need to use the infrastructure_oci_oci_host resource instead - the usage is the same as below, however
# it can also take OCI parameters directly.
infrastructure_vm_host osi_fqdn do
bootstrapper "infrastructure_chef_bootstrapper[#{osi_fqdn}]"
specs_cpu_count 4
specs_ram_gb 16
action :create
keys keys
admin_keys keys
admin_connect_user connect_user
admin_final_user 'root'
connect_user connect_user
final_user 'oracle'
end