Using AWS as Terraform Backend
Terraform is great at provisioning cloud infrastructure. Terraform needs to keep the current state somewhere. Local filesystem can be used in many cases, but not ideal if there are multiple people sharing this state file. In case of AWS, we usually wants to keep it in AWS itself.
We can actually use terraform to provision these. I do find a simple copy and paste one-time run bash script sufficient for this case. This way, we do not need to maintain two sets of terraform scripts.
Download and Configure AWS CLI
brew install awscliThen create a profile with keys
$ aws configure --profile myprofile
AWS Access Key ID [None]: <key>
AWS Secret Access Key [None]: <value>
Default region name [None]: <region or leave none>
Default output format [None]: yamlCreate S3 Bucket
It is recommended to turn on bucket versioning so the history of states is preserved.
$ aws s3 mb s3://<project>-tfstate \
  --profile myprofile \
  --region us-west-2
$ aws s3api put-public-access-block \
  --bucket <project>-tfstate \
  --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true" \
  --profile myprofile \
  --region us-west-2
$ aws s3api put-bucket-versioning \
  --bucket <project>-tfstate \
  --versioning-configuration "Status=Enabled" \
  --profile myprofile \
  --region us-west-2
Create DynamoDB Table
While terraform uses S3 to store the actual state, it needs some locking mechanism that S3 does not provide. This is done via DynamoDB. The table must have a primary key named LockID as a string. 
aws dynamodb create-table \
  --table-name <project>-tfstate \
  --attribute-definitions AttributeName=LockID,AttributeType=S \
  --key-schema AttributeName=LockID,KeyType=HASH \
  --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
  --profile myprofile \
  --region us-west-2Use the Backend in Terraform
Now we can configure S3 (and DynamoDB) as our backend in main.tf
terraform {
  backend "s3" {
    bucket = "<project>-tfstate"
    key    = "terraform.tfstate"
    dynamodb_table = "<project>-tfstate"
    encrypt = true
    region = "us-west-2"
    profile = "myprofile"
  }
}References
- https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html#cli-quick-configuration
 - https://docs.aws.amazon.com/cli/latest/reference/s3api/create-bucket.html
 - https://docs.aws.amazon.com/cli/latest/reference/s3api/put-public-access-block.html
 - https://docs.aws.amazon.com/cli/latest/reference/dynamodb/create-table.html
 - https://www.terraform.io/docs/backends/types/s3.html