diff --git a/terraform/README.md b/terraform/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a9cfef57b27a5a4cf3f793725a2c4124efb5fb4b
--- /dev/null
+++ b/terraform/README.md
@@ -0,0 +1,31 @@
+# Terraform modules
+
+This directory contains Terraform modules and a library of reusable modules
+under `library`. Each module deploys a complete service. Although services will
+be interconnected and there will be dependencies between services, the goal is
+to keep the modules whole so that applying the module deploys the entire
+service.
+
+## A word on environments
+
+Each module has a Terraform variables files (`.tfvars`) and a workspace for each
+environment that service is deployed to. This puts the emphasis on keeping the
+services the same across different environments with little changes, mainly for
+scale (eg. 2 instances instead of 5).
+
+## Common workflow
+
+In this example, deploying to the dev environment. A convention is used for the
+default workflow (have it be prod or dev or just not used).
+
+```
+terraform init
+terraform workspace new dev
+# Or if the workspace is already present:
+terraform workspace select dev
+terraform plan -var-file=dev.tfvars -out=tfplan
+# Review the changes to be applied.
+terraform apply tfplan
+```
+
+## Some more information here (like different providers, other conventions)
diff --git a/terraform/foo/dev.tf b/terraform/foo/dev.tf
new file mode 100644
index 0000000000000000000000000000000000000000..7407b8789e309232c05f38e07371a7edf3de7ebe
--- /dev/null
+++ b/terraform/foo/dev.tf
@@ -0,0 +1 @@
+instance_count = 2
diff --git a/terraform/foo/main.tf b/terraform/foo/main.tf
new file mode 100644
index 0000000000000000000000000000000000000000..4e39eee4fd02efb8e05ca55e6cbbce811e1a802e
--- /dev/null
+++ b/terraform/foo/main.tf
@@ -0,0 +1,14 @@
+terraform {
+  backend "s3" {
+    bucket         = "tf-states"
+    key            = "foo.tfstate"
+    region         = "us-east-1"
+    encrypt        = true
+    dynamodb_table = "tf-locks"
+  }
+}
+
+locals {
+  env    = terraform.workspace == "default" ? "prod" : terraform.workspace
+  module = basename(abspath(path.root))
+}
diff --git a/terraform/foo/outputs.tf b/terraform/foo/outputs.tf
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/terraform/foo/providers.tf b/terraform/foo/providers.tf
new file mode 100644
index 0000000000000000000000000000000000000000..4a0d4ace9f33dea90c760e4ca1708eb410456973
--- /dev/null
+++ b/terraform/foo/providers.tf
@@ -0,0 +1,9 @@
+provider "aws" {
+  default_tags {
+    tags = {
+      Environment = local.env
+      # Easy to track down which module created a resource.
+      Module      = local.module
+    }
+  }
+}
diff --git a/terraform/foo/staging.tf b/terraform/foo/staging.tf
new file mode 100644
index 0000000000000000000000000000000000000000..3b1241f575f3521ac607531eea3c2dace6aa952e
--- /dev/null
+++ b/terraform/foo/staging.tf
@@ -0,0 +1 @@
+instance_count = 3
diff --git a/terraform/foo/variables.tf b/terraform/foo/variables.tf
new file mode 100644
index 0000000000000000000000000000000000000000..9121b154a20c862b170af10765d42680ba6520da
--- /dev/null
+++ b/terraform/foo/variables.tf
@@ -0,0 +1,7 @@
+variable "instance_count" {
+  type        = number
+  description = "The number of instances to deploy."
+  # If the convention is not to use the default workspace, delete the default
+  # value.
+  default     = 5
+}
diff --git a/terraform/library/README.md b/terraform/library/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..77ff62b844b307f961dc6006d5f34d53df696ec9
--- /dev/null
+++ b/terraform/library/README.md
@@ -0,0 +1,3 @@
+# Terraform module library
+
+A library of reusable modules (not to deployed by themselves).
diff --git a/terraform/library/aws/asg/README.md b/terraform/library/aws/asg/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..1bbab2490eff6a3f414273fa9ded07d519be302e
--- /dev/null
+++ b/terraform/library/aws/asg/README.md
@@ -0,0 +1 @@
+# Auto scaling group
diff --git a/terraform/library/aws/asg/main.tf b/terraform/library/aws/asg/main.tf
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/terraform/library/aws/asg/outputs.tf b/terraform/library/aws/asg/outputs.tf
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/terraform/library/aws/asg/variables.tf b/terraform/library/aws/asg/variables.tf
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391