Skip to content

Instantly share code, notes, and snippets.

@leehambley
Created June 16, 2020 22:22
Show Gist options
  • Save leehambley/e6eda23333962b45636803910bad907f to your computer and use it in GitHub Desktop.
Save leehambley/e6eda23333962b45636803910bad907f to your computer and use it in GitHub Desktop.
resource "aws_ses_domain_identity" "zbn" {
domain = var.zone_base_name
}
resource "aws_ses_domain_mail_from" "contact_form" {
domain = aws_ses_domain_identity.zbn.domain
mail_from_domain = "bounce.${aws_ses_domain_identity.zbn.domain}"
}
resource "aws_api_gateway_account" "quasar" {
cloudwatch_role_arn = aws_iam_role.cloudwatch.arn
}
resource "aws_iam_role" "cloudwatch" {
name = "api_gateway_cloudwatch_global"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy" "cloudwatch" {
name = "default"
role = aws_iam_role.cloudwatch.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
"logs:GetLogEvents",
"logs:FilterLogEvents"
],
"Resource": "*"
}
]
}
EOF
}
resource "aws_route53_record" "example_ses_domain_mail_from_mx" {
zone_id = data.aws_route53_zone.root_domain_name.id
name = aws_ses_domain_mail_from.contact_form.mail_from_domain
type = "MX"
ttl = "600"
records = ["10 feedback-smtp.us-east-1.amazonses.com"]
}
resource "aws_api_gateway_base_path_mapping" "mapping" {
api_id = aws_api_gateway_rest_api.quasar.id
stage_name = aws_api_gateway_deployment.quasar.stage_name
domain_name = aws_api_gateway_domain_name.lapi.domain_name
depends_on = [aws_api_gateway_deployment.quasar]
}
resource "aws_api_gateway_rest_api" "quasar" {
name = "quasar"
description = "Quasar API"
tags = {
Client = var.client_name
Environment = var.environment_name
}
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": [
"execute-api:/*"
]
}
]
}
POLICY
}
resource "aws_api_gateway_resource" "quasar_lambda_contact_resource" {
rest_api_id = aws_api_gateway_rest_api.quasar.id
parent_id = aws_api_gateway_rest_api.quasar.root_resource_id
path_part = "contact"
}
resource "aws_api_gateway_method" "quasar_lambda_method" {
rest_api_id = aws_api_gateway_rest_api.quasar.id
resource_id = aws_api_gateway_resource.quasar_lambda_contact_resource.id
http_method = "POST"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "integration" {
rest_api_id = aws_api_gateway_rest_api.quasar.id
resource_id = aws_api_gateway_resource.quasar_lambda_contact_resource.id
http_method = aws_api_gateway_method.quasar_lambda_method.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.contact_email_form.invoke_arn
request_templates = {
"application/xml" = <<EOF
{
"body" : $input.json('$')
}
EOF
}
}
locals {
lapi_domain_name = "lapi.${var.environment_name}.${var.zone_base_name}"
stage_name = "stage-${var.environment_name}"
}
resource "aws_api_gateway_method_settings" "s" {
rest_api_id = aws_api_gateway_rest_api.quasar.id
stage_name = local.stage_name
method_path = "${aws_api_gateway_resource.quasar_lambda_contact_resource.path_part}/${aws_api_gateway_method.quasar_lambda_method.http_method}"
depends_on = [
aws_api_gateway_account.quasar,
aws_api_gateway_deployment.quasar
]
settings {
metrics_enabled = true
logging_level = "INFO"
}
}
resource "aws_route53_record" "lapi" {
name = local.lapi_domain_name
type = "A"
zone_id = data.aws_route53_zone.root_domain_name.id
alias {
evaluate_target_health = false
name = aws_api_gateway_domain_name.lapi.cloudfront_domain_name
zone_id = aws_api_gateway_domain_name.lapi.cloudfront_zone_id
}
}
resource "aws_acm_certificate" "lapi" {
provider = aws.useast1 # ACM Certs for CloudFront MUST be in this region
domain_name = local.lapi_domain_name
validation_method = "DNS"
tags = {
Client = "${var.client_name}"
Environment = "${var.environment_name}"
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_route53_record" "lapi_cert_validation" {
name = aws_acm_certificate.lapi.domain_validation_options.0.resource_record_name
type = aws_acm_certificate.lapi.domain_validation_options.0.resource_record_type
records = [aws_acm_certificate.lapi.domain_validation_options.0.resource_record_value]
zone_id = data.aws_route53_zone.root_domain_name.id
ttl = 60
}
resource "aws_acm_certificate_validation" "lapi_cert" {
provider = aws.useast1
certificate_arn = aws_acm_certificate.lapi.arn
validation_record_fqdns = [aws_route53_record.lapi_cert_validation.fqdn]
}
resource "aws_api_gateway_domain_name" "lapi" {
certificate_arn = aws_acm_certificate_validation.lapi_cert.certificate_arn
domain_name = local.lapi_domain_name
tags = {
Client = var.client_name
Environment = var.environment_name
}
}
resource "aws_api_gateway_deployment" "quasar" {
depends_on = [aws_api_gateway_integration.integration]
rest_api_id = aws_api_gateway_rest_api.quasar.id
stage_name = local.stage_name
}
resource "aws_lambda_permission" "apigw_lambda" {
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.contact_email_form.function_name
principal = "apigateway.amazonaws.com"
# More: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-control-access-using-iam-policies-to-invoke-api.html
source_arn = "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:${aws_api_gateway_rest_api.quasar.id}/*/${aws_api_gateway_method.quasar_lambda_method.http_method}${aws_api_gateway_resource.quasar_lambda_contact_resource.path}"
}
resource "aws_route53_record" "amazonses_verification_record" {
zone_id = data.aws_route53_zone.root_domain_name.id
name = "_amazonses.${var.zone_base_name}"
type = "TXT"
ttl = "600"
records = ["${aws_ses_domain_identity.zbn.verification_token}"]
}
resource "aws_iam_role" "lambda-contact-form" {
name = "lambda-contact-form"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
POLICY
}
resource "aws_iam_policy" "send-with-ses" {
name = "lambda_contact_form_ses"
path = "/"
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail"
],
"Resource": "*"
}
]
}
POLICY
}
resource "aws_iam_policy" "lambda_logging" {
name = "lambda_logging"
path = "/"
description = "IAM policy for logging from a lambda"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*",
"Effect": "Allow"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "lambda-contact-form-ses" {
role = aws_iam_role.lambda-contact-form.name
policy_arn = aws_iam_policy.send-with-ses.arn
}
resource "aws_iam_role_policy_attachment" "lambda_logs" {
role = aws_iam_role.lambda-contact-form.name
policy_arn = aws_iam_policy.lambda_logging.arn
}
resource "null_resource" "contact_email_form_zip_fn" {
triggers = {
source_code_hash = "${filebase64sha256("${path.module}/../src/lambda-funcs/contact-email-form/index.js")}"
}
provisioner "local-exec" {
command = "./build.sh"
working_dir = "${path.module}/../src/lambda-funcs/contact-email-form/"
}
}
data "archive_file" "contact_email_form_zip" {
type = "zip"
source_dir = "${path.module}/../src/lambda-funcs/contact-email-form/"
output_path = "${path.module}/../src/lambda-funcs/contact-email-form/deployment.zip"
depends_on = [null_resource.contact_email_form_zip_fn]
}
resource "aws_cloudwatch_log_group" "contact_email_form" {
name = "/aws/lambda/contact_email_form"
retention_in_days = 14
}
resource "aws_lambda_function" "contact_email_form" {
filename = "${path.module}/../src/lambda-funcs/contact-email-form/deployment.zip"
function_name = "contact_email_form"
role = aws_iam_role.lambda-contact-form.arn
handler = "index.handler"
source_code_hash = data.archive_file.contact_email_form_zip.output_base64sha256
runtime = "nodejs12.x"
depends_on = [
null_resource.contact_email_form_zip_fn,
aws_iam_role_policy_attachment.lambda_logs,
aws_cloudwatch_log_group.contact_email_form
]
}
module "cors" {
source = "squidfunk/api-gateway-enable-cors/aws"
version = "0.3.1"
api_id = aws_api_gateway_rest_api.quasar.id
api_resource_id = aws_api_gateway_resource.quasar_lambda_contact_resource.id
allow_methods = ["POST"]
}
# resource "aws_api_gateway_method" "options_method" {
# rest_api_id = aws_api_gateway_rest_api.quasar.id
# resource_id = aws_api_gateway_resource.quasar_lambda_contact_resource.id
# http_method = "OPTIONS"
# authorization = "NONE"
# }
# resource "aws_api_gateway_method_response" "options_200" {
# rest_api_id = aws_api_gateway_rest_api.quasar.id
# resource_id = aws_api_gateway_resource.quasar_lambda_contact_resource.id
# http_method = aws_api_gateway_method.options_method.http_method
# status_code = 200
# response_models = {
# "application/json" = "Empty"
# }
# response_parameters = {
# "method.response.header.Access-Control-Allow-Headers" = true,
# "method.response.header.Access-Control-Allow-Methods" = true,
# "method.response.header.Access-Control-Allow-Origin" = true
# }
# depends_on = [aws_api_gateway_method.options_method]
# }
# resource "aws_api_gateway_integration" "options_integration" {
# rest_api_id = aws_api_gateway_rest_api.quasar.id
# resource_id = aws_api_gateway_resource.quasar_lambda_contact_resource.id
# http_method = aws_api_gateway_method.options_method.http_method
# type = "MOCK"
# depends_on = [aws_api_gateway_method.options_method]
# }
# resource "aws_api_gateway_integration_response" "options_integration_response" {
# rest_api_id = aws_api_gateway_rest_api.quasar.id
# resource_id = aws_api_gateway_resource.quasar_lambda_contact_resource.id
# http_method = aws_api_gateway_method.options_method.http_method
# status_code = aws_api_gateway_method_response.options_200.status_code
# response_parameters = {
# "method.response.header.Access-Control-Allow-Headers" = "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
# "method.response.header.Access-Control-Allow-Methods" = "'GET,OPTIONS,POST,PUT'",
# "method.response.header.Access-Control-Allow-Origin" = "'*'",
# }
# depends_on = [aws_api_gateway_method_response.options_200]
# }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment