Closed adriamanu closed 2 years ago
Hey @adriamanu! First of all, thanks for this nice report;)
If I understand correctly, you would like to manage with Terraform a resource (gandi_livedns_records
) that can also be updated manually.
I'm not sure this is a usecase supported by Terraform and it seems pretty hard to handle it properly (for instance, deleting the resource with Terraform would then not mean the whole resource has to be deleted...).
would it be possible to add gandi_livedns_records as a data source in terraform (in order to dynamically pull records that match name and type) ?
If your plan is to use a datasource to update some value of the resource, this could not work since each time you run Terraform apply
, you will add more value to the resource.
I'm actually wondering what is your usecase exactly. Could you provide more details (you could send me a mail if you don't want to talk about it publicly)?
Hello @nlewo !
Thank you for your reply, here is some more context :
We have a domain on Gandi, let's call it example.com.
We have quite a lot of records on it, some of them are managed by Terraform and some of them are "legacy" record that have been added manually in the past.
On AWS we are using SES (Simple Email Service) and in order to verify and be able to use the domain example.com i need to 4 add records to this domain.
3 records of type CNAME (i can easily create them with the gandi provider) and one of them is of type TXT and with name "_amazonses".
The issue is that we have "legacy" TXT records that are also named "_amazonses" so when i want to create my TXT record, i got a 409
error from the gandi provider / api because it seems to be already existing.
The provider is using a POST route from api https://dns.api.gandi.net/api/v5/domains/<domain>/records
(which seems totally fine and the way to do), so it won't work when you want to add a record with a name that is already existing.
But it's not the case while using the front-end client https://admin.gandi.net/domain/ .
The front-end client is using a PUT method which retrieves the list of records that have the same name, append the record that you want to add on this list, then do the PUT and that way the new TXT record that share the same name is created.
This is the behaviour that i would like to have from the provider.
I modified a bit the code of the provider locally to make it work as expected gandi/resource_livedns_record.go
func resourceLiveDNSRecordCreate(d *schema.ResourceData, meta interface{}) error {
zoneUUID := d.Get("zone").(string)
name := d.Get("name").(string)
recordType := d.Get("type").(string)
ttl := d.Get("ttl").(int)
valuesList := d.Get("values").(*schema.Set).List()
var values []string
for _, v := range valuesList {
values = append(values, v.(string))
}
client := meta.(*clients).LiveDNS
// Retrieve existing records in case new record is of type TXT
if recordType == "TXT" {
rec, err := client.GetDomainRecordByNameAndType(zoneUUID, name, recordType)
if err != nil {
return err
}
// Add new values to existing ones
values = append(values, rec.RrsetValues...)
_, err = client.UpdateDomainRecordByNameAndType(zoneUUID, name, recordType, ttl, values)
if err != nil {
return err
}
} else {
_, err := client.CreateDomainRecord(zoneUUID, name, recordType, ttl, values)
if err != nil {
return err
}
}
calculatedID := fmt.Sprintf("%s/%s/%s", zoneUUID, name, recordType)
d.SetId(calculatedID)
return resourceLiveDNSRecordRead(d, meta)
}
That way the record was well created by Terraform by using the PUT/Update route and there is only one record to manage on the terraform state so it's not mutable.
terraform state show gandi_livedns_record.amazonses_verification_record
resource "gandi_livedns_record" "amazonses_verification_record" {
href = "https://api.gandi.net/v5/livedns/domains/example.com/records/_amazonses/TXT"
id = "example.com/_amazonses/TXT"
name = "_amazonses"
ttl = 600
type = "TXT"
values = [
"<some_txt_value>",
]
zone = "example.com"
}
I do not know if it is clearer for you ?
If it is can you tell me what is your point of view about that and how can i contribute to that in any way:
gandi_livedns_record
for example gandi_livedns_existing_record or gandi_livedns_txt_record.@adriamanu I tried to get some ideas on the Terraform discourse but i didn't get any feedback:(
I do not know if it is clearer for you ?
Yes, it is.
So, think it's important to keep the current behavior: a record is full managed by this Terraform provider. To address your usecase, i would propose to add a new flag on the resource gandi_livedns_record
. When this flag is set, your implementation would be used instead of the current one.
This flag could be named mutable
.
mutable = true
, Terraform update the value list with values it manages and doesn't touch the other values.mutable =false
(the default), the current behavior is preserved.What do you think?
I don't really like the mutable
choice but i don't have any better idea:/ Any other idea for the name of this flag?
Thank you for asking on other forums, appreciate it ! 🙏🏼
Concerning the code of my use case, i thought it would have been better to have a dedicated resource on the provider.
That way it doesn't impact current users and don't modify the behaviour of resources created with gandi_livedns_record
.
Moreover, my use case is really specific to a TXT Type of dns record, it can be weird to have the mutable flag enabled with A or AAAA records type for example (creating a new resource : gandi_livedns_mutable_txt_record)
For the moment, i'm going to go for the mutable flag version (name is fine and clear enough in my opinion), do further testing on my side then submit the PR, so that we can see if it fit correctly.
Hello, We have few dns records of type TXT with the same name that were created by hand in the past. (for a mail service) New records are handled by terraform but we faced an issue while trying to add new TXT records that share the same name of existing records in the dns.
I've got an issue with the creation of a gandi_livedns_record of type TXT with a name that is already existing. I've got the same issue by directly using the api with a POST method so i think this is a normal behaviour of the gandi provider.
While using the Gandi front-end they allows to create multiple TXT records with the same name, and to do so they are using the PUT method of the API (they retrieve the new record from the form and append other existing records that share the same name).
Is it planned on your roadmap to handle that case ? Is it the intended behaviour ? Is it possible to add that feature to the provider ? If it is not possible, would it be possible to add gandi_livedns_records as a data source in terraform (in order to dynamically pull records that match name and type) ?
How did i solve the issue
To solve my issue i had to import the resource
terraform import gandi_livedns_record.<record_name> <domain>/<record_name>/TXT
Copy the values to terraform locals and provide them with my new record in order to be able to create resource with terraform. Having to retrieve those values and store them on locals made the job, however, if dns records are updated, we will have to do same process again etc, so this is not dynamic. What are your thoughts on that ?Thank you for the good work and have a good day !