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

feat(storage): extend application schema for storage flag #492

Merged
merged 1 commit into from
Jul 2, 2024

Conversation

anvial
Copy link
Member

@anvial anvial commented May 29, 2024

Description

This PR introduces significant enhancements to our Terraform provider for Juju. The main changes include extending of the application schema to support the storage flag in the Terraform provider for Juju.

The schema now includes various attributes for configuring the storage constraints of a Juju application.

Fixes:

Type of change

  • Change existing resource

Environment

  • Juju controller version: -

  • Terraform version: -

Plan example

terraform {
  required_providers {
    juju = {
      source  = "juju/juju"
      version = "0.12.0"
    }
  }
}
provider "juju" {}

resource "juju_model" "storage-model" {
  name = "storage-model"
}

resource "juju_application" "postgresql" {
  name  = "postgresql"
  model = juju_model.storage-model.name

  charm {
    name     = "postgresql"
    channel  = "latest/stable"
  }

  storage = [
    {
      pool  = "lxd"
      label = "pgdata"
      size  = "8M"
      count = 1
    }
  ]

  units = 1
}
...

@anvial anvial requested a review from cderici May 29, 2024 08:47
Copy link
Contributor

@Aflynn50 Aflynn50 left a comment

Choose a reason for hiding this comment

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

Is it possible to do CRUD operations on all the storage parameters? If not would we have to use a data source instead?

},
"size": schema.StringAttribute{
Description: "The size of each volume. E.g. 100G",
Required: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

From reading the storage constraints docs, it seems to me that size is not required. From what I can tell you can choose to leave out any of size, pool and count.

I guess it would technically be fine if the user left out all three, it should just have no effect.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm, and where we said that this is optional...

Knowing that we do not support dynamic size volumes, I wonder how the "size" could be optional.

Copy link
Member

Choose a reason for hiding this comment

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

Find the default that juju uses and make that the default. Then the attribute can be optional.

Default: stringdefault.StaticString("str"),

I'm not sure if setting a default in the schema is possible or not. Charm metadata can optionally define a MinimumSize for storage:

	// There is no default MinimumSize; if left unspecified, a provider
	// specific default will be used, typically 1GB for block storage.

Copy link
Contributor

Choose a reason for hiding this comment

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

Here is the doc I was looking at https://juju.is/docs/juju/storage-constraint

internal/provider/resource_application.go Outdated Show resolved Hide resolved
internal/provider/resource_application.go Outdated Show resolved Hide resolved
@cderici cderici added this to the 0.13.0 milestone May 30, 2024
Copy link

@cderici cderici left a comment

Choose a reason for hiding this comment

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

Couple of comments and a suggestion:

  • I'm not sure if I understand what label is for, and why it is required? also the name "label" might get confused with the label for block devices in the context of storages.
  • why is the size required?
  • it might be a good idea to have some validation in the schema with a ValidateConfig (example here) against small stuff (like size being positive, or count defaults to 1 if size is specified, etc) (format here).

Also it would great if you can provide an example resource_application in the PR description that includes the use of this storage SetNestedAttribute so it would be clear what it'll look like.

@anvial anvial changed the title Define schema for storage flag in Terraform provider feat(storage): Define schema for storage flag in Terraform provider Jun 6, 2024
@anvial anvial changed the title feat(storage): Define schema for storage flag in Terraform provider feat(storage): extend application schema for storage flag Jun 7, 2024
@anvial
Copy link
Member Author

anvial commented Jun 7, 2024

Couple of comments and a suggestion:

  • I'm not sure if I understand what label is for, and why it is required? also the name "label" might get confused with the label for block devices in the context of storages.

Here we mimic under StorageContraints defined in storage.go (in Juju):

// StorageConstraints contains the user-specified constraints for provisioning
// storage instances for an application unit.
type StorageConstraints struct {
	// Pool is the name of the storage pool from which to provision the
	// storage instances.
	Pool string `bson:"pool"`

	// Size is the required size of the storage instances, in MiB.
	Size uint64 `bson:"size"`

	// Count is the required number of storage instances.
	Count uint64 `bson:"count"`
}

where label is "middle part" of storage-tag: storage-<storage-label>-NUM

  • why is the size required?

In Juju, we have a policy that "storage constraints require at least one field to be specified." However, this is difficult to provide in the declarative nature of TF. So, as a solution to be more strict about size.

  • it might be a good idea to have some validation in the schema with a ValidateConfig (example here) against small stuff (like size being positive, or count defaults to 1 if size is specified, etc) (format here).

thx I'll have a look

Also it would great if you can provide an example resource_application in the PR description that includes the use of this storage SetNestedAttribute so it would be clear what it'll look like.

I'll add example in the description.

@anvial anvial requested a review from hmlanigan June 7, 2024 10:38
@anvial anvial force-pushed the JUJU-6022-define-schema-for-storage-flag branch from aa0ccbd to 12f3b91 Compare June 7, 2024 10:42
internal/provider/resource_application.go Show resolved Hide resolved
internal/provider/resource_application.go Show resolved Hide resolved
},
"size": schema.StringAttribute{
Description: "The size of each volume. E.g. 100G",
Required: true,
Copy link
Member

Choose a reason for hiding this comment

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

Find the default that juju uses and make that the default. Then the attribute can be optional.

Default: stringdefault.StaticString("str"),

I'm not sure if setting a default in the schema is possible or not. Charm metadata can optionally define a MinimumSize for storage:

	// There is no default MinimumSize; if left unspecified, a provider
	// specific default will be used, typically 1GB for block storage.

Comment on lines 190 to 198
PlanModifiers: []planmodifier.Object{
objectplanmodifier.RequiresReplaceIfConfigured(),
objectplanmodifier.UseStateForUnknown(),
},
Copy link
Member

@hmlanigan hmlanigan Jun 7, 2024

Choose a reason for hiding this comment

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

On reflection, we may want to make these plan modifiers on each attribute, rather than on the object themselves. I need to understand the difference better.

Our goal is to mimic the behavior of juju deploy --storage and juju refresh --storage.

Scenarios to consider

  1. A new application resource with storage is created -> the application is deployed with storage.
  2. Storage attribute is added to an existing application resource without a new charm revision to refresh to. -> We should fail ?? Or recreate the application?
  3. Storage attribute is added to an existing application resource WITH a new charm revision to refresh to. -> Refresh the charm and add the storage.
  4. An existing storage attribute is removed from the plan -> recreate the application without the storage.

@hmlanigan
Copy link
Member

@Aflynn50 :

Is it possible to do CRUD operations on all the storage parameters? If not would we have to use a data source instead?

A resource or data source for storage is beyond the scope of the current storage project. The goal is to provide the functionality of juju deploy --storage and juju refresh --storage only.

We need to enhance the documentation to be clear on this point.

@anvial anvial force-pushed the JUJU-6022-define-schema-for-storage-flag branch 6 times, most recently from 283c239 to 7ba2ac6 Compare June 14, 2024 09:10
Copy link
Member

@hmlanigan hmlanigan left a comment

Choose a reason for hiding this comment

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

Approved once the two items have been addressed.

internal/provider/resource_application.go Show resolved Hide resolved
internal/provider/resource_application.go Outdated Show resolved Hide resolved
…urce

This commit extends the application schema to support the storage flag in the Terraform provider for Juju.
The schema now includes varios attributes for configuring the storage constraints of a Juju application.
@anvial anvial force-pushed the JUJU-6022-define-schema-for-storage-flag branch from 7ba2ac6 to 5ab3f0e Compare July 2, 2024 12:26
@anvial anvial merged commit ca1da69 into juju:main Jul 2, 2024
13 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants