pulumi / pulumi-digitalocean

A DigitalOcean Pulumi resource package, providing multi-language access to DigitalOcean
Apache License 2.0
83 stars 13 forks source link

digitalocean: update on Domain ends in a Replace(!?) that ends in Error #311

Open cr1st1p opened 4 years ago

cr1st1p commented 4 years ago

I created a domain, like

const domain = new digitalocean.Domain(BASE_DOMAIN, {
    name: BASE_DOMAIN,
    ipAddress: "A.B.C.D"
});

Then, I removed that ipAdress line. Code shows that it wants to replace it ! +- └─ digitalocean:index:Domain my.domain.com replace [diff: -ipAddress] This seemed an error to me, but I said... ok, let's go on.

And since a replacement seems to be happening by creating first another record, of course(?) it fails:

error: Error creating Domain: POST https://api.digitalocean.com/v2/domains: 422 domain 'my.domain.com': name already exists

During my debugging - note that I actually wanted some IP to change, by creating a new droplet, I bumped into other strange things as well:

      ++digitalocean:index/domain:Domain: (create-replacement)
        [id=my.domain.com]
        [urn=urn:pulumi:do-prod::my-digitalocean::digitalocean:index/domain:Domain::my.domain.com]
        [provider=urn:pulumi:do-prod::my-digitalocean::pulumi:providers:digitalocean::default_1_8_0::XYZXYZXYZ-XYZZYXYZYZYZYZ]
      - ipAddress: "A.B.C.D"
    +-digitalocean:index/domain:Domain: (replace)
        [id=my.domain.com]
        [urn=urn:pulumi:do-prod::my-digitalocean::digitalocean:index/domain:Domain::my.domain.com]
        [provider=urn:pulumi:do-prod::my-digitalocean::pulumi:providers:digitalocean::default_1_8_0::XYZXYZXYZ-XYZZYXYZYZYZYZ]
      - ipAddress: "A.B.C.D"

Maybe I don't know how to read it, but at first look it seems as if tries to replace the record with ... a similarly changed one? (i.e. the 2 entries are really the same, even if I redacted sensitive info)

And, before that, when it had to just change ipAddress:

    ++digitalocean:index/domain:Domain: (create-replacement)
        [id=my.domain.com]
        [urn=urn:pulumi:do-prod::my-digitalocean::digitalocean:index/domain:Domain::my.domain.com]
        [provider=urn:pulumi:do-prod::my-digitalocean::pulumi:providers:digitalocean::default_1_8_0::XYZXYZXYZ-XYZZYXYZYZYZYZ]
      ~ ipAddress: "A.B.C.D" => "E.F.G.H"
    +-digitalocean:index/domain:Domain: (replace)
        [id=my.domain.com]
        [urn=urn:pulumi:do-prod::my-digitalocean::digitalocean:index/domain:Domain::my.domain.com]
        [provider=urn:pulumi:do-prod::my-digitalocean::pulumi:providers:digitalocean::default_1_8_0::XYZXYZXYZ-XYZZYXYZYZYZYZ]
      ~ ipAddress: "A.B.C.D" => "E.F.G.H"

Using Typescript, pulumi version v1.13.0

lukehoban commented 4 years ago

There are a few things here:

  1. Changing the ipAddress requires a replacement - that is presumably related to how DigitalOcean models this resource.
  2. The replacement creates before deleting, leading to a failure - Pulumi will always try to create before replacement to avoid downtime, but for some resources that is not possible as there is a scarce resource (like domain names) involved. You can use { deleteBeforeReplace: true } to opt-in to deleting first, which will lead to brief downtime.
  3. The --diff display shows both create-replacement and replace events (and also a delete-replacement though it looks like you didn't get to that part). This is indeed a little confusing, but is the current way this composite event is represented. We should consider supressing the plain replace event and just keeping the concrete sub-steps.
cr1st1p commented 4 years ago

Thank you for the suggestion with 'deleteBeforeReplace' - I ended using it to fix my situation.

I checked the DO API and I do not see indeed an 'update' on the domain record. On the other hand, I think code handling DO Domain could be better: because the 'ipAddress' field means to automatically create an A record, when changing ipAddress field on the Domain object, it should change that A record and leave the domain object untouched. Not tested: side effect of the current way of handling ipAddress updates, could be that ALL records for that domain would be deleted when the domain object is recreated. And maybe even if you are maintaining them with Pulumi, it might not detect this situation until a manually stack refresh.

Anyway, until (if!) something gets changed into the way DO Domain 'ipAddress' field is handled, I think that people should not use it and use their own separate A record. And maybe for safety, you could actually remove it from your modules :-)

Feel free to close the bug if you consider so.

Regards!

gustawdaniel commented 2 years ago

I am not satisfied with this solution. Can I check if the domain exists and in this case only change DNS in this domain?

mikhailshilkov commented 2 years ago

The --diff display shows both create-replacement and replace events (and also a delete-replacement though it looks like you didn't get to that part).

This is tracked in https://github.com/pulumi/pulumi/issues/8185

For the rest, I transferred the issue to pulumi-digitalocean to track here.