Skip to content

Commit

Permalink
Add Container Instance Terraform module (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
ctxch committed Oct 30, 2023
1 parent 8630e7e commit 5612032
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 111 deletions.
13 changes: 3 additions & 10 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ crash.log
crash.*.log

# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json
Expand All @@ -32,11 +32,4 @@ override.tf.json
# Ignore CLI configuration files
.terraformrc
terraform.rc
/.idea/.gitignore
/acf_resource_container_instance.iml
/.idea/checkstyle-idea.xml
/.idea/google-java-format.xml
/.idea/jpa-buddy.xml
/.idea/misc.xml
/.idea/modules.xml
/.idea/vcs.xml
.idea/
42 changes: 20 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,21 @@
# Terraform OCI Container Instance
[![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?zipUrl=https://github.com/avaloqcloud/terraform-oci-container-instance/archive/refs/tags/v0.1.0.zip)

The code provides a reusuable Terraform module that provisions
simple container instance on Oracle Cloud Infrastructure.

## Usage
module "container_instance" {
source = "../terraform-oci-container-instance"

compartment_ocid = var.compartment_ocid
subnet_id = var.subnet_id
container_instance = var.container_instance
image_pull_secrets = var.image_pull_secrets
}
## Terraform OCI Container Instance
The code provides a reusable Terraform module that provisions a container instance on Oracle Cloud Infrastructure.

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0.0 |
| <a name="requirement_oci"></a> [oci](#requirement\_oci) | >= 4.101.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.2 |
| <a name="requirement_oci"></a> [oci](#requirement\_oci) | 5.18.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_oci"></a> [oci](#provider\_oci) | >= 4.101.0 |
| <a name="provider_oci"></a> [oci](#provider\_oci) | 5.18.0 |

## Modules

Expand All @@ -34,18 +25,25 @@ No modules.

| Name | Type |
|------|------|
| [oci_container_instances_container_instance.container_instance](https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/container_instances_container_instance) | resource |
| [oci_identity_availability_domains.local_ads](https://registry.terraform.io/providers/oracle/oci/latest/docs/data-sources/identity_availability_domains) | data source |
| [oci_container_instances_container_instance.container_instance](https://registry.terraform.io/providers/oracle/oci/5.18.0/docs/resources/container_instances_container_instance) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_compartment_ocid"></a> [compartment\_ocid](#input\_compartment\_ocid) | n/a | `string` | `null` | no |
| <a name="input_container_instance"></a> [container\_instance](#input\_container\_instance) | n/a | `any` | n/a | yes |
| <a name="input_image_pull_secrets"></a> [image\_pull\_secrets](#input\_image\_pull\_secrets) | n/a | `map(any)` | `null` | no |
| <a name="input_subnet_id"></a> [subnet\_id](#input\_subnet\_id) | n/a | `string` | `null` | no |
| <a name="input_availability_domain"></a> [availability\_domain](#input\_availability\_domain) | The availability domain where the container instance runs. | `string` | n/a | yes |
| <a name="input_compartment_ocid"></a> [compartment\_ocid](#input\_compartment\_ocid) | The OCID of the compartment. | `string` | n/a | yes |
| <a name="input_container_restart_policy"></a> [container\_restart\_policy](#input\_container\_restart\_policy) | The container restart policy is applied for all containers in container instance. | `string` | `"ALWAYS"` | no |
| <a name="input_containers"></a> [containers](#input\_containers) | The containers to create on this container instance. | <pre>list(object({<br> display_name = string<br> image_url = string<br> environment_variables = optional(map(string))<br><br> command = optional(list(string))<br> arguments = optional(list(string))<br><br> volume_mounts = optional(list(object({<br> volume_name = string<br> mount_path = string<br> })))<br><br> resource_config = optional(map(object({<br> memory_limit_in_gbs = optional(number)<br> vcpus_limit = optional(number)<br> })))<br><br> memory_limit_in_gbs = optional(number)<br> vcpus_limit = optional(number)<br><br> working_directory = optional(string)<br> }))</pre> | n/a | yes |
| <a name="input_display_name"></a> [display\_name](#input\_display\_name) | A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. If you don't provide a name, a name is generated automatically. | `string` | n/a | yes |
| <a name="input_image_pull_secrets"></a> [image\_pull\_secrets](#input\_image\_pull\_secrets) | The image pulls secrets so you can access private registry to pull container images. | <pre>list(map(object({<br> registry_endpoint = string<br> secret_type = string<br> secret_id = optional(string)<br> username = optional(string)<br> password = optional(string)<br> })))</pre> | `[]` | no |
| <a name="input_memory_in_gbs"></a> [memory\_in\_gbs](#input\_memory\_in\_gbs) | The total amount of memory available to the container instance, in gigabytes. | `number` | n/a | yes |
| <a name="input_ocpus"></a> [ocpus](#input\_ocpus) | The total number of OCPUs available to the container instance. | `number` | n/a | yes |
| <a name="input_shape"></a> [shape](#input\_shape) | The shape of the container instance. The shape determines the resources available to the container instance. | `string` | n/a | yes |
| <a name="input_subnet_id"></a> [subnet\_id](#input\_subnet\_id) | The OCID of the subnet to create the VNIC in. | `string` | n/a | yes |
| <a name="input_volumes"></a> [volumes](#input\_volumes) | A volume is a directory with data that is accessible across multiple containers in a container instance. | <pre>list(object({<br> name = string<br> volume_type = string<br> backing_store = optional(string)<br><br> configs = optional(list(object({<br> data = optional(string)<br> file_name = optional(string)<br> })))<br> }))</pre> | `[]` | no |

## Outputs

No outputs.
<!-- END_TF_DOCS -->
122 changes: 57 additions & 65 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,82 +1,74 @@
data "oci_identity_availability_domains" "local_ads" {
compartment_id = var.compartment_ocid
}


resource "oci_container_instances_container_instance" "container_instance" {
count = length(var.container_instance)

availability_domain = data.oci_identity_availability_domains.local_ads.availability_domains.0.name
compartment_id = var.compartment_ocid

display_name = var.container_instance[count.index]["container_name"]
container_restart_policy = "ALWAYS"
shape = var.container_instance[count.index]["shape"]
shape_config {
memory_in_gbs = var.container_instance[count.index]["mem"]
ocpus = var.container_instance[count.index]["cpu"]
}
availability_domain = var.availability_domain
compartment_id = var.compartment_ocid

vnics {
subnet_id = var.subnet_id
is_public_ip_assigned = false
}
display_name = var.display_name
container_restart_policy = var.container_restart_policy
shape = var.shape
shape_config {
memory_in_gbs = var.memory_in_gbs
ocpus = var.ocpus
}

containers {
image_url = var.container_instance[count.index]["container_image_url"]
display_name = var.container_instance[count.index]["container_name"]
vnics {
subnet_id = var.subnet_id
is_public_ip_assigned = false
hostname_label = var.display_name
}

environment_variables = var.container_instance[count.index]["env_variables"]
dynamic "containers" {
for_each = var.containers
content {
display_name = containers.value.display_name
image_url = containers.value.image_url
environment_variables = try(containers.value.environment_variables, null)

command = try(var.container_instance[count.index]["command"], null)
arguments = try(var.container_instance[count.index]["arguments"], null)
command = try(containers.value.command, null)
arguments = try(containers.value.arguments, null)

dynamic "volume_mounts" {
for_each = try(var.container_instance[count.index]["volumes"], {})
content {
volume_name = volume_mounts.key
mount_path = volume_mounts.value.path
}
}
dynamic "volume_mounts" {
for_each = containers.value.volume_mounts == null ? [] : containers.value.volume_mounts
content {
volume_name = volume_mounts.value.volume_name
mount_path = volume_mounts.value.mount_path
}
}

resource_config {
memory_limit_in_gbs = try(var.container_instance[count.index]["memory_limit"], null)
}

security_context {
run_as_group = try(var.container_instance[count.index]["run_as_group"], null)
run_as_user = try(var.container_instance[count.index]["run_as_user"], null)
security_context_type = "LINUX"
resource_config {
memory_limit_in_gbs = try(containers.value.memory_limit_in_gbs, null)
vcpus_limit = try(containers.value.vcpus_limit, null)
}

working_directory = try(containers.value.working_directory, null)
}
}

working_directory = try(var.container_instance[count.index]["working_directory"], null)
}

dynamic "image_pull_secrets" {
for_each = try(var.image_pull_secrets, {})
content {
registry_endpoint = image_pull_secrets.value.registry_endpoint
secret_type = image_pull_secrets.value.secret_type
dynamic "volumes" {
for_each = var.volumes
content {
name = volumes.value.name
volume_type = volumes.value.volume_type

secret_id = try(image_pull_secrets.value.secret_id, null)
username = base64encode(try(image_pull_secrets.value.username, null))
password = base64encode(try(image_pull_secrets.value.password, null))
dynamic "configs" {
for_each = try(volumes.value.configs, [])
content {
data = configs.value.data
file_name = configs.value.file_name
}
}
}
}
}

dynamic "volumes" {
for_each = try(var.container_instance[count.index]["volumes"], {})
content {
name = volumes.key
volume_type = volumes.value.volume_type
backing_store = try(volumes.value.backing_store, null)
dynamic "configs" {
for_each = try(volumes.value.configs, {})
dynamic "image_pull_secrets" {
for_each = var.image_pull_secrets
content {
data = try(configs.value, null)
file_name = try(configs.key, null)
registry_endpoint = image_pull_secrets.value.registry_endpoint
secret_type = image_pull_secrets.value.secret_type

secret_id = try(image_pull_secrets.value.secret_id, null)
username = base64encode(try(image_pull_secrets.value.username, null))
password = base64encode(try(image_pull_secrets.value.password, null))
}
}
}
}
}
14 changes: 7 additions & 7 deletions providers.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.0.0"
required_providers {
oci = {
source = "oracle/oci"
version = ">= 4.101.0"
experiments = [module_variable_optional_attrs]
required_version = "~> 1.2"
required_providers {
oci = {
source = "oracle/oci"
version = "5.18.0"
}
}
}
}

81 changes: 81 additions & 0 deletions schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
title: "Container Instance Creation"
description: "Container Instance Creation on OCI"
outputGroups:
- title: "Container Instance"
schemaVersion: 1.1.0
locale: "en"
variableGroups:
- title: "OCI (Oracle Cloud Infrastructure) details"
variables:
- compartment_ocid
- availability_domain
- subnet_id

- title: "Container Instance configuration details"
variables:
- display_name
- shape
- container_restart_policy
- memory_in_gbs
- ocpus
- containers
- volumes
- image_pull_secrets

variables:
compartment_ocid:
type: string
required: true
description: "The OCID of the compartment."
title: "Compartment OCID"
availability_domain:
type: string
required: true
visible: complexExpression
subnet_id:
type: string
title: "Subnet ID"
description: "The OCID of the subnet to create the VNIC in."
required: true
display_name:
type: string
pattern: "^[a-z-]+$"
title: "Display Name"
description: "A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. If you don't provide a name, a name is generated automatically."
required: true
shape:
type: string
title: "Shape"
description: "The shape of the container instance. The shape determines the resources available to the container instance."
required: true
container_restart_policy:
type: string
pattern: "^(ALWAYS|NEVER|ON_FAILURE)$"
title: "Container Restart Policy"
description: "The container restart policy is applied for all containers in container instance."
required: true
memory_in_gbs:
type: number
title: "Memory in GBs"
description: "The total amount of memory available to the container instance, in gigabytes."
required: true
ocpus:
type: number
title: "OCPUs"
description: "The total number of OCPUs available to the container instance."
required: true
containers:
type: list(map)
title: "Containers"
description: "The containers to create on this container instance."
required: true
volumes:
type: list(map)
title: "Volumes"
description: "A volume is a directory with data that is accessible across multiple containers in a container instance."
required: false
image_pull_secrets:
type: list(map)
title: "Image Pull Secrets"
description: "The image pulls secrets so you can access private registry to pull container images."
required: false
Loading

0 comments on commit 5612032

Please sign in to comment.