Skip to content

Commit

Permalink
Add main module infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
vibou committed Oct 9, 2019
1 parent 9b14ead commit 98545d2
Show file tree
Hide file tree
Showing 14 changed files with 350 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/create-master-dev-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
on:
push:
branches:
- master

name: create master → dev PR

jobs:
auto_create_master_dev_pr:
name: Auto create master → dev PR
runs-on: ubuntu-latest

steps:
- name: Checkout sources
uses: actions/checkout@master
with:
fetch-depth: 1

- name: install hub
run: curl -qs https://raw.githubusercontent.com/inextensodigital/github/master/install-hub.sh | bash -

- name: Auto create master → dev PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: hub pull-request -b dev -h master -m "master → dev" || exit 0
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.terraform
48 changes: 48 additions & 0 deletions api_gateway.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
resource "aws_api_gateway_rest_api" "graphql" {
description = "graphql api gateway"
name = "${local.graphql_gateway_name}"
}

resource "aws_api_gateway_resource" "graphql" {
rest_api_id = aws_api_gateway_rest_api.graphql.id
parent_id = aws_api_gateway_rest_api.graphql.root_resource_id
path_part = "graphql"
}

resource "aws_api_gateway_method" "graphql" {
rest_api_id = aws_api_gateway_rest_api.graphql.id
resource_id = aws_api_gateway_resource.graphql.id
http_method = "POST"
authorization = "NONE"
}


resource "aws_api_gateway_integration" "graphql_lambda_integration" {
rest_api_id = aws_api_gateway_rest_api.graphql.id
resource_id = aws_api_gateway_resource.graphql.id
http_method = aws_api_gateway_method.graphql.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.graphql.invoke_arn
}

resource "aws_api_gateway_deployment" "graphql" {
depends_on = [aws_api_gateway_method.graphql, aws_api_gateway_integration.graphql_lambda_integration]
description = "Deployment by stage to access the endpoint"

rest_api_id = aws_api_gateway_rest_api.graphql.id

stage_name = var.stage
}

## REGISTER DOMAINS FOR API GATEWAY
resource "aws_api_gateway_domain_name" "graphql" {
domain_name = local.api_graphql_domain
certificate_arn = data.aws_acm_certificate.certificate.arn
}

resource "aws_api_gateway_base_path_mapping" "graphql" {
api_id = aws_api_gateway_rest_api.graphql.id
stage_name = aws_api_gateway_deployment.graphql.stage_name
domain_name = aws_api_gateway_domain_name.graphql.domain_name
}
6 changes: 6 additions & 0 deletions certificate.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
data "aws_acm_certificate" "certificate" {
provider = aws.n_virginia
domain = var.certificate_domain
statuses = ["ISSUED"]
most_recent = true
}
14 changes: 14 additions & 0 deletions cloudwatch.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
resource "aws_cloudwatch_log_group" "graphql" {
name = "/aws/lambda/${var.stage}-${var.app_name}-graphql"
}

data "aws_lambda_function" "logs_to_kibana" {
function_name = var.lambda_logs_to_kibana_name
}

resource "aws_cloudwatch_log_subscription_filter" "graphql_logs_to_kibana" {
name = var.logs_to_kibana_subscription_filter_name
log_group_name = aws_cloudwatch_log_group.graphql.name
filter_pattern = ""
destination_arn = data.aws_lambda_function.logs_to_kibana.arn
}
27 changes: 27 additions & 0 deletions iam.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
data "aws_iam_policy" "aws_lambda_vpc_access" {
arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
}

data "aws_iam_policy_document" "lambda_logging" {

statement {
sid = "${local.camel_app_name}LambdaLogging${title(var.stage)}"

actions = [
"logs:CreateLogStream",
"logs:PutLogEvents",
]

resources = [
"arn:aws:logs:*:*:/aws/lambda/${var.stage}-${var.app_name}-*",
]

effect = "Allow"
}
}

resource "aws_iam_policy" "lambda_logging" {
description = "Policy to allow the lambda to create and publish logs in cloudwatch"
name = "${var.stage}-${var.app_name}-lambda-logs"
policy = data.aws_iam_policy_document.lambda_logging.json
}
88 changes: 88 additions & 0 deletions lambda_graphql.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Policies definition
data "aws_iam_policy_document" "graphql_group_policy" {
statement {
sid = "LambdaAssumeRole"

actions = [
"sts:AssumeRole",
]

effect = "Allow"

principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}

principals {
type = "AWS"
identifiers = [
var.default_account_arn,
var.security_account_arn,
]
}
}
}

resource "aws_iam_role" "graphql_lambda_role" {
name = "${local.camel_app_name}Graphql${title(var.stage)}"
assume_role_policy = data.aws_iam_policy_document.graphql_group_policy.json
}

# Allow access to VPC
resource "aws_iam_role_policy_attachment" "graphql_lambda_execution" {
role = aws_iam_role.graphql_lambda_role.name
policy_arn = data.aws_iam_policy.aws_lambda_vpc_access.arn
}

