Overview
The starter kit supports multiple isolated environments (staging, production, etc.) with independent state management and deployment workflows. Each environment lives in its own directory under environments/.
Note: All environment files and GitHub Actions workflows are automatically generated by the
make setupcommand. See the Install guide.
Environment structure
Each environment directory contains:
environments/
└── staging/
├── backend.tf # Terraform and S3 backend configuration
├── main.tf # Provider and module configuration
├── variables.tf # Input variable definitions
├── outputs.tf # Output values from the OIDC module
└── terraform.tfvars # Variable values for OIDC configuration
backend.tf
Configures Terraform version, required providers, and S3 backend:
terraform {
required_version = ">= 1.10"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "terraform-state-123456789012-eu-west-1"
key = "environments/staging/terraform.tfstate"
region = "eu-west-1"
encrypt = true
use_lockfile = true
}
}
Key features:
- State encryption -
encrypt = trueenables AES-256 server-side encryption - Native state locking -
use_lockfile = trueenables Terraform 1.10+ locking with.tflockfiles (see Terraform S3 Backend docs) - Unique state key - Each environment uses its own path
main.tf
Configures the AWS provider and calls the OIDC module:
provider "aws" {
region = var.aws_region
default_tags {
tags = {
Environment = "staging"
ManagedBy = "terraform"
Repository = "your-org/your-repo"
}
}
}
module "oidc_provider" {
source = "../../modules/oidc-provider"
use_existing_oidc_provider = var.use_existing_oidc_provider
github_repo = var.github_repo
role_name = var.role_name
managed_policy_arns = var.managed_policy_arns
}
Key features:
- Default tags - Automatically applied to all resources
- Module-based - Uses the
oidc-providermodule frommodules/ - Configurable OIDC - Can create or reuse existing OIDC providers
variables.tf
Defines all input variables with defaults:
variable "aws_region" {
description = "AWS region for resources"
type = string
default = "eu-west-1"
}
variable "use_existing_oidc_provider" {
description = "Whether to use an existing OIDC provider"
type = bool
default = true
}
variable "github_repo" {
description = "GitHub repository name (format: owner/repo)"
type = string
default = "your-org/your-repo"
}
variable "role_name" {
description = "Name of the IAM role for GitHub Actions"
type = string
default = "GitHubActionsServiceRole-Terraform"
}
variable "managed_policy_arns" {
description = "List of IAM policy ARNs to attach"
type = list(string)
default = [
"arn:aws:iam::aws:policy/AdministratorAccess"
]
}
| Variable | Description |
|---|---|
aws_region | AWS region for deploying resources |
use_existing_oidc_provider | Set true for multiple environments in same account |
github_repo | Your GitHub repository in owner/repo format |
role_name | IAM role name for GitHub Actions |
managed_policy_arns | AWS managed policies attached to the role |
outputs.tf
Exports values from the OIDC module:
output "oidc_provider_arn" {
description = "ARN of the GitHub OIDC provider"
value = module.oidc_provider.oidc_provider_arn
}
output "role_arn" {
description = "ARN of the GitHub Actions IAM role"
value = module.oidc_provider.role_arn
}
output "role_name" {
description = "Name of the GitHub Actions IAM role"
value = module.oidc_provider.role_name
}
Adding a new environment
Use the setup wizard:
make setup
The wizard:
- Detects existing backend (reuses S3 bucket)
- Prompts for environment name
- Generates all necessary files
- Checks for existing OIDC provider
- Deploys OIDC infrastructure
- Displays IAM role ARN
Multi-account setup: Switch AWS credentials before running make setup:
assume production-account
make setup # Select: production
See Install for detailed setup options.
Multi-account vs. single-account
Single-account deployment
When deploying multiple environments to the same AWS account, the OIDC provider can only exist once:
- First environment:
use_existing_oidc_provider = false - Additional environments:
use_existing_oidc_provider = true
Multi-account deployment
When deploying to separate AWS accounts, each account needs its own OIDC provider:
- Each environment:
use_existing_oidc_provider = false
This provides complete isolation with separate IAM configurations.
Default tags
The default_tags block applies tags to all resources:
default_tags {
tags = {
Environment = "staging"
ManagedBy = "terraform"
Repository = "your-org/your-repo"
}
}
No need to repeat tag blocks on individual resources.
IAM role permissions
The managed_policy_arns variable controls GitHub Actions permissions:
managed_policy_arns = [
"arn:aws:iam::aws:policy/AdministratorAccess"
]
For production, consider more restrictive policies based on your infrastructure needs.
Next steps
- Project Structure - Repository layout
- CI/CD Workflows - Deployment automation
- OIDC Provider - Module implementation