Skip to content

Commit

Permalink
Release 0.1.4 (#6)
Browse files Browse the repository at this point in the history
* 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 <andre.correa@oracle.com>
Co-authored-by: Ionut Sturzu <ionut.sturzu@oracle.com>
Co-authored-by: gfeodoro <gfeodoro@GFEODORO-RO.ro.oracle.com>
  • Loading branch information
3 people authored May 17, 2024
1 parent 594faa6 commit 48ad16f
Show file tree
Hide file tree
Showing 82 changed files with 3,944 additions and 763 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@
marketplace-images/**/*.txt
platform-images/**/*.txt
userdata
mounting-block-volumes.txt
mounting-block-volumes.txt
**/examples/clusters/*
**/creds
**/clean-setup
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This repository contains Terraform modules for managing workload resources in OC

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

Helper modules:
- [Platform Images](./platform-images/) - aids in finding OCI Platform images. Use it to obtain image information for provisioning a Compute instance.
Expand Down
10 changes: 10 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# May 15, 2024 Release Notes - 0.1.4

## New
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.

## Updates
1. Compute module can now manage cluster networks and compute clusters. See [Clusters](./cis-compute-storage/README.md#clusters-1) for details.
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.
3. Compute module now supports SSH public keys passed in as a file or as a string.

# February 29, 2024 Release Notes - 0.1.3

## Updates
Expand Down
115 changes: 109 additions & 6 deletions cis-compute-storage/README.md

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion cis-compute-storage/SPEC.md

Large diffs are not rendered by default.

455 changes: 455 additions & 0 deletions cis-compute-storage/cluster_instances_configuration.tf

Large diffs are not rendered by default.

86 changes: 86 additions & 0 deletions cis-compute-storage/clusters.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.

data "oci_identity_availability_domains" "cluster_ads" {
for_each = var.clusters_configuration != null ? (var.clusters_configuration.clusters != null ? var.clusters_configuration.clusters : {}) : {}
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)
}

locals {
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"}
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"}
}

resource "oci_core_cluster_network" "these" {
for_each = local.cluster_networks
lifecycle {
## Check 1: cluster_network_settings is required for clusters of type "cluster_network".
precondition {
condition = lower(coalesce(each.value.type,"cluster_network")) == "cluster_network" && each.value.cluster_network_settings == null ? false : true
error_message = "VALIDATION FAILURE in cluster \"${each.key}\": \"cluster_network_settings\" is required for clusters of type \"${lower(coalesce(each.value.type,"cluster_network"))}\"."
}
}
#Required
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)
instance_pools {
#Required
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)
size = each.value.cluster_network_settings.instance_pool != null ? coalesce(each.value.cluster_network_settings.instance_pool.size,1) : 1

#Optional
display_name = each.value.cluster_network_settings.instance_pool != null ? each.value.cluster_network_settings.instance_pool.name : null
defined_tags = each.value.defined_tags != null ? each.value.defined_tags : var.clusters_configuration.default_defined_tags
freeform_tags = each.value.freeform_tags != null ? each.value.freeform_tags : var.clusters_configuration.default_freeform_tags
}
placement_configuration {
#Required
availability_domain = data.oci_identity_availability_domains.cluster_ads[each.key].availability_domains[coalesce(each.value.availability_domain,1) - 1].name
primary_vnic_subnets {
#Required
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
is_assign_ipv6ip = coalesce(each.value.cluster_network_settings.networking.ipv6_enable,false)
dynamic "ipv6address_ipv6subnet_cidr_pair_details" {
for_each = coalesce(each.value.cluster_network_settings.networking.ipv6_enable,false) ? coalesce(each.value.cluster_network_settings.networking.ipv6_subnet_cidrs,[]) : []
content {
ipv6subnet_cidr = each.key
}
}
}
dynamic "secondary_vnic_subnets" {
for_each = each.value.cluster_network_settings.networking.secondary_vnic_settings != null ? [1] : []
content {
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
display_name = each.value.cluster_network_settings.networking.secondary_vnic_settings.name
is_assign_ipv6ip = coalesce(each.value.cluster_network_settings.networking.secondary_vnic_settings.ipv6_enable,false)
dynamic "ipv6address_ipv6subnet_cidr_pair_details" {
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,[]) : []
content {
ipv6subnet_cidr = each.key
}
}
}
}
}

