Created
September 22, 2022 14:54
-
-
Save danpaldev/9ca284cebc77413cfd809d201f16c522 to your computer and use it in GitHub Desktop.
Terraform infra
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
terraform { | |
required_providers { | |
aws = { | |
source = "hashicorp/aws" | |
version = "~> 4.16" | |
} | |
} | |
required_version = ">= 1.2.0" | |
} | |
provider "aws" { | |
region = var.default_region | |
} | |
data "aws_caller_identity" "current" {} | |
locals { | |
accountId = data.aws_caller_identity.current.account_id | |
} | |
output "accountId" { | |
value = local.accountId | |
} | |
# Creating the S3 Bucket for storing audios | |
resource "aws_s3_bucket" "tts-audios" { | |
bucket = "audios-from-pollychan" | |
# TODO -> Add Lifecycle config. to delete obj in 24 hrs. | |
} | |
resource "aws_s3_bucket_acl" "tts-audios-s3-acl" { | |
bucket = aws_s3_bucket.tts-audios.id | |
acl = "private" | |
} | |
# Creating Policy | |
resource "aws_iam_policy" "policy_for_lambda" { | |
name = "polly-tts-lambda-policy" | |
path = "/" | |
description = "Required permissions for the lambda function" | |
# Terraform's "jsonencode" function converts a | |
# Terraform expression result to valid JSON syntax. | |
policy = jsonencode({ | |
Version : "2012-10-17", | |
Statement : [ | |
{ | |
Sid : "AllowReadWriteOnS3", | |
Action : [ | |
"s3:DeleteObject", | |
"s3:GetObject", | |
"s3:ListBucket", | |
"s3:PutObject" | |
], | |
Effect : "Allow", | |
Resource : "*" | |
}, | |
{ | |
Sid : "AllowTTSGenerationOnPolly", | |
Action : [ | |
"polly:StartSpeechSynthesisTask", | |
"polly:SynthesizeSpeech" | |
], | |
Effect : "Allow", | |
Resource : "*" | |
}, | |
{ | |
Sid : "FullCloudwatchAccess", | |
Action : "logs:*", | |
Effect : "Allow", | |
Resource : "*" | |
} | |
] | |
}) | |
} | |
/* | |
Fixing the error: | |
MalformedPolicyDocument: Has prohibited field Resource | |
https://stackoverflow.com/a/61971229/ | |
https://stackoverflow.com/a/44581645/ | |
*/ | |
# Creating the role for the lambda function | |
resource "aws_iam_role" "permissions-lambda-tts" { | |
name = "PermissionsLambdaTTS" | |
assume_role_policy = jsonencode({ | |
Version : "2012-10-17", | |
Statement : [ | |
{ | |
Action : "sts:AssumeRole", | |
Principal : { | |
Service : "lambda.amazonaws.com" | |
}, | |
Effect : "Allow", | |
} | |
] | |
}) | |
} | |
# Binding the Policy to the Role | |
resource "aws_iam_role_policy_attachment" "resource_for_attach" { | |
role = aws_iam_role.permissions-lambda-tts.name | |
policy_arn = aws_iam_policy.policy_for_lambda.arn | |
} | |
# Creating Lambda | |
resource "aws_lambda_function" "tts-generator" { | |
# If the file is not in the current working directory you will need to include a | |
# path.module in the filename. | |
runtime = "python3.9" | |
filename = "lambda_code.zip" | |
function_name = "tts-generator" | |
role = aws_iam_role.permissions-lambda-tts.arn | |
handler = "lambda_code.lambda_handler" | |
depends_on = [aws_iam_role.permissions-lambda-tts] | |
# The filebase64sha256() function is available in Terraform 0.11.12 and later | |
# For Terraform 0.11.11 and earlier, use the base64sha256() function and the file() function: | |
# source_code_hash = "${base64sha256(file("lambda_function_payload.zip"))}" | |
source_code_hash = filebase64sha256("lambda_code.zip") | |
environment { | |
variables = { | |
DEFAULT_LANG = "japanese" | |
} | |
} | |
} | |
# Creating REST API | |
resource "aws_api_gateway_rest_api" "polly-chan-api" { | |
name = "polly-chan-api" | |
endpoint_configuration { | |
types = ["REGIONAL"] | |
} | |
} | |
/************ | |
I didn't create any resource (i.e., a path for the API), | |
because using the root one (/) is enough for my needs. | |
This path (/) is inherently created whenever a new REST API | |
is created, so I can reference the root path in my methods | |
without having to create it! | |
https://stackoverflow.com/a/61084896/ | |
**************/ | |
// Creating the Option Method (Needed when API Gateway is "proxied" to lambda) | |
resource "aws_api_gateway_method" "OPTIONS-method" { | |
authorization = "NONE" | |
http_method = "OPTIONS" | |
resource_id = aws_api_gateway_rest_api.polly-chan-api.root_resource_id | |
rest_api_id = aws_api_gateway_rest_api.polly-chan-api.id | |
} | |
resource "aws_api_gateway_integration" "OPTIONS-Integration" { | |
rest_api_id = aws_api_gateway_rest_api.polly-chan-api.id | |
resource_id = aws_api_gateway_rest_api.polly-chan-api.root_resource_id | |
http_method = aws_api_gateway_method.OPTIONS-method.http_method | |
type = "MOCK" | |
} | |
resource "aws_api_gateway_method_response" "mocked_200" { | |
rest_api_id = aws_api_gateway_rest_api.polly-chan-api.id | |
resource_id = aws_api_gateway_rest_api.polly-chan-api.root_resource_id | |
http_method = aws_api_gateway_method.OPTIONS-method.http_method | |
status_code = "200" | |
// This headers are used to prevent browsers from complaining about CORS | |
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, | |
} | |
/* | |
You need to add a integration_response (the resource just below this), | |
in order to succesfully define an empty application/json response_model | |
See here: | |
https://github.com/hashicorp/terraform/issues/10157#issuecomment-263560025 | |
*/ | |
response_models = { | |
"application/json" = "Empty" | |
} | |
} | |
resource "aws_api_gateway_integration_response" "MyDemoIntegrationResponse" { | |
rest_api_id = aws_api_gateway_rest_api.polly-chan-api.id | |
resource_id = aws_api_gateway_rest_api.polly-chan-api.root_resource_id | |
http_method = aws_api_gateway_method.OPTIONS-method.http_method | |
status_code = aws_api_gateway_method_response.mocked_200.status_code | |
response_templates = { | |
"application/json" = "" | |
} | |
} | |
// Creating the POST Method | |
resource "aws_api_gateway_method" "POST-method" { | |
authorization = "NONE" | |
http_method = "POST" | |
resource_id = aws_api_gateway_rest_api.polly-chan-api.root_resource_id | |
rest_api_id = aws_api_gateway_rest_api.polly-chan-api.id | |
} | |
resource "aws_api_gateway_integration" "POST-Integration" { | |
rest_api_id = aws_api_gateway_rest_api.polly-chan-api.id | |
resource_id = aws_api_gateway_rest_api.polly-chan-api.root_resource_id | |
http_method = aws_api_gateway_method.POST-method.http_method | |
integration_http_method = "POST" | |
type = "AWS_PROXY" | |
uri = aws_lambda_function.tts-generator.invoke_arn | |
} | |
// Method Configuration resource. Only created to set up the throttling limits for the API | |
resource "aws_api_gateway_method_settings" "all" { | |
rest_api_id = aws_api_gateway_rest_api.polly-chan-api.id | |
stage_name = aws_api_gateway_stage.polly-chan-api.stage_name | |
method_path = "*/*" | |
settings { | |
throttling_rate_limit = 100 | |
throttling_burst_limit = 50 | |
} | |
} | |
// Invoke policy to allow lambda execution. As in https://bit.ly/3BPpskU | |
resource "aws_lambda_permission" "api_invoke_policy" { | |
statement_id = "AllowExecutionFromAPIGateway" | |
action = "lambda:InvokeFunction" | |
function_name = aws_lambda_function.tts-generator.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:${var.default_region}:${local.accountId}:${aws_api_gateway_rest_api.polly-chan-api.id}/*/*/" | |
} | |
// Creating the Deployment | |
resource "aws_api_gateway_deployment" "polly-chan-deployment" { | |
rest_api_id = aws_api_gateway_rest_api.polly-chan-api.id | |
depends_on = [ | |
aws_api_gateway_integration.POST-Integration, | |
aws_api_gateway_integration.OPTIONS-Integration | |
] | |
description = "Deployed ${timestamp()}" | |
} | |
resource "aws_api_gateway_stage" "polly-chan-api" { | |
deployment_id = aws_api_gateway_deployment.polly-chan-deployment.id | |
rest_api_id = aws_api_gateway_rest_api.polly-chan-api.id | |
stage_name = "dev" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment