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

Support Deployment Alias update without downtime #249

Open
jacobroschen opened this issue Dec 23, 2024 · 2 comments
Open

Support Deployment Alias update without downtime #249

jacobroschen opened this issue Dec 23, 2024 · 2 comments

Comments

@jacobroschen
Copy link

jacobroschen commented Dec 23, 2024

Description

My team is attempting to manually create a Deployment, then promote it to a specific domain using vercel_alias resource. The terraform code looks something like this.

# API that the UI is dependent on
resource "aws_ecs_service" "api" { }

resource "vercel_project" "ui" {
  name  = "ui"
  auto_assign_custom_domains = false
}

resource "vercel_project_domain" "ui_domain" {
  project_id = vercel_project.ui.id
  domain = "my-app-domain.example.com"
}

# Create the Vercel deployment, but do not assign the domain yet
resource "vercel_deployment" "ui" {
  project_id = vercel_project.ui.id
  files = data.vercel_project_directory.ui.files
  production  = true
}

resource "vercel_alias" "ui" {
  alias  = vercel_project_domain.ui_domain.domain
  deployment_id = vercel_deployment.ui.id
  # Wait to assign prod until downstream services are ready
  depends_on = [aws_ecs_service.api]
}

The resulting terraform plan looks like this.

Start Destroy: `vercel_alias.ui`
Start Change: `aws_ecs_service.api`
Start Change: `vercel_deployment.ui`
End Destroy: `vercel_alias.ui`
# some time...
End Change: `vercel_deployment.ui`
# some time...
End Change: `aws_ecs_service.api`
Start Create: `vercel_alias.ui`
End Create: `vercel_alias.ui`

The problem here is that by design terraform destroys resources in reverse order of their creation, which means that vercel_alias.ui will be destroyed before everything else, and the new alias will not be created until after all of it's dependencies have been updated. The end user will then see a 404: DEPLOYMENT_NOT_FOUND error if they attempt to load the specified domain between the start of the terraform run and the end of the terraform run.

Desired Outcome

The goal here is that we want to have zero-downtime deployments when assigning domains manually to a deployment.

Solutions Attempted

We tried updating the vercel_alias.ui resource lifecycle to only add the alias after the destroy

resource "vercel_alias" "ui" {
  # ...
  lifecycle {
    create_before_destroy = true
  }

This looked promising, as the alias was still active while waiting for all of vercel_alias.ui's dependencies to finish, it ended up destroying the alias completely, resulting in a 404: DEPLOYMENT_NOT_FOUND after terraform had finished applying changes.

Other thoughts

The create alias api is definitely strange, as there isn't a PATCH or PUT resource available for it. However, it does appear that the POST resource behaves very similar to an update.

Creates a new alias for the deployment with the given deployment ID. The authenticated user or team must own this deployment. If the desired alias is already assigned to another deployment, then it will be removed from the old deployment and assigned to the new one.

From my limited understanding of this repo & terraform providers, it looks like updating of aliases aren't supported. Could this be implemented using the POST alias endpoint? This would then allow terraform to update the resource in place in the correct order, without any downtime.

@dglsparsons
Copy link
Collaborator

Hey, thanks for raising this. It sounds like we need to support updating an alias in place, without destroying or re-creating it.

It looks like the API for creating an alias is an upsert API... so I think it might work, although I haven't experimented. If so, though, it could be as simple as just filling in the Update() method on the vercel_alias resource, and removing RequiresReplace on the deployment_id field.

I might not have time to get around to this especially soon, but if you're happy contributing, please feel free!

@Swahjak
Copy link

Swahjak commented Jan 27, 2025

Also looking for this feature with a very similar use case 👍

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

No branches or pull requests

3 participants