Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ This module provisions the IBM Cloud Code Engine fully managed and serverless pl
* [secret](./modules/secret)
* [Examples](./examples)
* [Apps example](./examples/apps)
* [Build example](./examples/build)
* [Jobs example](./examples/jobs)
* [Contributing](#contributing)
<!-- END OVERVIEW HOOK -->
Expand Down Expand Up @@ -157,7 +158,7 @@ No resources.
|------|-------------|------|---------|:--------:|
| <a name="input_apps"></a> [apps](#input\_apps) | A map of code engine apps to be created. | <pre>map(object({<br/> image_reference = string<br/> image_secret = optional(string)<br/> run_env_variables = optional(list(object({<br/> type = optional(string)<br/> name = optional(string)<br/> value = optional(string)<br/> prefix = optional(string)<br/> key = optional(string)<br/> reference = optional(string)<br/> })))<br/> run_volume_mounts = optional(list(object({<br/> mount_path = string<br/> reference = string<br/> name = optional(string)<br/> type = string<br/> })))<br/> image_port = optional(number)<br/> managed_domain_mappings = optional(string)<br/> run_arguments = optional(list(string))<br/> run_as_user = optional(number)<br/> run_commands = optional(list(string))<br/> run_service_account = optional(string)<br/> scale_concurrency = optional(number)<br/> scale_concurrency_target = optional(number)<br/> scale_cpu_limit = optional(string)<br/> scale_ephemeral_storage_limit = optional(string)<br/> scale_initial_instances = optional(number)<br/> scale_max_instances = optional(number)<br/> scale_memory_limit = optional(string)<br/> scale_min_instances = optional(number)<br/> scale_request_timeout = optional(number)<br/> scale_down_delay = optional(number)<br/> }))</pre> | `{}` | no |
| <a name="input_bindings"></a> [bindings](#input\_bindings) | A map of code engine bindings to be created. | <pre>map(object({<br/> secret_name = string<br/> components = list(object({<br/> name = string<br/> resource_type = string<br/> }))<br/> }))</pre> | `{}` | no |
| <a name="input_builds"></a> [builds](#input\_builds) | A map of code engine builds to be created. Requires 'ibmcloud\_api\_key' to be set for authentication and execution. | <pre>map(object({<br/> output_image = string<br/> output_secret = string # pragma: allowlist secret<br/> source_url = string<br/> strategy_type = string<br/> source_context_dir = optional(string)<br/> source_revision = optional(string)<br/> source_secret = optional(string)<br/> source_type = optional(string)<br/> strategy_size = optional(string)<br/> strategy_spec_file = optional(string)<br/> timeout = optional(number)<br/> }))</pre> | `{}` | no |
| <a name="input_builds"></a> [builds](#input\_builds) | A map of code engine builds to be created. Requires 'ibmcloud\_api\_key' to be set for authentication and execution. | <pre>map(object({<br/> output_image = optional(string)<br/> output_secret = optional(string) # pragma: allowlist secret<br/> source_url = string<br/> strategy_type = optional(string)<br/> source_context_dir = optional(string)<br/> source_revision = optional(string)<br/> source_secret = optional(string)<br/> source_type = optional(string)<br/> strategy_size = optional(string)<br/> strategy_spec_file = optional(string)<br/> timeout = optional(number)<br/> region = optional(string)<br/> container_registry_namespace = optional(string)<br/> prefix = optional(string)<br/> }))</pre> | `{}` | no |
| <a name="input_cbr_rules"></a> [cbr\_rules](#input\_cbr\_rules) | The context-based restrictions rule to create. Only one rule is allowed. | <pre>list(object({<br/> description = string<br/> account_id = string<br/> rule_contexts = list(object({<br/> attributes = optional(list(object({<br/> name = string<br/> value = string<br/> }))) }))<br/> enforcement_mode = string<br/> operations = optional(list(object({<br/> api_types = list(object({<br/> api_type_id = string<br/> }))<br/> })))<br/> }))</pre> | `[]` | no |
| <a name="input_config_maps"></a> [config\_maps](#input\_config\_maps) | A map of code engine config maps to be created. | <pre>map(object({<br/> data = map(string)<br/> }))</pre> | `{}` | no |
| <a name="input_domain_mappings"></a> [domain\_mappings](#input\_domain\_mappings) | A map of code engine domain mappings to be created. | <pre>map(object({<br/> tls_secret = string # pragma: allowlist secret<br/> components = list(object({<br/> name = string<br/> resource_type = string<br/> }))<br/> }))</pre> | `{}` | no |
Expand Down
8 changes: 8 additions & 0 deletions examples/build/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Build example

An end-to-end apps example that will provision the following:
- A new resource group if one is not passed in.
- Code Engine project
- Code Engine build
- Code Engine registry secret
- Container registry namespace
30 changes: 30 additions & 0 deletions examples/build/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
########################################################################################################################
# Resource group
########################################################################################################################

module "resource_group" {
source = "terraform-ibm-modules/resource-group/ibm"
version = "1.3.0"
# if an existing resource group is not set (null) create a new one using prefix
resource_group_name = var.resource_group == null ? "${var.prefix}-resource-group" : null
existing_resource_group_name = var.resource_group
}

########################################################################################################################
# Code Engine instance
########################################################################################################################

module "code_engine" {
source = "../.."
ibmcloud_api_key = var.ibmcloud_api_key
resource_group_id = module.resource_group.resource_group_id
project_name = "${var.prefix}-project"
builds = {
"${var.prefix}-build1" = {
source_url = "https://github.com/IBM/CodeEngine"
container_registry_namespace = "cr-ce"
prefix = var.prefix
region = var.region
}
}
}
24 changes: 24 additions & 0 deletions examples/build/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
########################################################################################################################
# Outputs
########################################################################################################################

output "resource_group_id" {
description = "The id of created resource group."
value = module.resource_group.resource_group_id
}

output "resource_group_name" {
description = "The name of created resource group."
value = module.resource_group.resource_group_name
}

output "project_id" {
description = "ID of the created code engine project."
value = module.code_engine.project_id
}

output "build" {
description = "Configuration of the created code engine domain mapping."
value = module.code_engine.build
sensitive = true
}
8 changes: 8 additions & 0 deletions examples/build/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
########################################################################################################################
# Provider config
########################################################################################################################

provider "ibm" {
ibmcloud_api_key = var.ibmcloud_api_key
region = var.region
}
27 changes: 27 additions & 0 deletions examples/build/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
########################################################################################################################
# Input variables
########################################################################################################################

variable "ibmcloud_api_key" {
type = string
description = "The IBM Cloud API Key"
sensitive = true
}

variable "region" {
type = string
description = "Region to provision all resources created by this example"
default = "us-south"
}

variable "prefix" {
type = string
description = "Prefix to append to all resources created by this example"
default = "ce-build"
}

variable "resource_group" {
type = string
description = "The name of an existing resource group to provision resources in to. If not set a new resource group will be created using the prefix variable"
default = null
}
12 changes: 12 additions & 0 deletions examples/build/version.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

terraform {
required_version = ">= 1.9.0"
# Ensure that there is always 1 example locked into the lowest provider version of the range defined in the main
# module's version.tf (this example), and 1 example that will always use the latest provider version (jobs examples).
required_providers {
ibm = {
source = "IBM-Cloud/ibm"
version = ">= 1.79.0, < 2.0.0"
}
}
}
39 changes: 21 additions & 18 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,27 @@ module "secret" {
# Code Engine Build
##############################################################################
module "build" {
depends_on = [module.secret]
source = "./modules/build"
for_each = var.builds
ibmcloud_api_key = var.ibmcloud_api_key
existing_resource_group_id = var.resource_group_id
project_id = local.project_id
name = each.key
output_image = each.value.output_image
output_secret = each.value.output_secret
source_url = each.value.source_url
strategy_type = each.value.strategy_type
source_context_dir = each.value.source_context_dir
source_revision = each.value.source_revision
source_secret = each.value.source_secret
source_type = each.value.source_type
strategy_size = each.value.strategy_size
strategy_spec_file = each.value.strategy_spec_file
timeout = each.value.timeout
depends_on = [module.secret]
source = "./modules/build"
for_each = var.builds
ibmcloud_api_key = var.ibmcloud_api_key
existing_resource_group_id = var.resource_group_id
project_id = local.project_id
name = each.key
output_image = each.value.output_image
output_secret = each.value.output_secret
source_url = each.value.source_url
strategy_type = each.value.strategy_type
source_context_dir = each.value.source_context_dir
source_revision = each.value.source_revision
source_secret = each.value.source_secret
source_type = each.value.source_type
strategy_size = each.value.strategy_size
strategy_spec_file = each.value.strategy_spec_file
timeout = each.value.timeout
region = each.value.region
container_registry_namespace = each.value.container_registry_namespace
prefix = each.value.prefix
}

##############################################################################
Expand Down
19 changes: 13 additions & 6 deletions modules/build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ You need the following permissions to run this module.

### Modules

No modules.
| Name | Source | Version |
|------|--------|---------|
| <a name="module_cr_endpoint"></a> [cr\_endpoint](#module\_cr\_endpoint) | terraform-ibm-modules/container-registry/ibm//modules/endpoint | 2.1.0 |
| <a name="module_cr_namespace"></a> [cr\_namespace](#module\_cr\_namespace) | terraform-ibm-modules/container-registry/ibm | 2.1.0 |
| <a name="module_secret"></a> [secret](#module\_secret) | ../../modules/secret | n/a |

### Resources

Expand All @@ -54,21 +58,24 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_container_registry_api_key"></a> [container\_registry\_api\_key](#input\_container\_registry\_api\_key) | The API key for the container registry in the target account. This is only used if 'output\_secret' is not set and a new registry secret needs to be created. If not provided, the IBM Cloud API key (ibmcloud\_api\_key) will be used instead. | `string` | `null` | no |
| <a name="input_container_registry_namespace"></a> [container\_registry\_namespace](#input\_container\_registry\_namespace) | The name of the namespace to create in IBM Cloud Container Registry for organizing container images. Must be set if 'output\_image' is not set. | `string` | `null` | no |
| <a name="input_existing_resource_group_id"></a> [existing\_resource\_group\_id](#input\_existing\_resource\_group\_id) | The ID of an existing resource group where build will be provisioned. This must be the same resource group in which the code engine project was created. | `string` | n/a | yes |
| <a name="input_ibmcloud_api_key"></a> [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud API key. | `string` | n/a | yes |
| <a name="input_name"></a> [name](#input\_name) | The name of the build. | `string` | n/a | yes |
| <a name="input_output_image"></a> [output\_image](#input\_output\_image) | The name of the image. | `string` | n/a | yes |
| <a name="input_output_secret"></a> [output\_secret](#input\_output\_secret) | The secret that is required to access the image registry. | `string` | n/a | yes |
| <a name="input_output_image"></a> [output\_image](#input\_output\_image) | A container image can be identified by a container image reference with the following structure: registry / namespace / repository:tag. [Learn more](https://cloud.ibm.com/docs/codeengine?topic=codeengine-getting-started).<br/><br/>If not provided, the value will be derived from the 'container\_registry\_namespace' input variable, which must not be null in that case. | `string` | `null` | no |
| <a name="input_output_secret"></a> [output\_secret](#input\_output\_secret) | The secret that is required to access the IBM Cloud Container Registry. Make sure that the secret is granted with push permissions towards the specified container registry namespace. If not provided, it will be created using the value of 'container\_registry\_api\_key'; if that is not set, 'ibmcloud\_api\_key' will be used instead. | `string` | `null` | no |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | Prefix appended to the container registry namespace and registry secret if created. | `string` | `null` | no |
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | The ID of the project where build will be created. | `string` | n/a | yes |
| <a name="input_region"></a> [region](#input\_region) | The region in which to provision the build. This must be the same region in which the code engine project was created. | `string` | `"us-south"` | no |
| <a name="input_source_context_dir"></a> [source\_context\_dir](#input\_source\_context\_dir) | The directory in the repository that contains the buildpacks file or the Dockerfile. | `string` | `null` | no |
| <a name="input_source_revision"></a> [source\_revision](#input\_source\_revision) | Commit, tag, or branch in the source repository to pull. | `string` | `null` | no |
| <a name="input_source_secret"></a> [source\_secret](#input\_source\_secret) | The name of the secret that is used access the repository source. If the var.source\_type value is `local`, this field must be omitted. | `string` | `null` | no |
| <a name="input_source_type"></a> [source\_type](#input\_source\_type) | Specifies the type of source to determine if your build source is in a repository or based on local source code. | `string` | `null` | no |
| <a name="input_source_secret"></a> [source\_secret](#input\_source\_secret) | The name of the secret that is used access the repository source. If the var.source\_type value is `local`, this input must be omitted. | `string` | `null` | no |
| <a name="input_source_type"></a> [source\_type](#input\_source\_type) | Specifies the type of source to determine if your build source is in a repository or based on local source code. If the value is `local`, then 'source\_secret' input must be omitted. | `string` | `null` | no |
| <a name="input_source_url"></a> [source\_url](#input\_source\_url) | The URL of the code repository. | `string` | n/a | yes |
| <a name="input_strategy_size"></a> [strategy\_size](#input\_strategy\_size) | The size for the build, which determines the amount of resources used. | `string` | `null` | no |
| <a name="input_strategy_spec_file"></a> [strategy\_spec\_file](#input\_strategy\_spec\_file) | The path to the specification file that is used for build strategies for building an image. | `string` | `null` | no |
| <a name="input_strategy_type"></a> [strategy\_type](#input\_strategy\_type) | The strategy to use for building the image. | `string` | n/a | yes |
| <a name="input_strategy_type"></a> [strategy\_type](#input\_strategy\_type) | The strategy to use for building the image. | `string` | `"dockerfile"` | no |
| <a name="input_timeout"></a> [timeout](#input\_timeout) | The maximum amount of time, in seconds, that can pass before the build must succeed or fail. | `number` | `600` | no |

### Outputs
Expand Down
51 changes: 49 additions & 2 deletions modules/build/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
# Create Code Engine build
##############################################################################

locals {
prefix = var.prefix != null ? (trimspace(var.prefix) != "" ? "${var.prefix}-" : "") : ""
}

resource "ibm_code_engine_build" "ce_build" {
project_id = var.project_id
name = var.name
output_image = var.output_image
output_secret = var.output_secret
output_image = local.output_image
output_secret = var.output_secret != null ? var.output_secret : module.secret[0].name
source_url = var.source_url
source_context_dir = var.source_context_dir
source_revision = var.source_revision
Expand Down Expand Up @@ -39,3 +43,46 @@ resource "terraform_data" "run_build" {
}
}
}


##############################################################################
# Container Registry
##############################################################################

locals {
create_cr_namespace = var.output_image == null && var.container_registry_namespace != null ? true : false
image_container = local.create_cr_namespace ? "${module.cr_endpoint[0].container_registry_endpoint_private}/${module.cr_namespace[0].namespace_name}" : null
output_image = local.create_cr_namespace ? "${local.image_container}/${var.name}" : var.output_image
}

module "cr_namespace" {
count = local.create_cr_namespace ? 1 : 0
source = "terraform-ibm-modules/container-registry/ibm"
version = "2.1.0"
namespace_name = "${local.prefix}${var.container_registry_namespace}"
resource_group_id = var.existing_resource_group_id
}

module "cr_endpoint" {
count = local.create_cr_namespace ? 1 : 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the count cause an issue an existing namespace is passed?

It seems there should be no count and the module should always be created. The value is used when creating a code engine secret to access the container registry, which is unrelated to namespace creation.

Additional comment included where this is used.

source = "terraform-ibm-modules/container-registry/ibm//modules/endpoint"
version = "2.1.0"
region = var.region
}

##############################################################################
# Code Engine Secret
##############################################################################

module "secret" {
count = var.output_secret == null ? 1 : 0
source = "../../modules/secret"
project_id = var.project_id
name = "${local.prefix}registry-access-secret"
data = {
password = var.container_registry_api_key != null ? var.container_registry_api_key : var.ibmcloud_api_key,
username = "iamapikey",
server = module.cr_endpoint[0].container_registry_endpoint_private
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value of server may be undefined.

When local.create_name_space is false module.cr_endpoint does not exist. See comment on module definition.

}
format = "registry"
}
Loading