Skip to content

Commit 3abf88b

Browse files
MiaAltieriGu1nness
andauthored
[DPE-6303] add simple replica set terraform (#374)
* fix install timeout * update poetry + workflows * remove fields related to packages * fix linting issues * duplicate requirements in separate parts * migrate to use charm_version file per Carls suggestion * give workflow in tox access to poetry export * update charm version to pep format * PR feedback * remove build wrapper * add simple replica set terraform * add latest changes for ci fixes with terraform * remove dir * remove lock * Update terraform/tests/variables.tf Co-authored-by: Neha Oudin <[email protected]> --------- Co-authored-by: Neha Oudin <[email protected]>
1 parent ba1e705 commit 3abf88b

File tree

10 files changed

+383
-0
lines changed

10 files changed

+383
-0
lines changed

.github/workflows/ci.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,55 @@ jobs:
5757
- name: Run tests
5858
run: tox run -e unit
5959

60+
terraform-test:
61+
name: Terraform - Lint and Simple Deployment
62+
runs-on: ubuntu-22.04
63+
timeout-minutes: 120
64+
steps:
65+
- name: Checkout repo
66+
uses: actions/checkout@v4
67+
with:
68+
fetch-depth: 0
69+
- name: Install terraform snap
70+
run: |
71+
sudo snap install terraform --channel=latest/stable --classic
72+
- name: lint charm module
73+
working-directory: ./terraform
74+
run: |
75+
terraform init
76+
terraform fmt
77+
terraform validate
78+
- name: lint test charm module
79+
working-directory: ./terraform/tests
80+
run: |
81+
terraform init
82+
terraform fmt
83+
terraform validate
84+
- name: run checks - prepare
85+
run: |
86+
sudo snap install juju --channel=3.6/beta --classic
87+
sudo snap install juju-wait --channel=latest/stable --classic
88+
sudo snap install jq
89+
- name: LXD setup
90+
run: |
91+
sudo snap refresh lxd --channel=latest/stable
92+
sudo adduser "$USER" 'lxd'
93+
# `newgrp` does not work in GitHub Actions; use `sg` instead
94+
sg 'lxd' -c "lxd waitready"
95+
sg 'lxd' -c "lxd init --auto"
96+
sg 'lxd' -c "lxc network set lxdbr0 ipv6.address none"
97+
sudo iptables -F FORWARD
98+
sudo iptables -P FORWARD ACCEPT
99+
- name: Juju setup
100+
run: |
101+
sg 'lxd' -c "juju bootstrap 'localhost' --config model-logs-size=10G"
102+
juju model-defaults logging-config='<root>=INFO; unit=DEBUG'
103+
juju add-model test
104+
- name: Terraform deploy
105+
working-directory: ./terraform/tests/
106+
run: |
107+
terraform apply -var "model_name=test" -target null_resource.simple_deployment_juju_wait_deployment -auto-approve
108+
60109
build:
61110
name: Build charm | ${{ matrix.path }}
62111
uses: canonical/data-platform-workflows/.github/workflows/[email protected]

terraform/README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Terraform module for mongodb-k8s-operator
2+
3+
This is a Terraform module facilitating the deployment of the MongoDB charm with [Terraform juju provider](https://github.com/juju/terraform-provider-juju/). For more information, refer to the provider [documentation](https://registry.terraform.io/providers/juju/juju/latest/docs).
4+
5+
## Requirements
6+
This module requires a `juju` model to be available. Refer to the [usage section](#usage) below for more details.
7+
8+
## API
9+
10+
### Inputs
11+
The module offers the following configurable inputs:
12+
13+
| Name | Type | Description | Required |
14+
| - | - | - | - |
15+
| `app_name`| string | Application name | False |
16+
| `channel`| string | Channel that the charm is deployed from | False |
17+
| `base`| string | The series to be used for this charm | False |
18+
| `config`| map(string) | Map of the charm configuration options | False |
19+
| `model_name`| string | Name of the model that the charm is deployed on | True |
20+
| `resources`| map(string) | Map of the charm resources | False |
21+
| `revision`| number | Revision number of the charm name | False |
22+
| `units`| number | Number of units to be deployed | False |
23+
| `constraints`| string | Machine constraints for the charm | False |
24+
| `storage`| map(string) | Storage description, must follow the juju provider schema | False |
25+
26+
27+
### Outputs
28+
Upon applied, the module exports the following outputs:
29+
30+
| Name | Description |
31+
| - | - |
32+
| `app_name`| Application name |
33+
| `provides`| Map of `provides` endpoints |
34+
| `requires`| Map of `requires` endpoints |
35+
36+
## Usage
37+
38+
This module is intended to be used as part of a higher-level module. When defining one, users should ensure that Terraform is aware of the `juju_model` dependency of the charm module. There are two options to do so when creating a high-level module:
39+
40+
### Define a `juju_model` resource
41+
Define a `juju_model` resource and pass to the `model_name` input a reference to the `juju_model` resource's name. For example:
42+
43+
```
44+
resource "juju_model" "mongodb-k8s" {
45+
name = mongodb-k8s
46+
}
47+
48+
module "mongodb-k8s-operator" {
49+
source = "<path-to-this-directory>"
50+
model_name = juju_model.mongodb-k8s.name
51+
}
52+
```
53+
54+
### Define a `data` source
55+
Define a `data` source and pass to the `model_name` input a reference to the `data.juju_model` resource's name. This will enable Terraform to look for a `juju_model` resource with a name attribute equal to the one provided, and apply only if this is present. Otherwise, it will fail before applying anything.
56+
57+
```
58+
data "juju_model" "mongodb-k8s" {
59+
name = var.model_name
60+
}
61+
62+
module "mongodb-k8s" {
63+
source = "<path-to-this-directory>"
64+
model_name = data.juju_model.mongodb-k8s.name
65+
}
66+
```

terraform/main.tf

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright 2024 Canonical Ltd.
2+
# See LICENSE file for licensing details.
3+
4+
resource "juju_application" "mongodb-k8s" {
5+
6+
charm {
7+
name = "mongodb-k8s"
8+
channel = var.channel
9+
revision = var.revision
10+
11+
}
12+
config = var.config
13+
model = var.model
14+
name = var.app_name
15+
units = var.units
16+
constraints = var.constraints
17+
18+
19+
# TODO: uncomment once final fixes have been added for:
20+
# Error: juju/terraform-provider-juju#443, juju/terraform-provider-juju#182
21+
# placement = join(",", var.machines)
22+
23+
endpoint_bindings = [
24+
for k, v in var.endpoint_bindings : {
25+
endpoint = k, space = v
26+
}
27+
]
28+
29+
storage_directives = var.storage
30+
31+
lifecycle {
32+
precondition {
33+
condition = length(var.machines) == 0 || length(var.machines) == var.units
34+
error_message = "Machine count does not match unit count"
35+
}
36+
precondition {
37+
condition = length(var.storage) == 0 || lookup(var.storage, "count", 0) <= 1
38+
error_message = "Only one storage is supported"
39+
}
40+
}
41+
}

terraform/outputs.tf

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Copyright 2024 Canonical Ltd.
2+
# See LICENSE file for licensing details.
3+
4+
output "app_name" {
5+
description = "Name of the deployed application."
6+
value = juju_application.mongodb-k8s.name
7+
}
8+
9+
# Provided integration endpoints
10+
11+
output "database_endpoint" {
12+
description = "Name of the endpoint to provide the mongodb_client interface."
13+
value = "database"
14+
}
15+
16+
output "cos_agent_endpoint" {
17+
description = "Name of the endpoint to provide the cos_agent interface."
18+
value = "cos-agent"
19+
}
20+
21+
output "config_server_endpoint" {
22+
description = "Name of the endpoint to provide the shards interface."
23+
value = "config-server"
24+
}
25+
26+
output "cluster_endpoint" {
27+
description = "Name of the endpoint to provide the config-server interface."
28+
value = "cluster"
29+
}
30+
31+
# Required integration endpoints
32+
33+
output "certificates_endpoint" {
34+
description = "Name of the endpoint to provide the tls-certificates interface."
35+
value = "certificates"
36+
}
37+
38+
output "s3_credentials_endpoint" {
39+
description = "Name of the endpoint to provide the s3 interface."
40+
value = "s3-credentials"
41+
}
42+
43+
output "sharding_endpoint" {
44+
description = "Name of the endpoint to provide the shards interface."
45+
value = "sharding"
46+
}

terraform/tests/preamble.tf

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
resource "null_resource" "preamble" {
2+
provisioner "local-exec" {
3+
command = <<-EOT
4+
sudo snap install juju-wait --classic || true
5+
EOT
6+
}
7+
}
8+
9+
resource "juju_application" "self-signed-certificates" {
10+
charm {
11+
name = "self-signed-certificates"
12+
channel = "latest/stable"
13+
}
14+
model = var.model_name
15+
depends_on = [null_resource.preamble]
16+
}
17+
18+
resource "juju_application" "data-integrator" {
19+
charm {
20+
name = "data-integrator"
21+
channel = "latest/stable"
22+
}
23+
model = var.model_name
24+
depends_on = [null_resource.preamble]
25+
}

terraform/tests/providers.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
terraform {
2+
required_providers {
3+
juju = {
4+
source = "juju/juju"
5+
version = "~> 0.14.0"
6+
}
7+
http = {
8+
source = "hashicorp/http"
9+
version = "~> 3.4.5"
10+
}
11+
external = {
12+
source = "hashicorp/external"
13+
version = "~> 2.3.4"
14+
}
15+
}
16+
}

terraform/tests/simple_deployment.tf

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
module "mongodb-k8s" {
2+
source = "../"
3+
app_name = var.app_name
4+
model = var.model_name
5+
units = var.simple_mongodb_units
6+
channel = "6/edge"
7+
}
8+
9+
resource "juju_integration" "simple_deployment_tls-operator_mongodb-integration" {
10+
model = var.model_name
11+
12+
application {
13+
name = juju_application.self-signed-certificates.name
14+
}
15+
application {
16+
name = var.app_name
17+
}
18+
depends_on = [
19+
juju_application.self-signed-certificates,
20+
module.mongodb-k8s
21+
]
22+
23+
}
24+
25+
resource "juju_integration" "simple_deployment_data-integrator_mongodb-integration" {
26+
model = var.model_name
27+
28+
application {
29+
name = juju_application.data-integrator.name
30+
}
31+
application {
32+
name = var.app_name
33+
}
34+
depends_on = [
35+
juju_application.data-integrator,
36+
module.mongodb-k8s
37+
]
38+
39+
}
40+
41+
resource "null_resource" "simple_deployment_juju_wait_deployment" {
42+
provisioner "local-exec" {
43+
command = <<-EOT
44+
juju-wait -v --model ${var.model_name}
45+
EOT
46+
}
47+
48+
depends_on = [juju_integration.simple_deployment_tls-operator_mongodb-integration]
49+
}

terraform/tests/variables.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
variable "model_name" {
2+
description = "Model name"
3+
type = string
4+
}
5+
6+
variable "app_name" {
7+
description = "MongoDB app name"
8+
type = string
9+
default = "mongodb-k8s"
10+
}
11+
12+
variable "simple_mongodb_units" {
13+
description = "Node count"
14+
type = number
15+
default = 1
16+
}

terraform/variables.tf

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright 2024 Canonical Ltd.
2+
# See LICENSE file for licensing details.
3+
4+
variable "app_name" {
5+
description = "Application name"
6+
type = string
7+
default = "mongodb-k8s"
8+
}
9+
10+
variable "channel" {
11+
description = "Charm channel"
12+
type = string
13+
default = "6/stable"
14+
}
15+
16+
17+
18+
variable "config" {
19+
description = "Map of charm configuration options"
20+
type = map(string)
21+
default = {}
22+
}
23+
24+
variable "model" {
25+
description = "Model name"
26+
type = string
27+
}
28+
29+
variable "revision" {
30+
description = "Charm revision"
31+
type = number
32+
default = null
33+
}
34+
35+
variable "units" {
36+
description = "Charm units"
37+
type = number
38+
default = 3
39+
}
40+
41+
variable "constraints" {
42+
description = "String listing constraints for this application"
43+
type = string
44+
default = "arch=amd64"
45+
}
46+
47+
variable "machines" {
48+
description = "List of machines for placement"
49+
type = list(string)
50+
default = []
51+
}
52+
53+
variable "storage" {
54+
description = "Map of storage used by the application"
55+
type = map(string)
56+
default = {}
57+
}
58+
59+
variable "endpoint_bindings" {
60+
description = "Map of endpoint bindings"
61+
type = map(string)
62+
default = {}
63+
}

0 commit comments

Comments
 (0)