terraform-provider-incus
terraform-provider-incus copied to clipboard
Implement an `incus_image_alias` resource
We currently don't seem to have a way to create and manage image aliases through the provider.
Hi @stgraber , long time no see. I would like to take on this task. Could you assign it to me?
Nice to see you again!
Hello @stgraber, I apologize for the lack of progress on this issue. I just returned from vacation and will be submitting the PR this weekend. Thank you for your patience!
No worries at all!
@stgraber cc @maveonair Hi there,
I'm currently working on acceptance tests for the incus_image_alias resource and have encountered a state drift issue related to the aliases field in the incus_image resource.
The Problem:
The incus_image resource allows specifying aliases directly (as a list).
At the same time, we also have the incus_image_alias resource for managing aliases individually.
During acceptance tests, after applying both resources, a terraform refresh detects a difference and forces a replacement of both resources.
This happens because the aliases assigned via incus_image_alias are not reflected in the Read function of incus_image, since the alias is added after the image is pulled and the image state is already persisted.
Example
resource "incus_image" "img" {
source {
remote = "images"
alias = "alpine/edge"
}
aliases = ["alpine-test"] # <- causes drift
}
resource "incus_image_alias" "img" {
name = "alpine-test"
fingerprint = incus_image.img.fingerprint
}
Proposed Solution
I propose removing the aliases field from incus_image entirely and relying solely on incus_image_alias for alias management. This avoids overlapping responsibilities and eliminates state drift during testing and usage.
Would you recommend removing the aliases field from incus_image to avoid this conflict, or do you see value in keeping both?
Does that also happens when you do it like this:
resource "incus_image" "img" {
source {
remote = "images"
alias = "alpine/edge"
}
aliases = [incus_image_alias.img.name]
}
resource "incus_image_alias" "img" {
name = "alpine-test"
fingerprint = incus_image.img.fingerprint
}
Hi, @maveonair,
Thank you for providing the configuration file! However, I've encountered a new cycle reference issue:
root@lima-incus:~/tf# cat main.tf
terraform {
required_providers {
incus = {
source = "lxc/incus"
}
}
}
resource "incus_image" "img" {
source_image = {
remote = "images"
name = "alpine/edge"
}
aliases = [incus_image_alias.img.alias]
}
resource "incus_image_alias" "img" {
alias = "alpine"
description = "Alpine Edge"
fingerprint = incus_image.img.fingerprint
}
output "alias" {
value = incus_image_alias.img.alias
}
root@lima-incus:~/tf# terraform plan
╷
│ Warning: Provider development overrides are in effect
│
│ The following provider development overrides are set in the CLI configuration:
│ - lxc/incus in /root/terraform-provider-incus
│
│ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases.
╵
╷
│ Error: Cycle: incus_image_alias.img, incus_image.img
│
│
╵
In this configuration, the aliases = [incus_image_alias.img.alias] syntax creates a circular dependency because incus_image depends on incus_image_alias, while incus_image_alias depends on incus_image.
Should the aliases parameter use a direct string value like aliases = ["alpine"] instead?
I believe we should revise our approach to defining aliases. Otherwise, we won’t be able to break the circular dependency.
I’m curious to hear your thoughts on this alternative syntax:
resource "incus_image" "img" {
source_image = {
remote = "images"
name = "alpine/edge"
}
alias {
name = "alpine"
description = "Alpine Linux"
}
alias {
name = "alpine-edge"
description = "Alpine Linux Edge"
}
}
By keeping everything within the image resource, we can ensure the correct modification order for aliases.
@stgraber does that sound like a good idea?
Ah yeah, that'd be fine with me
Thanks @maveonair and @stgraber! I'll work on updating the PR over the weekend to implement alias as nested configuration blocks within the image resource.