Rolling deployments

This documentation was generated with the assistance of AI. Please report any inaccuracies.

By default a Spring Boot service generated by iru-setup-java-springboot deploys with one deploy.yml job: build the image, tofu apply, health-check. Rolling deployments are an opt-in alternative that turns every deployment into a staged rollout. The new version ("green") is deployed at 0 % traffic, smoke-tested on a candidate URL, shifted in steps, and the old version ("blue") is kept until the rollout completes so it can be restored.

Enabling it

  • At repository setup, iru-setup-java-springboot asks "Support blue/green rolling deployments?" (Step 3c), but only when CI is on: the workflows drive the rollout, so ci: no skips the question. The front door (iru-setup-repository) does not ask; it forwards rolling-deployments, deployment-strategy and advance when they are supplied as args.

  • On an existing repository run /iru-springboot-rolling-deployments enable (or disable).

  • The choice is recorded in springboot-stack.yml; absent means disabled and the generated files are unchanged:

deploy:
  rolling:
    enabled: true
    strategy: canary      # rolling | blue-green | canary | linear
    advance: hybrid       # auto | manual | hybrid
    steps: [10, 50, 100]
    bakeMinutes: 10

Strategies

Strategy Behaviour

blue-green

One cutover from 0 % to 100 % (steps: [100]).

canary

Gradual shift through steps (default 10, 50, 100 %), with a soak of bakeMinutes between steps.

linear

Equal-sized steps at a fixed interval.

rolling

The runtime’s native in-place rolling update: no second environment and no traffic split. advance is limited to auto, rollback is weaker, and the single-job deploy.yml is kept (with a wait-for-stable step). No promote.yml is generated.

Advance modes

auto

A metric gate (see below) decides every step. A breach rolls back automatically to 100 % blue.

manual

The run ends once green is deployed, and its summary shows the candidate URL. A person runs promote.yml for every step.

hybrid (recommended)

The metric gate must pass first, then a person confirms through promote.yml on prod. On dev it advances automatically. A failing gate still rolls back automatically.

Signalling "this step is safe": promote.yml

promote.yml is a workflow_dispatch workflow. Its inputs are the environment and a target: the next step, a specific percentage, rollback or abort. It shares the deploy-<environment> concurrency group with deploy.yml and undeploy.yml, so a promotion can never overlap a deployment.

It is stateless: it reads the current split from the cloud (ALB listener weights, Cloud Run traffic, Argo Rollout status), validates the metric gate for auto and hybrid, refuses to skip past the configured steps, finalises at 100 % (the old revision is scaled down or the Rollout fully promoted), and writes the result to the job summary. No runner is held open between steps.

GitHub Environment required reviewers are deliberately not the mechanism: on private repositories they need GitHub Enterprise, whereas promote.yml works on every plan. The consequence is that anyone with repository write access can dispatch it. Restrict this with a deployment-branch rule on prod, a ruleset, or, on private Enterprise repositories, an Environment with reviewers.

Per-runtime behaviour

Runtime Shifting Candidate URL Metric gate

ECS Fargate

Weighted blue/green target groups on the ALB listener (an ALB is required)

ALB test listener

CloudWatch alarms (5xx rate, p95 latency, unhealthy hosts)

Cloud Run

--no-traffic revision, tag, gcloud run services update-traffic

Revision tag URL

Cloud Monitoring query

EKS / GKE Autopilot

Argo Rollouts Rollout (promote, abort)

Preview Service

AnalysisTemplate on Prometheus

The workflow drives the shifting uniformly on every runtime. ECS’s native blue/green deployments (lifecycle hooks, alarm rollback) are the documented alternative for advance: auto only; they are not generated. Flagger is the documented alternative to Argo Rollouts and is not generated either.

OpenTofu exposes rollout_candidate_url, rollout_gate, rollout_alarm_names, rollout_target_groups and rollout_name per environment for the workflows to consume. Extra repository variables are ECS_CLUSTER, ECS_SERVICE, CLOUD_RUN_SERVICE, EKS_CLUSTER_NAME or GKE_CLUSTER_NAME, and K8S_NAMESPACE.

Rollback

A failed gate, promote.yml with rollback, or abort restores 100 % to the blue version, which is still running. undeploy.yml resets the split to the stable revision before stopping or destroying. With the rolling strategy the runtime’s native rollback applies, which is weaker because the old instances are replaced in place.

Cost

Blue/green temporarily doubles capacity while both versions run, and the extra load balancer resources, alarms and Argo Rollouts controller cost money. Thresholds for the alarms and queries need tuning per service.

Disabling

/iru-springboot-rolling-deployments disable refuses while a rollout is in progress (the cloud split is not 100 % on one version). It then restores the single-job deploy.yml and removes promote.yml after confirmation. The rollout infrastructure stays in infra/ until you review a tofu plan and apply it yourself: the skill never runs tofu apply or tofu destroy.