Skip to content
Merged
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
30 changes: 30 additions & 0 deletions .github/workflows/generate_terraform_docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

name: Update Terraform documentation

# Keep the `paths` filters below and the `terraform-directory` input in sync with
# the directories where the Terraform modules live.
on:
pull_request:
paths:
- "terraform/**"
- ".github/workflows/generate_terraform_docs.yaml"
push:
branches:
- main
paths:
- "terraform/**"
- ".github/workflows/generate_terraform_docs.yaml"

permissions:
contents: write
pull-requests: write

jobs:
terraform-docs:
name: Update Terraform documentation
uses: canonical/operator-workflows/.github/workflows/generate_terraform_docs.yaml@030c5b20a0bb880dcf1ed326bff0fc16b6eb6ac1 # main
secrets: inherit
with:
terraform-directory: terraform/charm/cloudflared,terraform/charm/cloudflare_configurator
17 changes: 17 additions & 0 deletions .github/workflows/terraform_modules_compliance.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

name: Terraform modules compliance

on:
workflow_dispatch:
pull_request:
paths:
- "**/terraform/**"
- ".github/workflows/terraform_modules_compliance.yaml"

jobs:
terraform-compliance:
uses: canonical/operator-workflows/.github/workflows/terraform_modules_compliance.yaml@030c5b20a0bb880dcf1ed326bff0fc16b6eb6ac1 # main
with:
terraform-directories: '["terraform/charm/cloudflared", "terraform/charm/cloudflare_configurator"]'
33 changes: 33 additions & 0 deletions .github/workflows/terraform_modules_release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

name: Terraform modules release

on:
workflow_dispatch:
pull_request:
paths:
- "terraform/**"
- ".github/workflows/terraform_modules_release.yaml"
push:
branches:
- main
paths:
- "terraform/**"
- ".github/workflows/terraform_modules_release.yaml"

jobs:
cloudflared-terraform:
uses: canonical/operator-workflows/.github/workflows/terraform_modules_release.yaml@030c5b20a0bb880dcf1ed326bff0fc16b6eb6ac1 # main
permissions:
contents: write
with:
tag-prefix: cloudflared-tf-
major-version-file: terraform/charm/cloudflared/MAJOR_VERSION
cloudflare-configurator-terraform:
uses: canonical/operator-workflows/.github/workflows/terraform_modules_release.yaml@030c5b20a0bb880dcf1ed326bff0fc16b6eb6ac1 # main
permissions:
contents: write
with:
tag-prefix: cloudflare-configurator-tf-
major-version-file: terraform/charm/cloudflare_configurator/MAJOR_VERSION
18 changes: 8 additions & 10 deletions .github/workflows/test_terraform_modules.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2025 Canonical Ltd.
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

name: Terraform modules tests
Expand All @@ -7,16 +7,14 @@ on:
workflow_dispatch:
pull_request:
paths:
- 'terraform/**'
- 'terraform-product/**'
- "**/terraform/**"
- ".github/workflows/test_terraform_modules.yaml"

jobs:
terraform-tests:
uses: canonical/operator-workflows/.github/workflows/terraform_modules_test.yaml@main
permissions:
contents: read
terraform-tests-lxd:
uses: canonical/operator-workflows/.github/workflows/terraform_modules_test.yaml@030c5b20a0bb880dcf1ed326bff0fc16b6eb6ac1 # main
secrets: inherit
with:
k8s-controller: true
#lxd-controller: true
terraform-directories: '["terraform"]'
k8s-controller: false
lxd-controller: true
terraform-directories: '["terraform/charm/cloudflared", "terraform/charm/cloudflare_configurator"]'
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ __pycache__/
terraform/**/.terraform*
terraform/**/.tfvars
terraform/**/*.tfstate*
**/.terraform/
**/.terraform.lock.hcl
# opcli/spread generated files
.spread-reuse.*
.spread-run-*/
Expand Down
1 change: 1 addition & 0 deletions .licenserc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ header:
- 'docs/release-notes/template/*.yaml'
- 'uv.lock'
- '**/uv.lock'
- '**/MAJOR_VERSION'
comment: on-failure
20 changes: 20 additions & 0 deletions docs/release-notes/artifacts/pr0030.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

version_schema: 2
Comment thread
weiiwang01 marked this conversation as resolved.

changes:
- title: Added CC008-compliant Terraform modules
author: weiiwang01
type: minor
description: >
Added Terraform modules for the cloudflared and cloudflare-configurator
charms following the CC008 Charm Terraform Module standard, together with
the Terraform test, compliance, release and documentation workflows.
urls:
pr:
- https://github.com/canonical/cloudflared-operators/pull/30
related_doc:
related_issue:
visibility: public
highlight: false
6 changes: 6 additions & 0 deletions terraform/.tflint.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

rule "terraform_required_version" {
enabled = true
}
1 change: 1 addition & 0 deletions terraform/MAJOR_VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
1 change: 1 addition & 0 deletions terraform/charm/cloudflare_configurator/MAJOR_VERSION
66 changes: 66 additions & 0 deletions terraform/charm/cloudflare_configurator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<!-- vale Canonical.007-Headings-sentence-case = NO -->
# Cloudflare-configurator Terraform module
<!-- vale Canonical.007-Headings-sentence-case = YES -->

This folder contains a base [Terraform][Terraform] module for the cloudflare-configurator charm.

The module uses the [Terraform Juju provider][Terraform Juju provider] to model the charm
deployment onto any machine environment managed by [Juju][Juju].