#Optional
# cluster_configuration {
# #Required
# hpc_island_id = oci_core_hpc_island.test_hpc_island.id

# #Optional
# network_block_ids = var.cluster_network_cluster_configuration_network_block_ids
# }

display_name = each.value.name
defined_tags = each.value.defined_tags != null ? each.value.defined_tags : var.clusters_configuration.default_defined_tags
freeform_tags = each.value.freeform_tags != null ? each.value.freeform_tags : var.clusters_configuration.default_freeform_tags
}

resource "oci_core_compute_cluster" "these" {
for_each = local.compute_clusters
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)
availability_domain = data.oci_identity_availability_domains.cluster_ads[each.key].availability_domains[coalesce(each.value.availability_domain, 1) - 1].name
display_name = each.value.name
defined_tags = each.value.defined_tags != null ? each.value.defined_tags : var.clusters_configuration.default_defined_tags
freeform_tags = each.value.freeform_tags != null ? each.value.freeform_tags : var.clusters_configuration.default_freeform_tags
}
24 changes: 9 additions & 15 deletions cis-compute-storage/compute.tf
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,10 @@ resource "oci_core_instance" "these" {
}
}
metadata = {
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)
# user_data = contains(keys(data.template_cloudinit_config.config),each.key) ? data.template_cloudinit_config.config[each.key].rendered : null
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
user_data = contains(keys(data.template_file.cloud_config),each.key) ? base64encode(data.template_file.cloud_config[each.key].rendered) : null
}
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
}

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

data "template_file" "cloud_config" {
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} : {}
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__")
}

/* data "template_file" "block_volumes_templates" {
for_each = var.instances_configuration != null ? {for k, v in var.instances_configuration["instances"] : k => v if v.device_mounting != null} : {}
template = file("${path.module}/userdata/linux_mount.sh")
Expand All @@ -190,19 +196,7 @@ resource "oci_core_volume_backup_policy_assignment" "these_boot_volumes" {
block_vol_att_type = each.value.device_mounting.emulation_type != null ? lower(each.value.device_mounting.emulation_type) : "paravirtualized"
}
}
data "template_cloudinit_config" "config" {
for_each = var.instances_configuration != null ? {for k, v in var.instances_configuration["instances"] : k => v if v.device_mounting != null} : {}
gzip = false
base64_encode = true
# Main cloud-config configuration file.
part {
filename = "cloudinit.sh"
content_type = "text/x-shellscript"
content = data.template_file.block_volumes_templates[each.key].rendered
}
} */
*/

