- Install mise: https://mise.jdx.dev/getting-started.html
After devcontainer changes, run Codespaces: Rebuild Container from the Command Palette.
Create local AWS env values (do not commit .env):
cp .env.example .envSet values in .env for your account/workspace:
AWS_PROFILEAWS_REGIONTF_STATE_BUCKETTF_STATE_PREFIXTF_STATE_ENV
Authenticate with AWS SSO:
Use device code flow in remote dev containers/Codespaces to avoid localhost callback issues.
aws configure sso --profile dev --use-device-code
aws sso login --profile dev --use-device-code
aws sts get-caller-identity --profile devTroubleshooting (Codespaces/dev container):
- If login tries to redirect to
127.0.0.1, re-run with--use-device-code. - If cached SSO/token data is stale, clear cache and sign in again:
rm -rf ~/.aws/sso/cache ~/.aws/cli/cache
aws sso login --profile dev --use-device-codemise.toml loads .env via _.file = ".env", so tasks pick up AWS_PROFILE/AWS_REGION automatically.
Add mise activation to bash so tools from mise.toml are available in every new terminal:
echo 'eval "$(mise activate bash)"' >> ~/.bashrc
source ~/.bashrcFrom this repository:
mise install
mise current
terraform version
aws --version
kubectl version --clientIf terraform is still not found, open a new terminal and run:
source ~/.bashrcInstall git hooks:
mise run pre-commit:installThis installs a mise-backed git hook so commits from VS Code Source Control and terminal both work.
Run hooks manually across all files:
mise run pre-commit:runOptional: create a local Python virtual environment (ignored by git):
mise run uv:venv
source .venv/bin/activateIf you have not set up your local AWS environment yet, follow Codespaces / AWS env setup above first.
For remote containers/Codespaces, use --use-device-code for SSO login and see the troubleshooting note above if auth fails.
Verify active AWS credentials/profile with the task in mise.toml:
mise run aws:whoamiOr run AWS CLI directly through mise without relying on shell activation:
mise exec aws-cli -- aws --version
mise exec aws-cli -- aws configureRun tasks defined in mise.toml:
mise run terraform:init
mise run terraform:plan
mise run terraform:apply
mise run terraform:destroy
mise run terraform:validate
mise run terraform:validate-ci
mise run terraform:fmt
mise run checkov:scan
mise run checkov:scan-all
mise run check
mise run check:ciTemplate baseline note:
infra/main.tfis intentionally minimal and does not create default AWS infrastructure.- Add your own resources or internal modules under
infra/andmodules/.
Checkov task behavior:
checkov:scan/checkov:sarif: blocking scans for owned code (excludesinfra/.external_modules).checkov:scan-all/checkov:sarif-all: advisory scans including downloaded community module code.
- Prefer fixing findings instead of suppressing checks.
- If suppression is required, scope it to specific check IDs and document rationale in the PR.
- Keep suppressions minimal, time-bound, and reviewed regularly.
- Checkov policy is configured in
.checkov.yml; TFLint policy is configured in.tflint.hcl.
infra/backend.tf uses an S3 backend with runtime backend config.
Set these GitHub repository or environment variables before running deploy/destroy workflows:
TF_STATE_BUCKET(required): S3 bucket name for Terraform state.TF_STATE_PREFIX(optional): Prefix under the bucket. Defaults to GitHub repository name.AWS_ROLE_TO_ASSUME(required): IAM role ARN for OIDC auth.
For this repository, set TF_STATE_BUCKET=tfstate-llewandowski.
Locking is configured with S3 native lockfiles (use_lockfile=true), so no DynamoDB table is required.
Bucket requirements (configure on the S3 bucket itself):
- Versioning enabled.
- Default encryption enabled (SSE-S3 or SSE-KMS).
State key path is set by prefix + workflow input environment:
<prefix>/dev/terraform.tfstate<prefix>/staging/terraform.tfstate<prefix>/prod/terraform.tfstate
Where <prefix> is TF_STATE_PREFIX if set, otherwise the GitHub repo name (for example terraform-eks).
For local mise run terraform:init:
- Init always configures the S3 backend.
- Defaults are set in
mise.toml(TF_STATE_BUCKET=tfstate-llewandowski,TF_STATE_PREFIX=terraform-labs,TF_STATE_ENV=dev). - Override
TF_STATE_PREFIXorTF_STATE_ENVper workspace/environment as needed.
Use the bootstrap script to configure AWS OIDC trust + GitHub environments/variables for a new repository created from this template.
./scripts/bootstrap-template-repo.sh \
--repo <owner/new-repo> \
--aws-profile dev \
--state-bucket tfstate-llewandowskiDefaults:
- Role name:
GitHubActionsTerraformDeploy - Region:
us-east-1 - State prefix: repository name
After bootstrap, run the Deploy (Terraform Apply) workflow manually with environment=dev and confirm=APPLY.
Re-enable these rules in .tflint.hcl when the scaffold grows into real infrastructure:
terraform_unused_declarations: re-enable once locals/variables are actively consumed by resources or modules.terraform_unused_required_providers: re-enable oncerequired_providersonly lists providers used in code.- Run
mise run checkafter re-enabling to verify no regressions.