Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Craft the juju model-config for suppressing fan-config #22

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
6 changes: 3 additions & 3 deletions .github/workflows/plan-terraform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ jobs:
test:
- name: Openstack
yaml: test/openstack.yaml
cloud_integration: openstack
cloud_integration: "true"
- name: Vanilla
yaml: test/vanilla.yaml
cloud_integration: ''
cloud_integration: "false"
Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, I feel like 'cloud_integration=' was more intuitive than this, especially since we now need to set both "cloud" and "cloud_integration". Can we not just read the cloud from the variable and then set it in the model internally?

Copy link
Contributor Author

@addyess addyess Feb 19, 2025

Choose a reason for hiding this comment

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

so, there may be cases you want to deploy on a cloud -- but without the cloud-integrations. Juju requires the cloud value. So, I switched cloud_integration to be true/false to engage the cloud integration. But yeah -- i liked cloud_integration=<cloud> better too...

I wasn't sure how else to model this better.

Copy link
Contributor

Choose a reason for hiding this comment

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

fair enough

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok @bschimke95 i was won over by a powerful argument -- cloud in juju parlance is the name of a particular cloud instance. So i might have an openstack cloud instance named my-openstack-instance but i still want the openstack cloud-integration. So I think i've put it back to the way it was before i changed it

env:
TF_VAR_model: test
TF_VAR_model: '{"name": "test", "cloud": "openstack", "config": {"test": true}}'
TF_VAR_manifest_yaml: ${{ matrix.test.yaml }}
TF_VAR_cloud_integration: ${{ matrix.test.cloud_integration }}
WORKING_DIR: 'terraform'
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ main/.charmcraft_output_packages.txt
**/.terraform
**/.terraform.lock.hcl
**/*.tfstate
**/*.tfstate.backup
**/tfplan
50 changes: 33 additions & 17 deletions terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,32 @@ charm configuration.
## TODO
- [ ] Set outputs for each charm deployed
- [ ] Add COS integration
- [ ] Find a home for this module
- [ ] Add required subordinate (Landscape, NTP, etc..) see [This private Terraform Plan for details](https://git.launchpad.net/canonical-terraform-modules/tree/services/compute/canonical_k8s_cluster/main.tf#n214)
- [ ] Add required subordinate (Landscape, NTP, etc..) see [This private Terraform Plan for details][private-details]

## Applications
* [k8s](https://charmhub.io/k8s)
* [k8s-worker](https://charmhub.io/k8s-worker)

## Inputs
| Name | Type | Description | Required |
| - | - | - | - |
| `manifest_yaml` | string | Absolute path to the manifest yaml for the deployment | True |
| `model` | string | Name of the Juju model to deploy into | True |
| `cloud_integration` | string | Selection of a cloud integration | False |
| Name | Type | Description | Required |
| --- | --- | --- | --- |
| `manifest_yaml` | string | Absolute path to the manifest yaml for the deployment | True |
| `model` | object | Juju model attributes | True |
| `cloud_integration` | bool | Enablement of a cloud integration | False |

### Model Input:
Juju Model resource definition borrows its schema from [Juju Model Resource].

The schema requires only:
- **name**: Name of the model
- **cloud**: Cloud name

Default fields are:
- **region**: Region name (optional)
- **config**: Configuration map (optional)
- **constraints**: Constraints string (optional)
- **credential**: Credential name (optional)


## Outputs
TODO
Expand All @@ -30,29 +43,32 @@ TODO

Add the following to your main.tf for the canonical k8s solution:

```
```hcl
module "k8s" {
source = "git::https://github.com/canonical/k8s-bundles//terraform?ref=main"
model = "my-canonical-k8s"
model = {
name = "my-canonical-k8s"
cloud = "openstack"
}
manifest_yaml = "/path/to/manifest.yaml"
}
```

Define your manifest.yaml based on the requirements for your deployment. Specific configuration
options can be found under the charm URLs linked above.
Define your manifest.yaml based on the requirements for your deployment. Specific configuration options can be found under the charm URLs linked above.

```
```yaml
k8s:
units: 2
units: 3
base: [email protected]
constraints: arch=amd64 cores=2 mem=4096M root-disk=16384M
channel: 1.31/beta
channel: 1.32/stable
k8s_worker:
units: 2
base: [email protected]
constraints: arch=amd64 cores=2 mem=8192M root-disk=16384M
channel: 1.31/beta
channel: 1.32/stable
```



<!--LINKS -->
[Juju Model Resource]: https://registry.terraform.io/providers/juju/juju/0.16.0/docs/resources/model
[private-details]: https://git.launchpad.net/canonical-terraform-modules/tree/services/compute/canonical_k8s_cluster/main.tf#n214
12 changes: 6 additions & 6 deletions terraform/applications.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# See LICENSE file for licensing details.

module "k8s" {
source = "git::https://github.com/canonical/k8s-operator//charms/worker/k8s/terraform"
source = "git::https://github.com/canonical/k8s-operator//charms/worker/k8s/terraform?ref=KU-2727/float-terraform-juju-provider"
app_name = module.k8s_config.config.app_name
channel = module.k8s_config.config.channel
# This currently just sets the bootstrap-node-taints to have the right no schedule value
Expand All @@ -13,30 +13,30 @@ module "k8s" {
{"bootstrap-node-taints": "node-role.kubernetes.io/control-plane:NoSchedule"}
)
constraints = module.k8s_config.config.constraints
model = var.model
model = resource.juju_model.this.name
resources = module.k8s_config.config.resources
revision = module.k8s_config.config.revision
base = module.k8s_config.config.base
units = module.k8s_config.config.units
}

module "k8s_worker" {
source = "git::https://github.com/canonical/k8s-operator//charms/worker/terraform"
source = "git::https://github.com/canonical/k8s-operator//charms/worker/terraform?ref=KU-2727/float-terraform-juju-provider"
app_name = module.k8s_worker_config.config.app_name
base = coalesce(module.k8s_worker_config.config.base, module.k8s_config.config.base)
constraints = coalesce(module.k8s_worker_config.config.constraints, module.k8s_config.config.constraints)
channel = coalesce(module.k8s_worker_config.config.channel, module.k8s_config.config.channel)
config = module.k8s_worker_config.config.config
model = var.model
model = resource.juju_model.this.name
resources = module.k8s_worker_config.config.resources
revision = module.k8s_worker_config.config.revision
units = module.k8s_worker_config.config.units
}

module "openstack" {
count = var.cloud_integration == "openstack" ? 1 : 0
count = (var.model.cloud == "openstack" && var.cloud_integration) ? 1 : 0
source = "./openstack"
model = var.model
model = resource.juju_model.this.name
manifest_yaml = var.manifest_yaml
k8s = {
app_name = module.k8s.app_name
Expand Down
4 changes: 2 additions & 2 deletions terraform/configs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
# See LICENSE file for licensing details.

module "k8s_config" {
source = "git::https://github.com/canonical/k8s-bundles//terraform/manifest?ref=main"
source = "./manifest/"
manifest = var.manifest_yaml
app = "k8s"
}

module "k8s_worker_config" {
source = "git::https://github.com/canonical/k8s-bundles//terraform/manifest?ref=main"
source = "./manifest/"
manifest = var.manifest_yaml
app = "k8s_worker"
}
35 changes: 32 additions & 3 deletions terraform/integrations.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,37 @@
# Copyright 2024 Canonical Ltd.
# See LICENSE file for licensing details.

resource "juju_model" "this" {
name = var.model.name

cloud {
name = var.model.cloud
region = var.model.region
}

config = merge(
{ # Remove two keys from the config map if they exist
for k, v in var.model.config != null ? var.model.config : {} :
k => v
if !contains(["fan-config", "container-networking-method"], k)
},
{
fan-config = ""
container-networking-method = "local"
}
)

constraints = var.model.constraints
credential = var.model.credential

provisioner "local-exec" {
# workaround for https://github.com/juju/terraform-provider-juju/issues/667
command = "juju model-config fan-config=''"
}
}

resource "juju_integration" "k8s_cluster_integration" {
model = var.model
model = resource.juju_model.this.name
application {
name = module.k8s.app_name
endpoint = module.k8s.provides.k8s_cluster
Expand All @@ -14,7 +43,7 @@ resource "juju_integration" "k8s_cluster_integration" {
}

resource "juju_integration" "k8s_containerd" {
model = var.model
model = resource.juju_model.this.name
application {
name = module.k8s.app_name
endpoint = module.k8s.provides.containerd
Expand All @@ -26,7 +55,7 @@ resource "juju_integration" "k8s_containerd" {
}

resource "juju_integration" "k8s_cos_worker_tokens" {
model = var.model
model = resource.juju_model.this.name
application {
name = module.k8s.app_name
endpoint = module.k8s.provides.cos_worker_tokens
Expand Down
6 changes: 3 additions & 3 deletions terraform/openstack/applications.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# See LICENSE file for licensing details.

module "openstack_integrator" {
source = "git::https://github.com/charmed-kubernetes/charm-openstack-integrator//terraform?ref=main"
source = "git::https://github.com/charmed-kubernetes/charm-openstack-integrator//terraform?ref=KU-2727/float-terraform-juju-provider"

model = var.model
app_name = module.openstack_integrator_config.config.app_name
Expand All @@ -17,7 +17,7 @@ module "openstack_integrator" {
}

module "cinder_csi" {
source = "git::https://github.com/canonical/cinder-csi-operator//terraform?ref=main"
source = "git::https://github.com/canonical/cinder-csi-operator//terraform?ref=KU-2727/float-terraform-juju-provider"

model = var.model
app_name = module.cinder_csi_config.config.app_name
Expand All @@ -29,7 +29,7 @@ module "cinder_csi" {
}

module "openstack_cloud_controller" {
source = "git::https://github.com/charmed-kubernetes/openstack-cloud-controller-operator//terraform?ref=main"
source = "git::https://github.com/charmed-kubernetes/openstack-cloud-controller-operator//terraform?ref=KU-2727/float-terraform-juju-provider"

model = var.model
app_name = module.openstack_cloud_controller_config.config.app_name
Expand Down
6 changes: 3 additions & 3 deletions terraform/openstack/configs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
# See LICENSE file for licensing details.

module "openstack_integrator_config" {
source = "git::https://github.com/canonical/k8s-bundles//terraform/manifest?ref=main"
source = "../manifest/"
manifest = var.manifest_yaml
app = "openstack_integrator"
}

module "cinder_csi_config" {
source = "git::https://github.com/canonical/k8s-bundles//terraform/manifest?ref=main"
source = "../manifest/"
manifest = var.manifest_yaml
app = "cinder_csi"
}

module "openstack_cloud_controller_config" {
source = "git::https://github.com/canonical/k8s-bundles//terraform/manifest?ref=main"
source = "../manifest"
manifest = var.manifest_yaml
app = "openstack_cloud_controller"
}
2 changes: 1 addition & 1 deletion terraform/openstack/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ terraform {
required_providers {
juju = {
source = "juju/juju"
version = "~> 0.14.0"
version = ">= 0.14.0, < 1.0.0"
}
}
}
4 changes: 2 additions & 2 deletions terraform/test/vanilla.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
k8s:
units: 3
base: [email protected]
constraints: arch=amd64 cores=2 mem=8G root-disk=16G
constraints: arch=amd64 cores=2 mem=8192M root-disk=16384M
channel: latest/edge
k8s_worker:
units: 3
base: [email protected]
constraints: arch=amd64 cores=2 mem=8G root-disk=16G
constraints: arch=amd64 cores=2 mem=8192M root-disk=16384M
channel: latest/edge
44 changes: 34 additions & 10 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,43 @@ variable "manifest_yaml" {
type = string
}

variable "model" {
description = "Name of the Juju model to deploy to."
type = string
variable "cloud_integration" {
description = "Enable cloud integration."
type = bool
default = false
}

variable "cloud_integration" {
description = "Selection of a cloud integration"
type = string
default = ""
variable "model" {
description = <<EOT
Juju Model resource definition.

Schema represented by the juju model resource:
- name: Name of the model
- cloud: Cloud name
- region: Region name (optional)
- config: Configuration map (optional)
- constraints: Constraints string (optional)
- credential: Credential name (optional)

https://registry.terraform.io/providers/juju/juju/0.16.0/docs/resources/model
EOT

type = object({
name = string
cloud = string
region = optional(string)
config = optional(map(any))
constraints = optional(string)
credential = optional(string)
})

validation {
condition = contains(["", "openstack"], var.cloud_integration)
error_message = "Cloud must be one of '', or 'openstack'"
condition = (
var.model.config == null || alltrue([
for k, v in var.model.config:
v == null || can(tostring(v)) || can(tonumber(v)) || can(tobool(v))
])
)
error_message = "Config must be a map where values are only strings, numbers, or bools."
}
}

2 changes: 1 addition & 1 deletion terraform/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ terraform {
required_providers {
juju = {
source = "juju/juju"
version = "~> 0.14.0"
version = ">= 0.14.0, < 1.0.0"
}
}
}
Loading