Skip to content

Commit

Permalink
Added aws_profile variable
Browse files Browse the repository at this point in the history
  • Loading branch information
seanturner026 committed May 25, 2021
1 parent f7b5a24 commit e065e38
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 175 deletions.
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ bin

# terraform
**/.terraform/*
*.auto.tfvars
*.terraform.lock.hcl
*.tfstate
*.tfstate.*
*.auto.tfvars
*_override.tf
*_override.tf.json
crash.log
override.tf
override.tf.json
*_override.tf
*_override.tf.json
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
repos:
- repo: git://github.com/antonbabenko/pre-commit-terraform
rev: v1.47.0
hooks:
- id: terraform_docs
- id: terraform_fmt
- repo: git://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0
hooks:
- id: check-merge-conflict
48 changes: 35 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### Moot - A Serverless Release Dashboard
# Moot - A Serverless Release Dashboard

AWS Serverless solution deployed with Terraform which implements a single-page-application dashboard. This dashboard creates releases that are intended to trigger continuous integration (CI) production deploy pipelines. All that is needed to kick off a release is a version number.

Expand All @@ -17,13 +17,26 @@ This solution utilises the following services:
- S3 + Cloudfront (frontend)
- SSM Parameter Store (secrets management)

#### Installation
## Requirements

The following tools must be installed in order to fully deploy Moot

- [yarn](https://yarnpkg.com/getting-started/install) -- used to build the frontend locally
- [awscli](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) -- used to aws s3 sync the frontend assets
- [go](https://golang.org/doc/install#download) -- requires at least version 16 because of `go modules`

## Installation

The below snippet will fully deploy the dashboard (backend + frontend). In this instance, I am deploying to a cheap Route53 domain I purchased for testing purposes (`moot.link`).

If your AWS account does not have a Route53 hosted zone, remove the `hosted_zone_name` and `fqdn_alias` lines to use Cloudfront's default certificate and dns.

```hcl
module "moot" {
source = "github.com/seanturner026/moot.git"
name = "moot"
aws_profile = "default"
admin_user_email = var.admin_user_email
enable_delete_admin_user = false
github_token = var.github_token
Expand All @@ -36,24 +49,30 @@ module "moot" {
}
```

#### Workflows
## Workflows

- Standard Deploy: Merges the HEAD branch into the BASE (e.g. main) branch, creates release based on BASE branch
- Hotfix Deploy: Creates release based on the BASE branch


#### Repositories View
## Repositories View

![alt text](https://github.com/seanturner026/moot/blob/main/assets/repositories.png?raw=true)

#### Add Repository View
## Add Repository View
![alt text](https://github.com/seanturner026/moot/blob/main/assets/repositories-add.png?raw=true)

#### Users View
## Users View

![alt text](https://github.com/seanturner026/moot/blob/main/assets/users.png?raw=true)

## Terraform Providers
## Terraform Information

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

No requirements.

## Providers

| Name | Version |
|------|---------|
Expand All @@ -62,23 +81,26 @@ module "moot" {
| external | n/a |
| null | n/a |

## Terraform Inputs
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| admin\_user\_email | Controls the creation of an admin user that is required to initially gain access to the<br>dashboard.<br><br>If access to the dashboard is completely lost, do the following<br>• `var.enable_delete_admin_user = true`<br>• `terraform apply`<br>• `var.enable_delete_admin_user = false`<br>• `terraform apply`<br><br>If the initial admin user should no longer be able to access the dashboard, revoke access by<br>setting `var.enable_delete_admin_user = true` and running `terraform apply` | `string` | `""` | no |
| aws\_profile | AWS Profile Name from `~/.aws/config that can be used for local execution. This profile is used<br>to preform the following actions:<br><br>• `aws s3 sync`: Sync bundle produced by `yarn` to build to s3<br>• `cognito-idp admin-create-user`: Creates an admin cognito user for dashboard access<br>• `cognito-idp admin-delete-user`: Deletes an admin cognito user if the user should not <br>have access to the dashboard anymore, OR, if there is no way for the user to regain access.<br>• `cognito-idp list-users`: Obtains the admin user's ID in order to write the ID to the <br>DynamodDB table.<br>` | `string` | `""` | no |
| enable\_api\_gateway\_access\_logs | Enables API Gateway access logging to cloudwatch for the default stage. | `bool` | `false` | no |
| enable\_delete\_admin\_user | Destroys the admin user.<br><br>Set this value to true to destroy the user, and to false to recreate the user. | `bool` | `false` | no |
| fqdn\_alias | ALIAS for the Cloudfront distribution, S3, Cognito and API Gateway. Must be in the form of<br>`example.com`. | `string` | `""` | no |
| github\_token | Token for Github. | `string` | `""` | no |
| gitlab\_token | Token for Gitlab. | `string` | `""` | no |
| github\_token | Token for Github. | `string` | `"42"` | no |
| gitlab\_token | Token for Gitlab. | `string` | `"42"` | no |
| hosted\_zone\_name | Name of AWS Route53 Hosted Zone for DNS. | `string` | `""` | no |
| name | Name to be applied to all resources. | `string` | `"release_dashboard"` | no |
| slack\_webhook\_url | URL to send slack message payloads to. | `string` | `""` | no |
| slack\_webhook\_url | URL to send slack message payloads to. | `string` | `"42"` | no |
| tags | Map of tags to be applied to resources. | `map(string)` | `{}` | no |

## Terraform Outputs
## Outputs

| Name | Description |
|------|-------------|
| cloudfront\_domain\_name | FQDN of Cloudfront Distribution that can be used for DNS. |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
12 changes: 7 additions & 5 deletions locals.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
locals {

aws_profile = var.aws_profile != "" ? var.aws_profile : "default"
frontend_module_comprehension = [for module in jsondecode(file("${path.root}/.terraform/modules/modules.json"))["Modules"] : module if length(regexall("vuejs_frontend", module.Key)) > 0][0]
frontend_module_path = "${path.root}/${local.frontend_module_comprehension.Dir}"
main_module_name = split(".terraform/modules/", path.module)[1]
main_module_path = "./.terraform/modules/${local.main_module_name}"

ssm_parameters = {
client_pool_secret = {
description = "Cognito User Pool client secret."
Expand All @@ -22,11 +29,6 @@ locals {
lambda_binary_exists = { for key, _ in local.lambdas : key => fileexists("${path.module}/bin/${key}") }
}

frontend_module_comprehension = [for module in jsondecode(file("${path.root}/.terraform/modules/modules.json"))["Modules"] : module if length(regexall("vuejs_frontend", module.Key)) > 0][0]
frontend_module_path = "${path.root}/${local.frontend_module_comprehension.Dir}"
main_module_path = "./.terraform/modules/${local.main_module_name}"
main_module_name = split(".terraform/modules/", path.module)[1]

lambdas = {
auth = {
description = "Administrates user login, token refreshes, and password resets."
Expand Down
16 changes: 0 additions & 16 deletions r_cognito.tf
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,3 @@ resource "aws_cognito_identity_pool" "this" {

tags = var.tags
}

resource "null_resource" "create_admin_user" {
count = var.admin_user_email != "" && !var.enable_delete_admin_user ? 1 : 0

provisioner "local-exec" {
command = "aws --region ${data.aws_region.current.name} cognito-idp admin-create-user --user-pool-id ${aws_cognito_user_pool.this.id} --username ${var.admin_user_email} --user-attributes Name=email,Value=${var.admin_user_email}"
}
}

resource "null_resource" "delete_admin_user" {
count = var.admin_user_email != "" && var.enable_delete_admin_user ? 1 : 0

provisioner "local-exec" {
command = "aws --region ${data.aws_region.current.name} cognito-idp admin-delete-user --user-pool-id ${aws_cognito_user_pool.this.id} --username ${var.admin_user_email}"
}
}
59 changes: 0 additions & 59 deletions r_lambda.tf
Original file line number Diff line number Diff line change
@@ -1,62 +1,3 @@
resource "null_resource" "go_setup" {

triggers = {
hash_go_mod = filemd5("${local.main_module_path}/go.mod")
hash_go_sum = filemd5("${local.main_module_path}/go.sum")
}

provisioner "local-exec" {
command = "cp -f ${local.main_module_path}/go.mod ."
}

provisioner "local-exec" {
command = "cp -f ${local.main_module_path}/go.sum ."
}
}

resource "null_resource" "lambda_build" {
for_each = local.lambdas
depends_on = [null_resource.go_setup]

triggers = {
binary_exists = local.null.lambda_binary_exists[each.key]

hash_main = join("", [
for file in fileset("${path.module}/cmd/${each.key}", "*.go") : filemd5("${path.module}/cmd/${each.key}/${file}")
])

hash_util = join("", [
for file in fileset("${path.module}/internal/util", "*.go") : filemd5("${path.module}/internal/util/${file}")
])
}

provisioner "local-exec" {
command = "export GO111MODULE=on"
}

provisioner "local-exec" {
command = "cd ${local.main_module_path} && GOOS=linux go build -ldflags '-s -w' -o ./bin/${each.key} ./cmd/${each.key}/."
}
}

resource "null_resource" "lambda_test" {
for_each = local.lambdas

triggers = {
hash_main = join("", [
for file in fileset("${path.module}/cmd/${each.key}", "*.go") : filemd5("${path.module}/cmd/${each.key}/${file}")
])

hash_util = join("", [
for file in fileset("${path.module}/internal/util", "*.go") : filemd5("${path.module}/internal/util/${file}")
])
}

provisioner "local-exec" {
command = "cd ${local.main_module_path} && go test ./cmd/${each.key}"
}
}

resource "aws_lambda_function" "this" {
depends_on = [null_resource.lambda_build, null_resource.lambda_test]
for_each = local.lambdas
Expand Down
92 changes: 88 additions & 4 deletions r_null.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,102 @@ resource "null_resource" "build_frontend" {
}

provisioner "local-exec" {
command = "cd ${local.frontend_module_path} && yarn install"
interpreter = ["/bin/bash", "-c"]
command = "cd ${local.frontend_module_path} && yarn install"
}

provisioner "local-exec" {
command = "cd ${local.frontend_module_path} && echo \"VUE_APP_API_GATEWAY_ENDPOINT=${aws_apigatewayv2_api.this.api_endpoint}\" > .env"
interpreter = ["/bin/bash", "-c"]
command = "cd ${local.frontend_module_path} && echo \"VUE_APP_API_GATEWAY_ENDPOINT=${aws_apigatewayv2_api.this.api_endpoint}\" > .env"
}

provisioner "local-exec" {
command = "cd ${local.frontend_module_path} && yarn build"
interpreter = ["/bin/bash", "-c"]
command = "cd ${local.frontend_module_path} && yarn build"
}

provisioner "local-exec" {
command = "cd ${local.frontend_module_path} && aws s3 sync --cache-control 'max-age=604800' dist/ s3://${aws_s3_bucket.this.id}"
interpreter = ["/bin/bash", "-c"]
command = "cd ${local.frontend_module_path} && AWS_DEFAULT_PROFILE=${local.aws_profile} aws s3 sync --cache-control 'max-age=604800' dist/ s3://${aws_s3_bucket.this.id}"
}
}

resource "null_resource" "go_setup" {

triggers = {
hash_go_mod = filemd5("${local.main_module_path}/go.mod")
hash_go_sum = filemd5("${local.main_module_path}/go.sum")
}

provisioner "local-exec" {
interpreter = ["/bin/bash", "-c"]
command = "cp -f ${local.main_module_path}/go.mod ."
}

provisioner "local-exec" {
interpreter = ["/bin/bash", "-c"]
command = "cp -f ${local.main_module_path}/go.sum ."
}
}

resource "null_resource" "lambda_build" {
for_each = local.lambdas
depends_on = [null_resource.go_setup]

triggers = {
binary_exists = local.null.lambda_binary_exists[each.key]

hash_main = join("", [
for file in fileset("${path.module}/cmd/${each.key}", "*.go") : filemd5("${path.module}/cmd/${each.key}/${file}")
])

hash_util = join("", [
for file in fileset("${path.module}/internal/util", "*.go") : filemd5("${path.module}/internal/util/${file}")
])
}

provisioner "local-exec" {
interpreter = ["/bin/bash", "-c"]
command = "export GO111MODULE=on"
}

provisioner "local-exec" {
interpreter = ["/bin/bash", "-c"]
command = "cd ${local.main_module_path} && GOOS=linux go build -ldflags '-s -w' -o ./bin/${each.key} ./cmd/${each.key}/."
}
}

resource "null_resource" "lambda_test" {
for_each = local.lambdas

triggers = {
hash_main = join("", [
for file in fileset("${path.module}/cmd/${each.key}", "*.go") : filemd5("${path.module}/cmd/${each.key}/${file}")
])

hash_util = join("", [
for file in fileset("${path.module}/internal/util", "*.go") : filemd5("${path.module}/internal/util/${file}")
])
}

provisioner "local-exec" {
interpreter = ["/bin/bash", "-c"]
command = "cd ${local.main_module_path} && go test ./cmd/${each.key}"
}
}

resource "null_resource" "create_admin_user" {
count = var.admin_user_email != "" && !var.enable_delete_admin_user ? 1 : 0

provisioner "local-exec" {
command = "aws --region ${data.aws_region.current.name} cognito-idp admin-create-user --user-pool-id ${aws_cognito_user_pool.this.id} --username ${var.admin_user_email} --user-attributes Name=email,Value=${var.admin_user_email}"
}
}

resource "null_resource" "delete_admin_user" {
count = var.admin_user_email != "" && var.enable_delete_admin_user ? 1 : 0

provisioner "local-exec" {
command = "aws --region ${data.aws_region.current.name} cognito-idp admin-delete-user --user-pool-id ${aws_cognito_user_pool.this.id} --username ${var.admin_user_email}"
}
}
Loading

0 comments on commit e065e38

Please sign in to comment.