## Module structure

- **main.tf** - Defines the Juju application to be deployed.
- **variables.tf** - Allows customization of the deployment. Also models the charm configuration,
except for exposing the deployment options (Juju model UUID, channel or application name).
- **outputs.tf** - Integrates the module with other Terraform modules, primarily
by defining potential integration endpoints (charm integrations), but also by exposing
the deployed Juju application.
- **terraform.tf** - Defines the Terraform and Juju provider versions.

## Using cloudflare-configurator base module in higher level modules

If you want to use the `cloudflare-configurator` base module as part of your Terraform module,
import it like shown below. Always pin the `?ref=` to a released tag or a commit hash: CC008
does not allow floating references such as branches.

```text
data "juju_model" "my_model" {
name = "my-model"
}

module "cloudflare_configurator" {
source = "git::https://github.com/canonical/cloudflared-operators//terraform/charm/cloudflare_configurator?ref=cloudflare-configurator-tf-1.0.0"

model_uuid = data.juju_model.my_model.uuid
# (Customize configuration variables here if needed)
}
```

Create integrations, for instance:

```text
resource "juju_integration" "cloudflared-route" {
model_uuid = data.juju_model.my_model.uuid
application {
name = module.cloudflare_configurator.application.name
endpoint = module.cloudflare_configurator.provides.cloudflared_route.endpoint
}
application {
name = "cloudflared"
endpoint = "cloudflared-route"
}
}
```

The complete list of available integrations can be found [in the Integrations tab][cloudflare-configurator-integrations].

<!-- The following section is auto-generated by terraform-docs. Do not edit it manually. -->
<!-- vale off -->
<!-- BEGIN_TF_DOCS -->
<!-- END_TF_DOCS -->
<!-- vale on -->

[Terraform]: https://www.terraform.io/
[Terraform Juju provider]: https://registry.terraform.io/providers/juju/juju/latest
[Juju]: https://canonical.com/juju
[cloudflare-configurator-integrations]: https://charmhub.io/cloudflare-configurator/integrations
18 changes: 18 additions & 0 deletions terraform/charm/cloudflare_configurator/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

resource "juju_application" "cloudflare_configurator" {
name = var.app_name
model_uuid = var.model_uuid

charm {
name = "cloudflare-configurator"
channel = var.channel
revision = var.revision
base = var.base
}

config = var.config
constraints = var.constraints
units = var.units
}
28 changes: 28 additions & 0 deletions terraform/charm/cloudflare_configurator/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

output "application" {
description = "The deployed application object."
value = juju_application.cloudflare_configurator
}

output "provides" {
description = "Map of the provided integration endpoints."
value = {
cloudflared_route = {
kind = "endpoint"
name = juju_application.cloudflare_configurator.name
endpoint = "cloudflared-route"
}
ingress = {
kind = "endpoint"
name = juju_application.cloudflare_configurator.name
endpoint = "ingress"
}
}
}

output "requires" {
description = "Map of the required integration endpoints."
value = {}
}
12 changes: 12 additions & 0 deletions terraform/charm/cloudflare_configurator/terraform.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

terraform {
required_version = "~> 1.12"
required_providers {
juju = {
source = "juju/juju"
version = "~> 1.0"
}
}
}
33 changes: 33 additions & 0 deletions terraform/charm/cloudflare_configurator/tests/main.tftest.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

run "setup_tests" {
module {
source = "./tests/setup"
}
}

run "basic_deploy" {
variables {
model_uuid = run.setup_tests.model_uuid
base = "ubuntu@24.04"
channel = "latest/edge"
# renovate: depName="cloudflare-configurator"
revision = 11
}

assert {
condition = output.application.name == "cloudflare-configurator"
error_message = "cloudflare-configurator application name did not match expected"
}

assert {
condition = output.provides.cloudflared_route.endpoint == "cloudflared-route"
error_message = "cloudflare-configurator module should provide 'provides.cloudflared_route' output"
}

assert {
condition = output.provides.ingress.endpoint == "ingress"
error_message = "cloudflare-configurator module should provide 'provides.ingress' output"
}
}
22 changes: 22 additions & 0 deletions terraform/charm/cloudflare_configurator/tests/setup/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

terraform {
required_version = "~> 1.12"
required_providers {
juju = {
source = "juju/juju"
version = "~> 1.0"
}
}
}

provider "juju" {}

resource "juju_model" "test_model" {
name = "tf-testing-${formatdate("YYYYMMDDhhmmss", timestamp())}"
}

output "model_uuid" {
value = juju_model.test_model.uuid
}
52 changes: 52 additions & 0 deletions terraform/charm/cloudflare_configurator/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

variable "app_name" {
description = "Name of the application in the Juju model."
type = string
default = "cloudflare-configurator"
nullable = false
}

variable "base" {
description = "The operating system on which to deploy."
type = string
default = null
}

variable "channel" {
description = "The channel to use when deploying a charm."
type = string
default = "latest/edge"
nullable = false
}

variable "config" {
description = "Application config. Details about available options can be found at https://charmhub.io/cloudflare-configurator/configurations"
type = map(string)
default = {}
}

variable "constraints" {
description = "Juju constraints to apply for this application."
type = string
default = null
}

variable "model_uuid" {
description = "UUID of the Juju model where the application will be deployed."
type = string
nullable = false
}

variable "revision" {
description = "Revision number of the charm."
type = number
default = null
}

variable "units" {
description = "The number of units to deploy."
type = number
default = 1
}
Loading
Loading