data "oci_core_vnic_attachments" "these" {
for_each = var.instances_configuration != null ? var.instances_configuration["instances"] : {}
Expand Down
40 changes: 40 additions & 0 deletions cis-compute-storage/examples/cluster-networks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# CIS Cluster Network Example

## Introduction
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.

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.

### Compute Instance
- The deployed Compute instance is used as a template for the cluster instance configuration.
- The Compute instance shape is "BM.Optimized3.36".
- 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.

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.

### Cluster Instance Configuration
- A cluster instance configuration is created based on the Compute instance. This is indicated by *template_instance_id* attribute within *cluster_instances_configuration* variable.
- The cluster instance configuration is created in the compartment specified by *default_compartment_id* attribute within *cluster_instances_configuration* variable.

### Cluster Instance Pool
- A cluster instance pool is created based on the provided cluster instance configuration.

### RDMA Cluster Network
- An RDMA cluster network with one cluster instance pool of size 1.
- The cluster instance pool size is specified by *instance_pool size* attribute within *clusters_configuration* variable.
- The cluster network is created in the compartment specified by *default_compartment_id* attribute within *clusters_configuration* variable.

## Using this example
1. Rename *input.auto.tfvars.template* to *\<project-name\>.auto.tfvars*, where *\<project-name\>* is any name of your choice.

2. Within *\<project-name\>.auto.tfvars*, provide tenancy connectivity information and adjust the input variables, by making the appropriate substitutions:
- Replace \<REPLACE-WITH-\*\> placeholders with appropriate values.

Refer to [cis-compute-storage module README.md](../../README.md) for overall attributes usage.

3. In this folder, run the typical Terraform workflow:
```
terraform init
terraform plan -out plan.out
terraform apply plan.out
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Copyright (c) 2023 Oracle and/or its affiliates.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.

#--------------------------------------------------------------------------------------------------------------------------------------
# 1. Rename this file to <project-name>.auto.tfvars, where <project-name> is a name of your choice.
# 2. Provide values for "Tenancy Connectivity Variables".
# 3. Replace <REPLACE-WITH-*> placeholders with appropriate values.
#--------------------------------------------------------------------------------------------------------------------------------------

#---------------------------------------
# Tenancy Connectivity Variables
#---------------------------------------

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>").
user_ocid = "<user OCID>" # Get this from OCI Console (after logging in, go to top-right-most menu item and click option "My profile").
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.
private_key_path = "<path to the private key>" # This is the full path on your local system to the API signing private key.
private_key_password = "" # This is the password that protects the private key, if any.
region = "<your tenancy region>" # The region name.

#---------------------------------------
# Input variables
#---------------------------------------

# This variable defines the RDMA clusters configuration.
# The clusters attribute allows for the definition of an arbitrary number of clusters.
clusters_configuration = {
default_compartment_id = "<REPLACE-WITH-CLUSTER-COMPARTMENT-OCID>"
clusters = {
"CLUSTER-NETWORK" = {
name = "basic-cluster-network"
type = "cluster_network"
availability_domain = 2
cluster_network_settings = {
instance_configuration_id = "INSTANCE-CONFIG"
instance_pool = {
size = 1
}
networking = {
subnet_id = "<REPLACE-WITH-CLUSTER-SUBNET-OCID>"
ipv6_enable = true
}
}
}
}
}

# This variable defines the instances configuration that clusters are built on.
# The configurations attribute allows for the definition of an arbitrary number of configurations.
# 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.
cluster_instances_configuration = {
default_compartment_id = "<REPLACE-WITH-CLUSTER-COMPARTMENT-OCID>"
configurations = {
INSTANCE-CONFIG = {
name = "cluster-instance-configuration"
template_instance_id = "CLUSTER-NETWORK-INSTANCE"
}
}
}

# This variable defines the Compute instances used as templates for the cluster.
# The instances attribute allows for the definition of an arbitrary number on Compute instances.
# Cluster networks require that Compute instance shapes is one of: "BM.Optimized3.36", "BM.HPC2.36", "BM.GPU.A100-v2.8", "BM.GPU4.8"
instances_configuration = {
default_compartment_id = "<REPLACE-WITH-INSTANCE-COMPARTMENT-OCID>"
default_subnet_id = "<REPLACE-WITH-INSTANCE-SUBNET-OCID>"
default_ssh_public_key_path = "~/.ssh/id_rsa.pub"
instances = {
CLUSTER-NETWORK-INSTANCE = {
shape = "BM.Optimized3.36"
name = "BM.Optimized3.36 Template Instance"
placement = {
availability_domain = 2
fault_domain = 2
}
boot_volume = {
size = 120
preserve_on_instance_deletion = false
}
networking = {
hostname = "bm-optimized336-template-instance"
network_security_groups = ["<REPLACE-WITH-INSTANCE-NSG-OCID>"]
}
image = {
name = "Oracle Linux 7 STIG" # Marketplace image
publisher_name = "Oracle Linux"
}
}
}
}
14 changes: 14 additions & 0 deletions cis-compute-storage/examples/cluster-networks/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

# Copyright (c) 2023 Oracle and/or its affiliates.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.

module "cluster_networks" {
source = "../.."
providers = {
oci = oci
oci.block_volumes_replication_region = oci
}
clusters_configuration = var.clusters_configuration
cluster_instances_configuration = var.cluster_instances_configuration
instances_configuration = var.instances_configuration
}
19 changes: 19 additions & 0 deletions cis-compute-storage/examples/cluster-networks/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (c) 2023 Oracle and/or its affiliates.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.

provider "oci" {
region = var.region
tenancy_ocid = var.tenancy_ocid
user_ocid = var.user_ocid
fingerprint = var.fingerprint
private_key_path = var.private_key_path
private_key_password = var.private_key_password
}

terraform {
required_providers {
oci = {
source = "oracle/oci"
}
}
}
Loading

0 comments on commit 48ad16f

Please sign in to comment.