Open phvalguima opened 10 months ago
Hi, in a discussion with @hmlanigan, the first step is to come up with an Schema for spaces.
My proposal is to have spaces as a DataSource and Resource. Therefore, an user can create new spaces in its modules or declare existing spaces from a controller.
One thing is that spaces and subnets are very connected concepts in Juju. I am not entirely sure if we should keep it as one single logical group (only spaces) or break it into two DataSources: spaces
and subnets
. I will write a schema proposal for each. In case it is decided to move on with one single logical object, then subnets become "NestedBlocks" in spaces but they can have the same Schema.
Having space support would allow us to interact with main cloud providers in TF more easily. One example, one could declare a subnet in AWS and then declare it directly as a subnet DataSource, pass to a space and start using it:
resource "aws_subnet" "public_cidr" {
vpc_id = aws_vpc.single_az_vpc.id
cidr_block = var.public_cidr.cidr
availability_zone = var.vpc.az
tags = {
Name = var.public_cidr.name
}
}
data "juju_subnet" "public_subnet" {
provider_id = aws_vpc.single_az_vpc.id
cidr = var.public_cidr.cidr
}
resource "juju_space" "public_space" {
...
subnets = [data.juju_subnet.public_subnet.cidr]
}
Then, an user can create a VM based on the information above and pass it to juju:
resource "aws_instance" "jumphost" {
...
public_ips = data.juju_subnet.public_subnet.cidr.0 # This way we are linked between Juju and AWS
}
resource "juju_machine" "jumphost_vm" {
...
}
I think the best argument to have subnets as DataSource instead of parts of Space object is to be able to track its lifecycle separated. This way, subnet
would show up in terraform state
and we can also execute operations, such as remove from space-1 and move it to space-2, as spaces depend on it explicitly.
Here is my proposal for the space schema, based in the space doc in Juju code:
Schema {
resp.Schema = schema.Schema{
Description: "A resource representing a Juju Space.",
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
Description: "The space name.",
Required: true,
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplaceIfConfigured()
},
},
"id": schema.StringAttribute{
Description: "The Space ID.",
Required: true,
Computed: true,
},
"model-uuid": schema.StringAttribute{
Description: "The model UUID containing this subnet.",
Computed: true,
Required: true,
},
"provider-id": schema.StringAttribute{
Description: "The cloud provider ID for the subnet.",
Computed: true,
},
"zones": schema.ListAttribute{
Description: "List of cloud provider's availability zones. Composed by each Subnet's AZ.",
Computed: true,
},
"subnets": schema.ListAttribute{
Description: "List of subnets' CIDRs that have been added to this space.",
Computed: true,
Optional: true
},
},
}
}
The subnet schema should consider the info that generally shows up in the output of:
$ juju subnets
10.10.10.0/20:
type: ipv4
provider-id: subnet-...
provider-network-id: vpc-...
status: in-use
space: alpha
zones:
* us-east-1a
Here is the schema is based on this struct from juju code:
Schema {
resp.Schema = schema.Schema{
Description: "A data source representing a Juju Subnet.",
Attributes: map[string]schema.Attribute{
"cidr": schema.StringAttribute{
Description: "The subnet CIDR.",
Required: true
Computed: true,
},
"type": schema.StringAttribute{
Description: "The subnet CIDR type (ipv4 or v6).",
Required: true
Computed: true,
},
"space-id": schema.StringAttribute{
Description: "The subnet Space ID.",
Optional: true,
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplaceIfConfigured()
},
},
"model-uuid": schema.StringAttribute{
Description: "The model UUID containing this subnet.",
Computed: true,
Required: true,
},
"status": schema.StringAttribute{
Description: "The subnet has been allocated .",
Optional: true,
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplaceIfConfigured()
},
},
"provider-id": schema.StringAttribute{
Description: "The cloud provider ID for the subnet.",
Computed: true,
},
"provider-network-id": schema.ListAttribute{
Description: "The cloud provider's network ID for the subnet.",
Computed: true,
},
"is-public": schema.BooleanAttribute{
Description: "Marks if this subnet is publicly available.",
Computed: true,
},
"vlan": schema.Int64Attribute{
Description: "VLAN tag used by this subnet.",
Computed: true,
Required: false,
},
"zones": schema.ListAttribute{
Description: "List of cloud provider's availability zones.",
},
"is-fan-underlay": schema.BooleanAttribute{
Description: "Indicates if this subnet represents a Fan network underlay CIDR.",
Optional: true,
Computed: true,
Default: false,
},
"is-fan-overlay": schema.BooleanAttribute{
Description: "Indicates if this subnet represents a Fan network overlay CIDR.",
Optional: true,
Computed: true,
Default: false,
},
},
}
}
Some thoughts related to the space source schema:
RequiresReplaceIfConfigured
necessary as there is a juju rename-space
command, thus it's available by API.RequiresReplace
.ElementType: types.StringType,
?As not all spaces are created by a user, e.g. MAAS, having a space datasource would also be good. There is also a default space called alpha
which is created by juju as all subnets must be in a space.
A subnet should be a datasource. You cannot directly add, modify nor remove a subnet via the juju client. Datasources can be referenced inside of resources. You can ask juju to search for available spaces and subnets, however I'm not sure how that fits into the terraform methodology. - Update: you've mentioned it should be a data source then used the resource schema to describe it.
A subnet datasource should have a cidr and model-uuid. An id is required for testing, see some of the other datasources.
Description
There is currently no way to interact with spaces API using the provider.
For example, there is no way to specify spaces in
juju_application
bindings. The only way I see to workaround this issue is to run the deployment with a bundle where I correctly specify spaces.The provider should also check at
add_space
if the subnets specified exist in juju'ssubnets
.Urgency
Casually reporting
Terraform Juju Provider version
edge
Terraform version
1.6.3
Terraform Configuration(s)
No response
Reproduce / Test
Debug/Panic Output
No response
Notes & References
No response