resource "aws_iam_role_policy_attachment" "graphql_logging" {
depends_on = ["aws_iam_policy.lambda_logging"]
role = aws_iam_role.graphql_lambda_role.name
policy_arn = aws_iam_policy.lambda_logging.arn
}

resource "aws_lambda_permission" "graphql" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.graphql.arn
principal = "apigateway.amazonaws.com"
source_arn = "${replace(aws_api_gateway_deployment.graphql.execution_arn, "/${var.stage}", "/*/*")}"
}

resource "aws_lambda_function" "graphql" {
description = "Processes graphql queries"
depends_on = [
aws_iam_role.graphql_lambda_role,
aws_cloudwatch_log_group.graphql,
]

function_name = "${local.graphql_lambda_function_name}"
source_code_hash = filebase64sha256(var.backend_lambda_filename)

s3_bucket = data.aws_s3_bucket.deployment_bucket.id
s3_key = var.backend_s3_key

handler = "index.handler"
runtime = "nodejs10.x"

publish = true

timeout = 6

memory_size = 1024

tags = "${var.common_tags}"

vpc_config {
subnet_ids = var.vpc["subnet_ids"]
security_group_ids = var.vpc["security_group_ids"]
}

environment {
variables = {
stage = var.stage
}
}

role = aws_iam_role.graphql_lambda_role.arn
}
28 changes: 28 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# COMPUTED VARIABLES DO NOT CHANGE ANY VALUES FROM HERE
locals {

## stage == prod: app_name
## else: app_name-{staging}
camel_app_name = replace(title(replace(var.app_name, "/\\W+/", " ")), " ", "")

# API GATEWAY VARIABLES
graphql_gateway_name = "${var.stage}-${var.app_name}-graphql"

# LAMBDA VARIABLES
graphql_lambda_function_name = "${var.stage}-${var.app_name}-graphql"




api_graphql_domain = [var.alternate_graphql_domain == null ?
var.graphql_domain :
var.alternate_graphql_domain
][0]

graphql_zone = [var.alternate_graphql_domain == null ?
regex("([^\\.]+)\\.(.+)", var.graphql_domain)[1] :
null
][0]

graphql_domain_array = [var.alternate_graphql_domain == null ? [var.graphql_domain] : []][0]
}
3 changes: 3 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
terraform {
required_version = "0.12.9"
}
3 changes: 3 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "graphql_lambda_version" {
value = aws_lambda_function.graphql.version
}
3 changes: 3 additions & 0 deletions provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
provider "aws" {
alias = "n_virginia"
}
18 changes: 18 additions & 0 deletions route53.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
data "aws_route53_zone" "graphql" {
count = length(local.graphql_domain_array)
name = "${local.graphql_zone}."
}

resource "aws_route53_record" "graphql" {
count = length(local.graphql_domain_array)

name = aws_api_gateway_domain_name.graphql.domain_name
type = "A"
zone_id = data.aws_route53_zone.graphql[count.index].zone_id

alias {
evaluate_target_health = false
name = aws_api_gateway_domain_name.graphql.cloudfront_domain_name
zone_id = aws_api_gateway_domain_name.graphql.cloudfront_zone_id
}
}
3 changes: 3 additions & 0 deletions s3bucket.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "aws_s3_bucket" "deployment_bucket" {
bucket = var.backend_s3_bucket
}
83 changes: 83 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# GLOBAL VARIABLES
variable "common_tags" {
type = "map"
description = "a list of tags set on the different resources"
default = {}
}

variable "stage" {
type = "string"
description = "The deploy environment in [prod, dev, preprod]"
}

variable "app_id" {
type = "string"
description = "The id of the application"
}

variable "app_name" {
type = "string"
description = "The name of the application"
}

# PROVIDER VARIABLES
variable "aws_region" {
type = "string"
description = "The aws region where the infrastructure is hosted"
default = "eu-central-1"
}

variable "backend_s3_bucket" {
type = "string"
description = "The bucket where the lambda is deployed on."
}

variable "backend_s3_key" {
type = "string"
description = "The key pointing to the lambda on the backend_s3_bucket"
}

variable "security_account_arn" {
type = "string"
description = "The security account arn"
}

variable "default_account_arn" {
type = "string"
description = "The security account arn"
}

variable "certificate_domain" {
type = "string"
description = "the domain certificate for cloudfront"
}

variable "graphql_domain" {
type = "string"
description = "the graphql api gateway"
}

variable "alternate_graphql_domain" {
type = "string"
description = "the graphql api gateway domain not managed by terraform"
}

variable "backend_lambda_filename" {
type = "string"
description = "the path to the lambda.zip file"
}

variable "lambda_logs_to_kibana_name" {
type = "string"
description = "name of the lambda to log in kibana"
}

variable "logs_to_kibana_subscription_filter_name" {
type = "string"
description = "the kibana subscription filter name"
}

variable "vpc" {
type = "map"
description = "expected subnet_ids => [] and security_group_ids => []"
}

0 comments on commit 98545d2

Please sign in to comment.