Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrated terraform outputs in frontend code-gen #75

Merged
merged 11 commits into from
Nov 12, 2019
7 changes: 6 additions & 1 deletion internal/config/config.go
Expand Up @@ -78,6 +78,7 @@ type aws struct {
Region string
EKS eks
Cognito cognito
S3Hosting s3Hosting `yaml:"s3_hosting"`
Terraform terraform
}

Expand All @@ -86,7 +87,11 @@ type terraform struct {
}

type cognito struct {
Deploy bool
Deploy bool
}

type s3Hosting struct {
Deploy bool
}

type eks struct {
Expand Down
27 changes: 26 additions & 1 deletion templates/ci/github.tmpl
Expand Up @@ -26,4 +26,29 @@ jobs:
uses: actions/upload-artifact@v1
with:
name: build
path: build
path: build

publish:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
with:
fetch-depth: 1

- name: Download build artifacts
uses: actions/download-artifact@v1
with:
name: build

# https://github.com/opspresso/action-s3-sync
- name: Publish to AWS S3
uses: opspresso/action-s3-sync@master
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: "<% .Config.AWS.Region %>"
FROM_PATH: "./build"
DEST_PATH: "s3://<% .Config.Frontend.App.Name %>"
OPTIONS: "--acl public-read"
2 changes: 2 additions & 0 deletions templates/commit0/commit0.tmpl
Expand Up @@ -16,6 +16,8 @@ infrastructure:
deploy: true
cognito:
deploy: true
s3_hosting
deploy: true

frontend:
framework: {{.FrontendFramework}}
Expand Down
52 changes: 0 additions & 52 deletions templates/react/.github/workflows/deploy.yml

This file was deleted.

2 changes: 2 additions & 0 deletions templates/terraform/environments/development/main.tf
Expand Up @@ -34,4 +34,6 @@ module "development" {

# Client configuration
user_pool = "{{ .Config.Name }}-development"
s3_hosting_bucket_name = "{{ .Config.Name }}-development"

}
2 changes: 2 additions & 0 deletions templates/terraform/environments/production/main.tf
Expand Up @@ -34,4 +34,6 @@ module "production" {

# Client configuration
user_pool = "{{ .Config.Name }}-production"
s3_hosting_bucket_name = "{{ .Config.Name }}-production"

}
1 change: 1 addition & 0 deletions templates/terraform/environments/staging/main.tf
Expand Up @@ -34,4 +34,5 @@ module "staging" {

# Client configuration
user_pool = "{{ .Config.Name }}-staging"
s3_hosting_bucket_name = "{{ .Config.Name }}-staging"
}
40 changes: 40 additions & 0 deletions templates/terraform/modules/cognito/main.tf
@@ -0,0 +1,40 @@
resource "aws_cognito_user_pool" "users" {
name = "${var.user_pool}-user-pool"

username_attributes = [
"email",
]

# auto_verified_attributes = ["email"]
}

resource "aws_cognito_user_pool_client" "client" {
name = "${var.user_pool}-cognito-client"

user_pool_id = "${aws_cognito_user_pool.users.id}"
generate_secret = false

allowed_oauth_flows_user_pool_client = true
allowed_oauth_flows = ["code", "implicit"]
allowed_oauth_scopes = ["profile", "openid"]

supported_identity_providers = ["COGNITO"]
refresh_token_validity = "14"

explicit_auth_flows = [
"ADMIN_NO_SRP_AUTH",
"USER_PASSWORD_AUTH",
]

write_attributes = ["email"]

callback_urls = ["https://auth.${var.hostname}","https://auth.${var.hostname}/oauth2/idpresponse"]
logout_urls = ["https://auth.${var.hostname}/logout"]
}

output "cognito_pool_id" {
value = "${aws_cognito_user_pool.users.id}"
}
output "cognito_client_id" {
value = "${aws_cognito_user_pool_client.client.id}"
}
7 changes: 7 additions & 0 deletions templates/terraform/modules/cognito/variables.tf
@@ -0,0 +1,7 @@
variable "user_pool" {
description = "AWS Cognito pool name"
}
variable "hostname" {
default = "{{ .Config.Frontend.Hostname }}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be a default, it should be passed in from where the module is being used.

description = "AWS Cognito pool name"
}
46 changes: 7 additions & 39 deletions templates/terraform/modules/environment/main.tf
Expand Up @@ -43,47 +43,15 @@ module "kube2iam" {
iam_account_id = data.aws_caller_identity.current.account_id
}

# @TODO - Move this to a different file

# {{ if .Config.Infrastructure.AWS.Cognito.Deploy }}
resource "aws_cognito_user_pool" "users" {
name = "${var.user_pool}-user-pool"

username_attributes = [
"email",
]

# auto_verified_attributes = ["email"]
}

resource "aws_cognito_user_pool_client" "client" {
name = "${var.user_pool}-cognito-client"

user_pool_id = "${aws_cognito_user_pool.users.id}"
generate_secret = false

allowed_oauth_flows_user_pool_client = true
allowed_oauth_flows = ["code", "implicit"]
allowed_oauth_scopes = ["profile", "openid"]

supported_identity_providers = ["COGNITO"]
refresh_token_validity = "14"

explicit_auth_flows = [
"ADMIN_NO_SRP_AUTH",
"USER_PASSWORD_AUTH",
]

write_attributes = ["email"]

callback_urls = ["https://auth.${var.hostname}","https://auth.${var.hostname}/oauth2/idpresponse"]
logout_urls = ["https://auth.${var.hostname}/logout"]
resource "cognito" "auth" {
user_pool = var.user_pool
hostname = var.hostname
}
# {{- end}}

output "cognito_pool_id" {
value = "${aws_cognito_user_pool.users.id}"
}
output "cognito_client_id" {
value = "${aws_cognito_user_pool_client.client.id}"
# {{ if .Config.Infrastructure.AWS.S3Hosting.Deploy }}
resource "s3_hosting" "assets" {
bucket_name = var.s3_hosting_bucket_name
}
# {{- end}}
10 changes: 6 additions & 4 deletions templates/terraform/modules/environment/variables.tf
Expand Up @@ -32,12 +32,14 @@ variable "eks_worker_ami" {
description = "The (EKS-optimized) AMI for EKS worker instances"
}

# {{ if .Config.Infrastructure.AWS.Cognito.Deploy }}
variable "user_pool" {
description = "AWS Cognito pool name"
}

variable "hostname" {
default = "{{ .Config.Frontend.Hostname }}"
description = "AWS Cognito pool name"
description = "Application hostname"
}
# {{- end}}

variable "s3_hosting_bucket_name" {
description = "S3 hosting bucket name"
}
103 changes: 103 additions & 0 deletions templates/terraform/modules/s3_hosting/main.tf
@@ -0,0 +1,103 @@
resource "aws_s3_bucket" "www" {
// Our bucket's name is going to be the same as our site's domain name.
bucket = "${var.bucket_name}"
// Because we want our site to be available on the internet, we set this so
// anyone can read this bucket.
acl = "public-read"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point this should be changed to private, with proper access set up from Cloudfront, we have plenty of examples of that. Not important for now though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup true, I just wanted to be a bit easier for demoing right now. We can just use the s3 url to load it.

// We also need to create a policy that allows anyone to view the content.
// This is basically duplicating what we did in the ACL but it's required by
// AWS. This post: http://amzn.to/2Fa04ul explains why.
policy = <<POLICY
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"AddPerm",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::${var.bucket_name}/*"]
}
]
}
POLICY

// S3 understands what it means to host a website.
website {
// Here we tell S3 what to use when a request comes in to the root
index_document = "index.html"
error_document = "404.html"
}
}

// TODO commented out for simpler demos

// Use the AWS Certificate Manager to create an SSL cert for our domain.
// This resource won't be created until you receive the email verifying you
// own the domain and you click on the confirmation link.
# resource "aws_acm_certificate" "certificate" {
# // We want a wildcard cert so we can host subdomains later.
# domain_name = "*.${local.www_domain_name}"
# validation_method = "EMAIL"

# // We also want the cert to be valid for the root domain even though we'll be
# // redirecting to the www. domain immediately.
# subject_alternative_names = ["${local.www_domain_name}"]
# }

resource "aws_cloudfront_distribution" "www_distribution" {
// origin is where CloudFront gets its content from.
origin {
// We need to set up a "custom" origin because otherwise CloudFront won't
// redirect traffic from the root domain to the www domain, that is from
custom_origin_config {
// These are all the defaults.
http_port = "80"
https_port = "443"
origin_protocol_policy = "http-only"
origin_ssl_protocols = ["TLSv1", "TLSv1.1", "TLSv1.2"]
}

// Here we're using our S3 bucket's URL!
domain_name = "${aws_s3_bucket.www.website_endpoint}"
// This can be any name to identify this origin.
origin_id = "${var.bucket_name}"
}

enabled = true
default_root_object = "index.html"

// All values are defaults from the AWS console.
default_cache_behavior {
viewer_protocol_policy = "redirect-to-https"
compress = true
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
// This needs to match the `origin_id` above.
target_origin_id = "${var.bucket_name}"
min_ttl = 0
default_ttl = 86400
max_ttl = 31536000

forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
}

# aliases = ["${local.www_domain_name}"]

restrictions {
geo_restriction {
restriction_type = "none"
}
}

viewer_certificate {
# acm_certificate_arn = "${aws_acm_certificate.certificate.arn}"
# ssl_support_method = "sni-only"
cloudfront_default_certificate = true
}
}
3 changes: 3 additions & 0 deletions templates/terraform/modules/s3_hosting/variables.tf
@@ -0,0 +1,3 @@
variable "bucket_name" {
description = "S3 hosting bucket name"
}