Skip to content

Commit 48ad16f

Browse files
andrecorreanetoionut-sturzugfeodoro
authored
Release 0.1.4 (#6)
* Added OKE module with examples for flannel and native cni * changed some parameters * Changed variables names, added preconditions, etc * Finalized the first version of OKE Module * fix: not enforcing TF < 1.3.0 * doc: updates * fix: Operator host added * Added virtual node pools * Added multiple oke examples * feat: clusters added * feat: initial templates * Modified oke examples and readmes * chore: template updated * doc: updates * fix: attributes renamed * fix: examples updated * feat: IAM example added * doc: updates * solved issue with key verification and variables name * solved naming on variables * Modified the native examples * fix: examples updated per new bastion module interface * fix: iam template updated * doc: updates * fix: var name updated * doc: updates * doc: updates * fix: ssh issue * feat: oss module basics * fix: bastion module called remotely * feat: cloud-init basics * feat: cloud-init script cane be provided inline or as file * feat: default_ssh_public_key_path and ssh_public_key_path are overloaded, taking a key string in addition to a key file. * chore: folders renamed * feat: default_ssh_public_key_path and ssh_public_key_path are overloaded, also taking a key string in addition to a key file. * fix: clusters examples updated * fix: clusters updated * doc: updates for clusters * chore: OSS removed * Update README.md * doc: updates * doc: release notes and version bump * chore: vars set with type any * fix: dependency variables strongly typed * chore: dependency variables quoted * doc: updated * doc: updates * doc: examples updated * fic: examples updated * doc: updates * doc: release notes updated --------- Signed-off-by: Andre Correa <[email protected]> Co-authored-by: Ionut Sturzu <[email protected]> Co-authored-by: gfeodoro <[email protected]>
1 parent 594faa6 commit 48ad16f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+3944
-763
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@
1212
marketplace-images/**/*.txt
1313
platform-images/**/*.txt
1414
userdata
15-
mounting-block-volumes.txt
15+
mounting-block-volumes.txt
16+
**/examples/clusters/*
17+
**/creds
18+
**/clean-setup

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This repository contains Terraform modules for managing workload resources in OC
66

77
The following modules are available:
88
- [CIS Compute & Storage](./cis-compute-storage/)
9-
- OKE (Oracle Kubernetes Engine) - soon
9+
- [OKE (Oracle Kubernetes Engine)](./cis-oke/)
1010

1111
Helper modules:
1212
- [Platform Images](./platform-images/) - aids in finding OCI Platform images. Use it to obtain image information for provisioning a Compute instance.

RELEASE-NOTES.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
# May 15, 2024 Release Notes - 0.1.4
2+
3+
## New
4+
1. OKE module added, supporting basic and enhanced clusters, with managed node pools and virtual node pools. See [OKE module](./cis-oke/README.md) for details.
5+
6+
## Updates
7+
1. Compute module can now manage cluster networks and compute clusters. See [Clusters](./cis-compute-storage/README.md#clusters-1) for details.
8+
2. Compute module now supports cloud-init scripts passed in as a file or as a string in [Terraform heredoc style](https://developer.hashicorp.com/terraform/language/expressions/strings#heredoc-strings). See [Compute](./cis-compute-storage/README.md#compute-1) for details.
9+
3. Compute module now supports SSH public keys passed in as a file or as a string.
10+
111
# February 29, 2024 Release Notes - 0.1.3
212

313
## Updates

cis-compute-storage/README.md

Lines changed: 109 additions & 6 deletions
Large diffs are not rendered by default.

cis-compute-storage/SPEC.md

Lines changed: 5 additions & 1 deletion
Large diffs are not rendered by default.

cis-compute-storage/cluster_instances_configuration.tf

Lines changed: 455 additions & 0 deletions
Large diffs are not rendered by default.

cis-compute-storage/clusters.tf

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
2+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
3+
4+
data "oci_identity_availability_domains" "cluster_ads" {
5+
for_each = var.clusters_configuration != null ? (var.clusters_configuration.clusters != null ? var.clusters_configuration.clusters : {}) : {}
6+
compartment_id = each.value.compartment_id != null ? (length(regexall("^ocid1.*$", each.value.compartment_id)) > 0 ? each.value.compartment_id : var.compartments_dependency[each.value.compartment_id].id) : (length(regexall("^ocid1.*$", var.clusters_configuration.default_compartment_id)) > 0 ? var.clusters_configuration.default_compartment_id : var.compartments_dependency[var.clusters_configuration.default_compartment_id].id)
7+
}
8+
9+
locals {
10+
cluster_networks = { for k, v in (var.clusters_configuration != null ? (var.clusters_configuration.clusters != null ? var.clusters_configuration.clusters : {}) : {}) : k => v if lower(coalesce(v.type,"cluster_network")) == "cluster_network"}
11+
compute_clusters = { for k, v in (var.clusters_configuration != null ? (var.clusters_configuration.clusters != null ? var.clusters_configuration.clusters : {}) : {}) : k => v if lower(coalesce(v.type,"cluster_network")) != "cluster_network"}
12+
}
13+
14+
resource "oci_core_cluster_network" "these" {
15+
for_each = local.cluster_networks
16+
lifecycle {
17+
## Check 1: cluster_network_settings is required for clusters of type "cluster_network".
18+
precondition {
19+
condition = lower(coalesce(each.value.type,"cluster_network")) == "cluster_network" && each.value.cluster_network_settings == null ? false : true
20+
error_message = "VALIDATION FAILURE in cluster \"${each.key}\": \"cluster_network_settings\" is required for clusters of type \"${lower(coalesce(each.value.type,"cluster_network"))}\"."
21+
}
22+
}
23+
#Required
24+
compartment_id = each.value.compartment_id != null ? (length(regexall("^ocid1.*$", each.value.compartment_id)) > 0 ? each.value.compartment_id : var.compartments_dependency[each.value.compartment_id].id) : (length(regexall("^ocid1.*$", var.clusters_configuration.default_compartment_id)) > 0 ? var.clusters_configuration.default_compartment_id : var.compartments_dependency[var.clusters_configuration.default_compartment_id].id)
25+
instance_pools {
26+
#Required
27+
instance_configuration_id = contains(keys(oci_core_instance_configuration.these),each.value.cluster_network_settings.instance_configuration_id) ? oci_core_instance_configuration.these[each.value.cluster_network_settings.instance_configuration_id].id : (length(regexall("^ocid1.*$", each.value.cluster_network_settings.instance_configuration_id)) > 0 ? each.value.cluster_network_settings.instance_configuration_id : null)
28+
size = each.value.cluster_network_settings.instance_pool != null ? coalesce(each.value.cluster_network_settings.instance_pool.size,1) : 1
29+
30+
#Optional
31+
display_name = each.value.cluster_network_settings.instance_pool != null ? each.value.cluster_network_settings.instance_pool.name : null
32+
defined_tags = each.value.defined_tags != null ? each.value.defined_tags : var.clusters_configuration.default_defined_tags
33+
freeform_tags = each.value.freeform_tags != null ? each.value.freeform_tags : var.clusters_configuration.default_freeform_tags
34+
}
35+
placement_configuration {
36+
#Required
37+
availability_domain = data.oci_identity_availability_domains.cluster_ads[each.key].availability_domains[coalesce(each.value.availability_domain,1) - 1].name
38+
primary_vnic_subnets {
39+
#Required
40+
subnet_id = length(regexall("^ocid1.*$", each.value.cluster_network_settings.networking.subnet_id)) > 0 ? each.value.cluster_network_settings.networking.subnet_id : var.network_dependency["subnets"][each.value.cluster_network_settings.networking.subnet_id].id
41+
is_assign_ipv6ip = coalesce(each.value.cluster_network_settings.networking.ipv6_enable,false)
42+
dynamic "ipv6address_ipv6subnet_cidr_pair_details" {
43+
for_each = coalesce(each.value.cluster_network_settings.networking.ipv6_enable,false) ? coalesce(each.value.cluster_network_settings.networking.ipv6_subnet_cidrs,[]) : []
44+
content {
45+
ipv6subnet_cidr = each.key
46+
}
47+
}
48+
}
49+
dynamic "secondary_vnic_subnets" {
50+
for_each = each.value.cluster_network_settings.networking.secondary_vnic_settings != null ? [1] : []
51+
content {
52+
subnet_id = length(regexall("^ocid1.*$", each.value.cluster_network_settings.networking.secondary_vnic_settings.subnet_id)) > 0 ? each.value.cluster_network_settings.networking.secondary_vnic_settings.subnet_id : var.network_dependency["subnets"][each.value.cluster_network_settings.networking.secondary_vnic_settings.subnet_id].id
53+
display_name = each.value.cluster_network_settings.networking.secondary_vnic_settings.name
54+
is_assign_ipv6ip = coalesce(each.value.cluster_network_settings.networking.secondary_vnic_settings.ipv6_enable,false)
55+
dynamic "ipv6address_ipv6subnet_cidr_pair_details" {
56+
for_each = coalesce(each.value.cluster_network_settings.networking.secondary_vnic_settings.ipv6_enable,false) ? coalesce(each.value.cluster_network_settings.networking.secondary_vnic_settings.ipv6_subnet_cidrs,[]) : []
57+
content {
58+
ipv6subnet_cidr = each.key
59+
}
60+
}
61+
}
62+
}
63+
}
64+
65+
#Optional
66+
# cluster_configuration {
67+
# #Required
68+
# hpc_island_id = oci_core_hpc_island.test_hpc_island.id
69+
70+
# #Optional
71+
# network_block_ids = var.cluster_network_cluster_configuration_network_block_ids
72+
# }
73+
74+
display_name = each.value.name
75+
defined_tags = each.value.defined_tags != null ? each.value.defined_tags : var.clusters_configuration.default_defined_tags
76+
freeform_tags = each.value.freeform_tags != null ? each.value.freeform_tags : var.clusters_configuration.default_freeform_tags
77+
}
78+
79+
resource "oci_core_compute_cluster" "these" {
80+
for_each = local.compute_clusters
81+
compartment_id = each.value.compartment_id != null ? (length(regexall("^ocid1.*$", each.value.compartment_id)) > 0 ? each.value.compartment_id : var.compartments_dependency[each.value.compartment_id].id) : (length(regexall("^ocid1.*$", var.clusters_configuration.default_compartment_id)) > 0 ? var.clusters_configuration.default_compartment_id : var.compartments_dependency[var.clusters_configuration.default_compartment_id].id)
82+
availability_domain = data.oci_identity_availability_domains.cluster_ads[each.key].availability_domains[coalesce(each.value.availability_domain, 1) - 1].name
83+
display_name = each.value.name
84+
defined_tags = each.value.defined_tags != null ? each.value.defined_tags : var.clusters_configuration.default_defined_tags
85+
freeform_tags = each.value.freeform_tags != null ? each.value.freeform_tags : var.clusters_configuration.default_freeform_tags
86+
}

cis-compute-storage/compute.tf

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,10 @@ resource "oci_core_instance" "these" {
170170
}
171171
}
172172
metadata = {
173-
ssh_authorized_keys = each.value.ssh_public_key_path != null ? file(each.value.ssh_public_key_path) : file(var.instances_configuration.default_ssh_public_key_path)
174-
# user_data = contains(keys(data.template_cloudinit_config.config),each.key) ? data.template_cloudinit_config.config[each.key].rendered : null
173+
ssh_authorized_keys = each.value.ssh_public_key_path != null ? (fileexists(each.value.ssh_public_key_path) ? file(each.value.ssh_public_key_path) : each.value.ssh_public_key_path) : var.instances_configuration.default_ssh_public_key_path != null ? (fileexists(var.instances_configuration.default_ssh_public_key_path) ? file(var.instances_configuration.default_ssh_public_key_path) : var.instances_configuration.default_ssh_public_key_path): null
174+
user_data = contains(keys(data.template_file.cloud_config),each.key) ? base64encode(data.template_file.cloud_config[each.key].rendered) : null
175175
}
176+
compute_cluster_id = each.value.cluster_id != null ? (contains(keys(oci_core_compute_cluster.these),each.value.cluster_id) ? oci_core_compute_cluster.these[each.value.cluster_id].id : (length(regexall("^ocid1.*$", each.value.cluster_id)) > 0 ? each.value.cluster_id : null)) : null
176177
}
177178

178179
resource "oci_core_volume_backup_policy_assignment" "these_boot_volumes" {
@@ -181,6 +182,11 @@ resource "oci_core_volume_backup_policy_assignment" "these_boot_volumes" {
181182
policy_id = local.oracle_backup_policies[lower(each.value.boot_volume != null ? each.value.boot_volume.backup_policy : "bronze")]
182183
}
183184

185+
data "template_file" "cloud_config" {
186+
for_each = var.instances_configuration != null ? {for k, v in var.instances_configuration["instances"] : k => v if v.cloud_init != null || var.instances_configuration.default_cloud_init_heredoc_script != null || var.instances_configuration.default_cloud_init_script_file != null} : {}
187+
template = coalesce(try(each.value.cloud_init.heredoc_script,null), try(file(try(each.value.cloud_init.script_file,null)),null), var.instances_configuration.default_cloud_init_heredoc_script, try(file(var.instances_configuration.default_cloud_init_script_file),null), "__void__")
188+
}
189+
184190
/* data "template_file" "block_volumes_templates" {
185191
for_each = var.instances_configuration != null ? {for k, v in var.instances_configuration["instances"] : k => v if v.device_mounting != null} : {}
186192
template = file("${path.module}/userdata/linux_mount.sh")
@@ -190,19 +196,7 @@ resource "oci_core_volume_backup_policy_assignment" "these_boot_volumes" {
190196
block_vol_att_type = each.value.device_mounting.emulation_type != null ? lower(each.value.device_mounting.emulation_type) : "paravirtualized"
191197
}
192198
}
193-
194-
data "template_cloudinit_config" "config" {
195-
for_each = var.instances_configuration != null ? {for k, v in var.instances_configuration["instances"] : k => v if v.device_mounting != null} : {}
196-
gzip = false
197-
base64_encode = true
198-
199-
# Main cloud-config configuration file.
200-
part {
201-
filename = "cloudinit.sh"
202-
content_type = "text/x-shellscript"
203-
content = data.template_file.block_volumes_templates[each.key].rendered
204-
}
205-
} */
199+
*/
206200

207201
data "oci_core_vnic_attachments" "these" {
208202
for_each = var.instances_configuration != null ? var.instances_configuration["instances"] : {}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# CIS Cluster Network Example
2+
3+
## Introduction
4+
This example shows how to deploy an RDMA cluster network in OCI using the [cis-compute-storage module](../../). It deploys one Compute instance, one cluster instance configuration, and one cluster network with the characteristics described below. Refer to [input.auto.tfvars.template](./input.auto.tfvars.template) for the variables configuration.
5+
6+
A [cluster network](https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/managingclusternetworks.htm) is a pool of high performance computing (HPC) instances that are connected with a high-bandwidth, ultra low-latency network. They're designed for highly demanding parallel computing jobs.
7+
8+
### Compute Instance
9+
- The deployed Compute instance is used as a template for the cluster instance configuration.
10+
- The Compute instance shape is "BM.Optimized3.36".
11+
- The Compute instance is created in the compartment and subnet specified by *default_compartment_id* and *default_subnet_id* attributes, respectively, within *instances_configuration* variable.
12+
13+
Note that you must provide the image *name* and *publisher_name* for provisioning the Compute instance. Use the [marketplace-images module](../../../marketplace-images/) to obtain Marketplace images information based on a search filter. It will also return the image OCID that can be used instead of the image name/publisher pair.
14+
15+
### Cluster Instance Configuration
16+
- A cluster instance configuration is created based on the Compute instance. This is indicated by *template_instance_id* attribute within *cluster_instances_configuration* variable.
17+
- The cluster instance configuration is created in the compartment specified by *default_compartment_id* attribute within *cluster_instances_configuration* variable.
18+
19+
### Cluster Instance Pool
20+
- A cluster instance pool is created based on the provided cluster instance configuration.
21+
22+
### RDMA Cluster Network
23+
- An RDMA cluster network with one cluster instance pool of size 1.
24+
- The cluster instance pool size is specified by *instance_pool size* attribute within *clusters_configuration* variable.
25+
- The cluster network is created in the compartment specified by *default_compartment_id* attribute within *clusters_configuration* variable.
26+
27+
## Using this example
28+
1. Rename *input.auto.tfvars.template* to *\<project-name\>.auto.tfvars*, where *\<project-name\>* is any name of your choice.
29+
30+
2. Within *\<project-name\>.auto.tfvars*, provide tenancy connectivity information and adjust the input variables, by making the appropriate substitutions:
31+
- Replace \<REPLACE-WITH-\*\> placeholders with appropriate values.
32+
33+
Refer to [cis-compute-storage module README.md](../../README.md) for overall attributes usage.
34+
35+
3. In this folder, run the typical Terraform workflow:
36+
```
37+
terraform init
38+
terraform plan -out plan.out
39+
terraform apply plan.out
40+
```
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Copyright (c) 2023 Oracle and/or its affiliates.
2+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
3+
4+
#--------------------------------------------------------------------------------------------------------------------------------------
5+
# 1. Rename this file to <project-name>.auto.tfvars, where <project-name> is a name of your choice.
6+
# 2. Provide values for "Tenancy Connectivity Variables".
7+
# 3. Replace <REPLACE-WITH-*> placeholders with appropriate values.
8+
#--------------------------------------------------------------------------------------------------------------------------------------
9+
10+
#---------------------------------------
11+
# Tenancy Connectivity Variables
12+
#---------------------------------------
13+
14+
tenancy_ocid = "<tenancy OCID>" # Get this from OCI Console (after logging in, go to top-right-most menu item and click option "Tenancy: <your tenancy name>").
15+
user_ocid = "<user OCID>" # Get this from OCI Console (after logging in, go to top-right-most menu item and click option "My profile").
16+
fingerprint = "<PEM key fingerprint>" # The fingerprint can be gathered from your user account. In the "My profile page, click "API keys" on the menu in left hand side.
17+
private_key_path = "<path to the private key>" # This is the full path on your local system to the API signing private key.
18+
private_key_password = "" # This is the password that protects the private key, if any.
19+
region = "<your tenancy region>" # The region name.
20+
21+
#---------------------------------------
22+
# Input variables
23+
#---------------------------------------
24+
25+
# This variable defines the RDMA clusters configuration.
26+
# The clusters attribute allows for the definition of an arbitrary number of clusters.
27+
clusters_configuration = {
28+
default_compartment_id = "<REPLACE-WITH-CLUSTER-COMPARTMENT-OCID>"
29+
clusters = {
30+
"CLUSTER-NETWORK" = {
31+
name = "basic-cluster-network"
32+
type = "cluster_network"
33+
availability_domain = 2
34+
cluster_network_settings = {
35+
instance_configuration_id = "INSTANCE-CONFIG"
36+
instance_pool = {
37+
size = 1
38+
}
39+
networking = {
40+
subnet_id = "<REPLACE-WITH-CLUSTER-SUBNET-OCID>"
41+
ipv6_enable = true
42+
}
43+
}
44+
}
45+
}
46+
}
47+
48+
# This variable defines the instances configuration that clusters are built on.
49+
# The configurations attribute allows for the definition of an arbitrary number of configurations.
50+
# Each configuration must provide a template_instance_id attribute, which value must be the key of a Compute instance within the instances_configuration variable above.
51+
cluster_instances_configuration = {
52+
default_compartment_id = "<REPLACE-WITH-CLUSTER-COMPARTMENT-OCID>"
53+
configurations = {
54+
INSTANCE-CONFIG = {
55+
name = "cluster-instance-configuration"
56+
template_instance_id = "CLUSTER-NETWORK-INSTANCE"
57+
}
58+
}
59+
}
60+
61+
# This variable defines the Compute instances used as templates for the cluster.
62+
# The instances attribute allows for the definition of an arbitrary number on Compute instances.
63+
# Cluster networks require that Compute instance shapes is one of: "BM.Optimized3.36", "BM.HPC2.36", "BM.GPU.A100-v2.8", "BM.GPU4.8"
64+
instances_configuration = {
65+
default_compartment_id = "<REPLACE-WITH-INSTANCE-COMPARTMENT-OCID>"
66+
default_subnet_id = "<REPLACE-WITH-INSTANCE-SUBNET-OCID>"
67+
default_ssh_public_key_path = "~/.ssh/id_rsa.pub"
68+
instances = {
69+
CLUSTER-NETWORK-INSTANCE = {
70+
shape = "BM.Optimized3.36"
71+
name = "BM.Optimized3.36 Template Instance"
72+
placement = {
73+
availability_domain = 2
74+
fault_domain = 2
75+
}
76+
boot_volume = {
77+
size = 120
78+
preserve_on_instance_deletion = false
79+
}
80+
networking = {
81+
hostname = "bm-optimized336-template-instance"
82+
network_security_groups = ["<REPLACE-WITH-INSTANCE-NSG-OCID>"]
83+
}
84+
image = {
85+
name = "Oracle Linux 7 STIG" # Marketplace image
86+
publisher_name = "Oracle Linux"
87+
}
88+
}
89+
}
90+
}

0 commit comments

Comments
 (0)