Skip to content

Commit

Permalink
[DPE-6089] Update Terraform to new scheme (#520)
Browse files Browse the repository at this point in the history
## Issue
We would like an easy way to deploy MongoDB using terraform on lxd and
openstack

## Solution
Add 

## Manual Testing
```
terraform init
terraform apply 
```
done on both LXD and on OpenStack

---------

Co-authored-by: Neha Oudin <[email protected]>
  • Loading branch information
MiaAltieri and Gu1nness authored Dec 17, 2024
1 parent c74db02 commit 62dd700
Show file tree
Hide file tree
Showing 11 changed files with 333 additions and 86 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,53 @@ jobs:
- name: Run tests
run: tox run -e unit

terraform-test:
name: Terraform - Lint and Simple Deployment
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: lint charm module
working-directory: ./terraform
run: |
terraform init
terraform fmt
terraform validate
- name: lint test charm module
working-directory: ./terraform/tests
run: |
terraform init
terraform fmt
terraform validate
- name: run checks - prepare
run: |
sudo snap install juju --channel=3.6/beta --classic
sudo snap install juju-wait --channel=latest/stable --classic
sudo snap install jq
- name: LXD setup
run: |
sudo snap refresh lxd --channel=latest/stable
sudo adduser "$USER" 'lxd'
# `newgrp` does not work in GitHub Actions; use `sg` instead
sg 'lxd' -c "lxd waitready"
sg 'lxd' -c "lxd init --auto"
sg 'lxd' -c "lxc network set lxdbr0 ipv6.address none"
sudo iptables -F FORWARD
sudo iptables -P FORWARD ACCEPT
- name: Juju setup
run: |
sg 'lxd' -c "juju bootstrap 'localhost' --config model-logs-size=10G"
juju model-defaults logging-config='<root>=INFO; unit=DEBUG'
juju add-model test
- name: Terraform deploy
working-directory: ./terraform/tests/
run: |
terraform apply -var "model=test" -target null_resource.simple_deployment_juju_wait_deployment -auto-approve
lib-check:
name: Check libraries
runs-on: ubuntu-latest
Expand Down
48 changes: 46 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,52 @@ override.tf.json
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*

# Ignore CLI configuration files


########################################################
#
# Terraform .gitignore
#
########################################################


# Local .terraform directories
**/.terraform/*
*.terraform.lock.hcl

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log
crash.*.log

# Generated files
*.key
credentials*

# 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
# to change depending on the environment.
*.tfvars
*.tfvars.json

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Include override files you do wish to add to version control using negated pattern
# !example_override.tf

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*

# Ignore CLI configuration files
.terraformrc
terraform.rc
.terraform.lock.hcl

90 changes: 49 additions & 41 deletions terraform/README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,66 @@
# MongoDB Operator Terraform module
# Terraform module for mongodb-operator

This folder contains a base [Terraform][Terraform] module for the `mongodb` charm.
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).

The module uses the [Terraform Juju provider][Terraform Juju provider] to model the charm deployment onto any Kubernetes environment managed by [Juju][Juju].
## Requirements
This module requires a `juju` model to be available. Refer to the [usage section](#usage) below for more details.

The base module is not intended to be deployed in separation (it is possible though), but should rather serve as a building block for higher level modules.
## API

## Module structure
### Inputs
The module offers the following configurable inputs:

- **main.tf** - Defines the Juju application to be deployed.
- **variables.tf** - Allows customization of the deployment such as Juju model name, channel or application name and charm configuration.
- **output.tf** - Responsible for integrating the module with other Terraform modules, primarily by defining potential integration endpoints (charm integrations), but also by exposing the application name.
- **terraform.tf** - Defines the Terraform provider.
| Name | Type | Description | Required |
| - | - | - | - |
| `app_name`| string | Application name | False |
| `channel`| string | Channel that the charm is deployed from | False |
| `base`| string | The series to be used for this charm | False |
| `config`| map(string) | Map of the charm configuration options | False |
| `model_name`| string | Name of the model that the charm is deployed on | True |
| `resources`| map(string) | Map of the charm resources | False |
| `revision`| number | Revision number of the charm name | False |
| `units`| number | Number of units to be deployed | False |
| `constraints`| string | Machine constraints for the charm | False |
| `storage`| map(string) | Storage description, must follow the juju provider schema | False |

## Using mongodb base module in higher level modules

If you want to use `mongodb-operator` base module as part of your Terraform module, import it like shown below.
### Outputs
Upon applied, the module exports the following outputs:

```text
module "mongodb-operator" {
source = "git::https://github.com/canonical/mongodb-operator.git/terraform"
model_name = "juju_model_name"
(Customize configuration variables here if needed)
}
```
| Name | Description |
| - | - |
| `app_name`| Application name |
| `provides`| Map of `provides` endpoints |
| `requires`| Map of `requires` endpoints |

Please see the link to customize the Grafana configuration variables if needed.
## Usage

- [MongoDB configuration options][MongoDB configuration options]
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:

Create the integrations, for instance:
### Define a `juju_model` resource
Define a `juju_model` resource and pass to the `model_name` input a reference to the `juju_model` resource's name. For example:

```text
resource "juju_integration" "amf-db" {
model = var.model_name
application {
name = module.amf.app_name
endpoint = module.amf.database_endpoint
}
```
resource "juju_model" "mongodb" {
name = mongodb
}
application {
name = module.mongodb.app_name
endpoint = module.mongodb.database_endpoint
}
module "mongodb-operator" {
source = "<path-to-this-directory>"
model_name = juju_model.mongodb.name
}
```

Please check the available [integration pairs][integration pairs].
### Define a `data` source
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.

[Terraform]: https://www.terraform.io/
[Juju]: https://juju.is
[Terraform Juju provider]: https://registry.terraform.io/providers/juju/juju/latest
[MongoDB configuration options]: https://charmhub.io/mongodb/configure?channel=6/edge
[integration pairs]: https://charmhub.io/mongodb/integrations?channel=6/edge
```
data "juju_model" "mongodb" {
name = var.model_name
}
module "mongodb" {
source = "<path-to-this-directory>"
model_name = data.juju_model.mongodb.name
}
```
43 changes: 34 additions & 9 deletions terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,40 @@
# See LICENSE file for licensing details.

resource "juju_application" "mongodb" {
name = var.app_name
model = var.model_name

charm {
name = "mongodb"
channel = var.channel
base = "[email protected]"
name = "mongodb"
channel = var.channel
revision = var.revision
base = "[email protected]"
}
config = var.config
units = 1
trust = true
}
config = var.config
model = var.model
name = var.app_name
units = var.units
constraints = var.constraints


# TODO: uncomment once final fixes have been added for:
# Error: juju/terraform-provider-juju#443, juju/terraform-provider-juju#182
# placement = join(",", var.machines)

endpoint_bindings = [
for k, v in var.endpoint_bindings : {
endpoint = k, space = v
}
]

storage_directives = var.storage

lifecycle {
precondition {
condition = length(var.machines) == 0 || length(var.machines) == var.units
error_message = "Machine count does not match unit count"
}
precondition {
condition = length(var.storage) == 0 || lookup(var.storage, "count", 0) <= 1
error_message = "Only one storage is supported"
}
}
}
23 changes: 1 addition & 22 deletions terraform/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ output "database_endpoint" {
value = "database"
}

output "obsolete_endpoint" {
description = "Name of the endpoint to provide the mongodb interface."
value = "obsolete"
}

output "cos_agent_endpoint" {
description = "Name of the endpoint to provide the cos_agent interface."
value = "cos-agent"
Expand All @@ -33,22 +28,6 @@ output "cluster_endpoint" {
value = "cluster"
}

output "metrics_endpoint" {
description = "Name of the endpoint to provide the prometheus_scrape interface."
value = "metrics-endpoint"
}

output "grafana_dashboard_endpoint" {
description = "Name of the endpoint to provide the grafana_dashboard interface."
value = "grafana-dashboard"
}

output "logging_endpoint" {
description = "Name of the endpoint to provide the loki_push_api relation interface."
value = "logging"
}


# Required integration endpoints

output "certificates_endpoint" {
Expand All @@ -64,4 +43,4 @@ output "s3_credentials_endpoint" {
output "sharding_endpoint" {
description = "Name of the endpoint to provide the shards interface."
value = "sharding"
}
}
25 changes: 25 additions & 0 deletions terraform/tests/preamble.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
resource "null_resource" "preamble" {
provisioner "local-exec" {
command = <<-EOT
sudo snap install juju-wait --classic || true
EOT
}
}

resource "juju_application" "self-signed-certificates" {
charm {
name = "self-signed-certificates"
channel = "latest/stable"
}
model = var.model_name
depends_on = [null_resource.preamble]
}

resource "juju_application" "data-integrator" {
charm {
name = "data-integrator"
channel = "latest/stable"
}
model = var.model_name
depends_on = [null_resource.preamble]
}
16 changes: 16 additions & 0 deletions terraform/tests/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
terraform {
required_providers {
juju = {
source = "juju/juju"
version = "~> 0.14.0"
}
http = {
source = "hashicorp/http"
version = "~> 3.4.5"
}
external = {
source = "hashicorp/external"
version = "~> 2.3.4"
}
}
}
Loading

0 comments on commit 62dd700

Please sign in to comment.