Environments
Thin, canonical deployable roots under env/ that compose reusable modules for a concrete deployment target and run without ad hoc parameters.
- Kind
- Architecture
- Domain
- Infrastructure & Runtime
- Applies at
env/- Status
- Stable
- Source · managed
env/README.md
01 Defines
The directory of canonical deployment targets: one readable root per logical deployed unit and tier, wiring reusable modules to the configuration that a specific continuous-deployment target needs.
02 Applies when
- A repository deploys something — a website, a service, a secrets system — through continuous deployment.
- The same deployed unit exists in more than one tier or variant, such as production, non-production, or a pull request deployment.
- A generic deployment system needs to find and run a root using only repository conventions.
03 Boundaries
- Reusable infrastructure lives in modules, not in environment roots.
- Developer-oriented and user-derived deployments live in
workspaces/. - Shared infrastructure such as VPCs and DNS zones may be referenced but is owned here only if this repository deploys it.
Expected behaviour
- 01Each root is a thin entry point that composes modules and supplies target-specific configuration.
- 02Roots are organised by logical deployed unit and then by environment tier or variant.
- 03Every root can be executed by a generic deployer without deployment-specific parameters passed by hand.
- 04Provider lock files are committed for deployable Terraform roots.
- 05State files, local variable files, provider plugin directories, and local cache output are never committed.
Behaviour#
env/ answers the question “what can be deployed?”. Each directory beneath it
is a root that a deployment system can point at and run, and each one stands
for a real target — production, a non-production tier, a variant. Reading the
tree tells you the full set of canonical deployments without opening any file.
A root is wiring, not implementation. It names a module, supplies a domain, a backend, and credentials, and exposes the outputs a deployer needs. The infrastructure pattern itself lives in a module, local or published, so the same pattern can back every tier. See Pinned Module Composition .
Terraform is the primary format, but the directory is not limited to it. Any deployment definition that the repository’s orchestration can execute as a root belongs here.
Layout#
- env/
- prod/ Environment tier
- release/ Logical deployed unit: the website Pinned Module Composition
- .terraform.lock.hcl Committed provider lock file
- backend.tf Committed S3 backend; the root owns its state
- main.tf Locals and one module block Modules
- outputs.tf Values the deployer reads after apply
- providers.tf Named AWS profiles and regions
- versions.tf Terraform and provider constraints
Environments and workspaces#
env/
- Canonical continuous-deployment targets
- Fully parameterless under the deployer
- One root per deployed unit and tier
- State owned directly by the root
workspaces/
- Development, testing, and validation copies
- Identity may come from developer context
- One root per system, many instances
- One state object per Terraform workspace
The split keeps env/ strict without making developer systems awkward: anything
that needs the current user or branch to decide its identity moves to
Workspaces
, and env/ stays
Parameterless Deployment
.
Examples#
The production root is a handful of locals and a single module block:
locals {
site_domain = "sampletest.dev.prosyon.ca"
tags = {
Environment = "production"
Project = "static-website"
ManagedBy = "terraform"
}
}
module "this" {
source = "registry.forge.prosyon.ca/patterned-designs/hcl-aws-cloudfront-s3-static-website-xam--variant-shared/aws"
providers = {
aws = aws
aws.us_east_1 = aws.us_east_1
aws.dns = aws.dns
}
domain = local.site_domain
}
Its outputs are exactly what the deployer needs to finish the job:
# The three values scripts/deploy.sh needs to upload the site and refresh the CDN.
output "bucket_name" {
value = module.this.bucket_name
}
output "cloudfront_distribution_id" {
value = module.this.cloudfront_distribution_id
}
output "site_url" {
value = "https://${local.site_domain}"
}
Connections