Skip to content

Instantly share code, notes, and snippets.

@garretfick
Last active October 1, 2020 12:38
Show Gist options
  • Save garretfick/07bb65d39fce2ede090333c67dd1fa3c to your computer and use it in GitHub Desktop.
Save garretfick/07bb65d39fce2ede090333c67dd1fa3c to your computer and use it in GitHub Desktop.
Terraform Configuration for Heroku/S3 Application
# This terraform configuration generates a Heroku PHP application
# using the Heroku postgress database addon and creates an AWS S3
# bucket to host static files for the application.
# The site is sufficiently simple that this configuation is
# contained in a single file
# The build creates environment variables in the Heroku application
# containing the credentials for the S3 bucket.
# Authentication for the AWS provider - we use this access
# key in order to be able to create a new AWS user and the S3
# bucket that the application needs.
variable "aws_access_key_id" {}
variable "aws_access_secret_key" {}
variable "aws_region" {
default = "us-west-1"
}
# Authentication for the Heroku provider - we use this access
# key in order to be able to create a new Heroku application
# and provision the addon
variable "heroku_email" {}
variable "heroku_api_key" {}
# Application environment - usually something like 'staging' or 'prod'
# We use this to label items and generate names
variable "app_environment" {}
# Heroku app settings
# This is the name of the Heroku application that we will create
# This needs to be unique (no to accounts can have the same name)
variable "heroku_app_name" {}
variable "heroku_app_region" {
default = "us"
}
# The application needs to provision a database. This the plan level
# for the basic Heroku Postgress database
variable "heroku_db_plan" {
default = "heroku-postgresql:hobby-basic"
}
# AWS and S3 settings - these define the details of the S3 bucket that we will create
# The credentials to access the bucket are created automatically by terraform
variable "filesystem_s3_user_name" {}
variable "filesystems_s3_bucket" {}
variable "filesystems_s3_region" {
default = "us-west-2"
}
variable "resource_tag_name" {}
# We need the Heroku provider in order to create the Heroku application
provider "heroku" {
email = "${var.heroku_email}"
api_key = "${var.heroku_api_key}"
}
# We need the AWS provider in order to create the S3 bucket
provider "aws" {
access_key = "${var.aws_access_key_id}"
secret_key = "${var.aws_access_secret_key}"
region = "${var.aws_region}"
}
# Creates the IAM key for write access to the S3 bucket
# We need to create the IAM users, give that user an access
# key, and finally give that user write access to the bucket
# with a policy
resource "aws_iam_user" "iam_user_s3_rw" {
name = "${var.filesystem_s3_user_name}"
# You cannot tag a user, but you can give them a path
# to help identify the context of the user
path = "/${var.resource_tag_name}/"
}
# Creates the API key for the user
resource "aws_iam_access_key" "s3_rw" {
user = "${aws_iam_user.iam_user_s3_rw.name}"
}
# Restricts the user to only the S3 bucket they should
# have access to
resource "aws_iam_user_policy" "policy_s3_rw" {
# We concatenate the user name with the policy to ensure that
# the policy name is unique, but still recognizable
name = "${aws_iam_user.iam_user_s3_rw.name}-policy"
user = "${aws_iam_user.iam_user_s3_rw.name}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": "arn:aws:s3::::${var.filesystems_s3_bucket}"
}
]
}
EOF
}
resource "aws_s3_bucket" "aws_bucket_static" {
bucket = "${var.filesystems_s3_bucket}"
acl = "private"
tags {
Name = "${var.resource_tag_name}"
Environment = "${var.app_environment}"
}
acl = "public-read"
cors_rule {
allowed_origins = ["*"]
allowed_methods = ["GET"]
max_age_seconds = 3000
allowed_headers = ["*"]
}
}
# Creates the primary Heroku application.
resource "heroku_app" "default" {
name = "${var.heroku_app_name}"
region = "${var.heroku_app_region}"
# We do need a URL for the database, but we don't
# need to create it because provisioning the
# addon automatically created this config var
config_vars = {
FILESYSTEMS_DEFAULT = "${var.filesystems_default}"
FILESYSTEMS_S3_KEY = "${aws_iam_access_key.s3_rw.id}"
FILESYSTEMS_S3_BUCKET = "${var.filesystems_s3_bucket}"
FILESYSTEMS_S3_REGION = "${var.filesystems_s3_region}"
FILESYSTEMS_S3_SECRET = "${aws_iam_access_key.s3_rw.secret}"
}
}
# Create the Heroku Postgress addon for the application
resource "heroku_addon" "database" {
app = "${heroku_app.default.name}"
plan = "${var.heroku_db_plan}"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment