Skip to content

Ask AI

Ask anything about Destesi — setup, products, APIs.

Powered by Claude. Answers may be wrong — always verify against the docs.

Deploy concepts

Deploy is a prompt-driven deployment product. You describe what you want running in the cloud; Deploy translates that into real infrastructure using vetted building blocks, shows you the plan, and waits for your approval before applying anything. This page explains the model so you understand what happens at each stage.

Deploy does not generate arbitrary Terraform. A deployment is composed from modules — proven building blocks that are assembled into a single Terraform root. Two modules exist today:

  • web-service — a containerized web service on ECS Fargate behind an Application Load Balancer, with an ECR repository, CloudWatch logs, and scoped security groups. You control the container port, CPU, memory, and task count.
  • postgres — an RDS PostgreSQL instance in the same VPC. You control the engine version, instance class, storage, database name, and username.

Modules are joined by declared wiring rather than hand-edited configuration. The database_url wiring connects a Postgres module to a service: it injects a DATABASE_URL environment variable into the service and opens the database’s security group to the service’s tasks, in one step.

This constraint is a feature. A small set of well-tested modules is safer and more predictable than unconstrained generation, and it is why Deploy can honestly tell you what it is about to do. If your repo doesn’t fit any module, the deployment stops with a clear message rather than producing an incorrect or unsafe configuration.

Every deployment goes through two stages before cloud resources exist:

  1. Plan — Deploy runs terraform plan against the composed configuration. The plan output streams to your browser in real time, showing every resource that will be created, its type, name, and effect on your cloud account. No resources are created in this stage.

  2. Apply — nothing happens until you click Apply. You own this gate. If the plan looks wrong — wrong region, unexpected resource count, unfamiliar names — you can abandon the deployment without any cloud spend. Only after you approve does Deploy build your image and run terraform apply.

This gate is the central safety property of Deploy, and it is not skippable. Redeploys go through it. Chat-driven changes go through it. Overriding a readiness warning goes through it. The state the deployment parks in while it waits is called awaiting_apply, and it is the only state applying can be entered from.

A deployment moves through twelve states. A repo-sourced deployment walks the full path; one that carries a pre-built container image skips the stages that read or build source.

State What is happening
Pending Deployment created; the pipeline is starting up.
Fetching repo Deploy is pulling your repo’s source through your GitHub connection.
Analyzing The readiness analyzer reads the source tree — build target, container port, health-check path, infrastructure dependencies.
Needs config The analyzer found something that would block the deploy and is waiting on you.
Planning terraform plan is running; output streams to your browser.
Awaiting apply The plan is ready. Waiting for your Apply. Nothing has been created.
Building image Your repo is being built into a container image and pushed to ECR.
Applying terraform apply is running; resources are being created.
Live Deployment succeeded. Your service endpoint is available.
Destroying terraform destroy is running in response to your Destroy action.
Destroyed All resources have been torn down. Terminal.
Failed A step errored. The streamed log shows the cause. You can retry the plan or tear down.

Once a deployment is Live you have two actions:

  • Redeploy — re-analyze the current repo, re-compose the stack, re-plan, and park at the approval gate again. It never applies on its own, so a redeploy is always something you consciously approve.
  • Destroy — run terraform destroy to remove every resource the deployment created.

You don’t edit configuration files to change a running deployment’s shape — you talk to it. Inside a deployment, the chat pane accepts instructions like “add a database”, which appends a postgres module and the database_url wiring, or “remove the database”, which takes both back out.

The revised configuration is staged as a pending revision and the deployment returns to the plan. It never auto-applies. You review the new plan and approve it exactly as you did the first one.

Before planning, Deploy analyzes your repo and records a readiness report: what it found, and what would block a deploy. A missing container build target, an ambiguous port, configuration it could not infer — each becomes an item you can act on.

When the report contains a blocker, the deployment parks in needs_config rather than planning against a guess. You can fix the underlying issue, or you can override the report and proceed. Overriding skips the advice, never the approval — an overridden deployment still stops at awaiting_apply and still needs your Apply.

There is a second, broader readiness check at the workspace level, answering “can Deploy do its job at all yet?” It reports an AWS connection as required and a GitHub connection as advisory. Deploy is the sharpest case for this in the suite: without an AWS account connected in a different product, every action here would fail, and nothing on the screen would say why.

Deploy does not store any cloud provider credentials. All credential access — AWS, GitHub, and future providers — flows through Connect, Destesi’s third-party credential hub.

When you deploy, Deploy asks Connect for a scoped credential for your workspace’s AWS connection. If no AWS connection exists, the deployment fails immediately with a clear prompt to set one up. This means:

  • Your AWS keys are managed in one place (connect.destesi.io), not scattered across products.
  • Revoking or rotating your AWS credentials in Connect affects every Deploy deployment in that workspace at once.
  • Deploy can never access a cloud account you haven’t explicitly authorized in Connect.

See the Connect concepts doc for how credential storage and authorization work.

Environment configuration lives at the workspace level as app variables, so every deployment in the workspace resolves the same set when it applies. A variable you mark as a secret is masked on read — there is no reveal path — and delivered to your container as an SSM task secret rather than a plain environment entry.

Deploy uses Terraform remote state as the source of truth for the resources a deployment owns; the deployment record is the source of truth for its lifecycle. This has two practical consequences:

  • Destroy is complete. Terraform tracks every resource it created. Destroying a deployment removes all of them — ECR repository, Fargate service, load balancer, security groups, log group, and the RDS instance if one was composed in. There are no orphaned resources left in your cloud account.
  • Redeploy is safe to run repeatedly. If a redeploy plans the same configuration that is already applied, Terraform detects no drift and the plan makes no changes. You will still see the plan and still have to approve it.

If the Terraform state is somehow lost, Deploy treats that deployment as unrecoverable and requires a new deployment from scratch. It will never apply blindly without a plan.