mirror of https://github.com/sgoudham/Tweeter.git
Create API Gateway with Lambda Backend
parent
7c5f19dc43
commit
4f95fcf321
@ -1,18 +1,214 @@
|
||||
from troposphere import Template
|
||||
from awacs.aws import Action, Statement, Principal, Policy
|
||||
from troposphere import Template, GetAtt, Ref, Join, Output, iam, awslambda
|
||||
from troposphere.apigateway import RestApi, Resource, Method, Integration, IntegrationResponse, MethodResponse, \
|
||||
Deployment, Stage
|
||||
from troposphere.awslambda import Function, Code
|
||||
from troposphere.s3 import Bucket
|
||||
from troposphere.sns import Topic, Subscription
|
||||
from troposphere.sqs import Queue
|
||||
|
||||
from util import Util
|
||||
|
||||
PROJECT_NAME: str = "Tweeter"
|
||||
REST_API_NAME: str = "TweeterAPI"
|
||||
REST_API_STAGE_NAME: str = "v1"
|
||||
API_LAMBDA_NAME: str = "ApiLambda"
|
||||
API_LAMBDA_KEBAB_NAME: str = "api-lambda"
|
||||
SHARED_CONFIG_BUCKET_NAME: str = "SharedConfig"
|
||||
|
||||
S3_QUEUE_NAME: str = "S3Queue"
|
||||
TWEETER_QUEUE_NAME: str = "TwitterQueue"
|
||||
TWITTER_QUEUE_NAME: str = "TwitterQueue"
|
||||
DYNAMO_DB_QUEUE_NAME: str = "DynamoDbQueue"
|
||||
FANOUT_TOPIC_NAME: str = "FanoutTopic"
|
||||
|
||||
template: Template = Template(PROJECT_NAME + "Workflow")
|
||||
templateUtil: Util = Util(template)
|
||||
|
||||
shared_config_bucket: Bucket = template.add_resource(Bucket(SHARED_CONFIG_BUCKET_NAME))
|
||||
rest_api: RestApi = template.add_resource(RestApi(REST_API_NAME, Name=REST_API_NAME))
|
||||
|
||||
api_lambda_execute_statements = [
|
||||
Statement(
|
||||
Action=[
|
||||
Action("logs", "*"),
|
||||
Action("cloudwatch", "*"),
|
||||
Action("cloudformation", "DescribeStacks"),
|
||||
Action("cloudformation", "DescribeStackEvents"),
|
||||
Action("cloudformation", "DescribeStackResource"),
|
||||
Action("cloudformation", "DescribeStackResources"),
|
||||
Action("cloudformation", "GetTemplate"),
|
||||
Action("cloudformation", "List*"),
|
||||
],
|
||||
Effect="Allow",
|
||||
Resource=["*"]
|
||||
),
|
||||
Statement(
|
||||
Action=[
|
||||
Action("sns", "Publish")
|
||||
],
|
||||
Effect="Allow",
|
||||
Resource=[Ref(FANOUT_TOPIC_NAME)]
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
api_lambda_execute_role: iam.Role = template.add_resource(
|
||||
iam.Role(
|
||||
API_LAMBDA_NAME + "ExecuteRole",
|
||||
AssumeRolePolicyDocument=Policy(
|
||||
Statement=[
|
||||
Statement(
|
||||
Effect="Allow",
|
||||
Action=[Action("sts", "AssumeRole")],
|
||||
Principal=Principal("Service", ["lambda.amazonaws.com", "apigateway.amazonaws.com"])
|
||||
)
|
||||
]
|
||||
),
|
||||
Policies=[
|
||||
iam.Policy(
|
||||
PolicyName=API_LAMBDA_NAME + "ExecutePolicy",
|
||||
PolicyDocument=Policy(Statement=api_lambda_execute_statements)
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
api_lambda_code: Code = Code(
|
||||
S3Bucket=Ref(shared_config_bucket),
|
||||
S3Key=Join("", [API_LAMBDA_KEBAB_NAME, "/code/", API_LAMBDA_KEBAB_NAME, "-", "1", ".zip"])
|
||||
)
|
||||
|
||||
api_lambda: Function = template.add_resource(
|
||||
Function(
|
||||
API_LAMBDA_NAME + "Function",
|
||||
Code=api_lambda_code,
|
||||
Description=API_LAMBDA_NAME + " Function",
|
||||
Handler="request_handler.event_handler",
|
||||
Role=GetAtt(API_LAMBDA_NAME + "ExecuteRole", "Arn"),
|
||||
Runtime="python3.9",
|
||||
Timeout=300,
|
||||
MemorySize=1024
|
||||
)
|
||||
)
|
||||
|
||||
api_lambda_invoke_permission = template.add_resource(awslambda.Permission(
|
||||
"APILambdaPermission",
|
||||
Action="lambda:InvokeFunction",
|
||||
FunctionName=Ref(api_lambda),
|
||||
Principal="apigateway.amazonaws.com",
|
||||
SourceArn=Join("", ["arn:aws:execute-api:", Ref("AWS::Region"), ":", Ref("AWS::AccountId"), ":", Ref(rest_api), "/*/*/*"])
|
||||
))
|
||||
|
||||
rest_api_resource: Resource = template.add_resource(
|
||||
Resource(
|
||||
API_LAMBDA_NAME + "Resource",
|
||||
RestApiId=Ref(rest_api),
|
||||
PathPart="tweet",
|
||||
ParentId=GetAtt(REST_API_NAME, "RootResourceId")
|
||||
)
|
||||
)
|
||||
|
||||
api_lambda_method: Method = template.add_resource(
|
||||
Method(
|
||||
API_LAMBDA_NAME + "Method",
|
||||
DependsOn=API_LAMBDA_NAME + "Function",
|
||||
RestApiId=Ref(rest_api),
|
||||
AuthorizationType="NONE",
|
||||
ResourceId=Ref(rest_api_resource),
|
||||
HttpMethod="POST",
|
||||
Integration=Integration(
|
||||
Type="AWS",
|
||||
IntegrationHttpMethod="POST",
|
||||
IntegrationResponses=[IntegrationResponse(StatusCode="200")],
|
||||
Uri=Join(
|
||||
"",
|
||||
[
|
||||
"arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/",
|
||||
GetAtt(api_lambda, "Arn"),
|
||||
"/invocations"
|
||||
]
|
||||
)
|
||||
),
|
||||
MethodResponses=[MethodResponse("SuccessResponse", StatusCode="200")]
|
||||
)
|
||||
)
|
||||
|
||||
rest_api_deployment: Deployment = template.add_resource(
|
||||
Deployment(
|
||||
REST_API_STAGE_NAME + "Deployment",
|
||||
DependsOn=API_LAMBDA_NAME + "Method",
|
||||
RestApiId=Ref(rest_api)
|
||||
)
|
||||
)
|
||||
|
||||
rest_api_stage: Stage = template.add_resource(
|
||||
Stage(
|
||||
REST_API_STAGE_NAME + "Stage",
|
||||
StageName=REST_API_STAGE_NAME,
|
||||
RestApiId=Ref(rest_api),
|
||||
DeploymentId=Ref(rest_api_deployment)
|
||||
)
|
||||
)
|
||||
|
||||
template.add_output(
|
||||
[
|
||||
Output(
|
||||
"RestApiEndpoint",
|
||||
Value=Join(
|
||||
"",
|
||||
[
|
||||
"https://",
|
||||
Ref(rest_api),
|
||||
".execute-api.eu-west-1.amazonaws.com/",
|
||||
REST_API_STAGE_NAME,
|
||||
],
|
||||
),
|
||||
Description="Endpoint for this stage of the api",
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
s3_queue: Queue = templateUtil.create_queue(S3_QUEUE_NAME)
|
||||
tweeter_queue: Queue = templateUtil.create_queue(TWEETER_QUEUE_NAME)
|
||||
twitter_queue: Queue = templateUtil.create_queue(TWITTER_QUEUE_NAME)
|
||||
dynamo_db_queue: Queue = templateUtil.create_queue(DYNAMO_DB_QUEUE_NAME)
|
||||
|
||||
fanout_topic: Topic = template.add_resource(Topic(
|
||||
FANOUT_TOPIC_NAME,
|
||||
Subscription=[
|
||||
Subscription(
|
||||
Protocol="sqs",
|
||||
Endpoint=GetAtt(s3_queue, "Arn")
|
||||
),
|
||||
Subscription(
|
||||
Protocol="sqs",
|
||||
Endpoint=GetAtt(twitter_queue, "Arn")
|
||||
),
|
||||
Subscription(
|
||||
Protocol="sqs",
|
||||
Endpoint=GetAtt(dynamo_db_queue, "Arn")
|
||||
)
|
||||
]
|
||||
))
|
||||
|
||||
templateUtil.add_queue_policy_for_write_to_topic(
|
||||
s3_queue,
|
||||
"S3QueuePolicy",
|
||||
"AllowS3QueueToWriteToFanoutTopic",
|
||||
fanout_topic
|
||||
)
|
||||
|
||||
templateUtil.add_queue_policy_for_write_to_topic(
|
||||
twitter_queue,
|
||||
"TwitterQueuePolicy",
|
||||
"AllowTwitterQueueToWriteToFanoutTopic",
|
||||
fanout_topic
|
||||
)
|
||||
|
||||
templateUtil.add_queue_policy_for_write_to_topic(
|
||||
dynamo_db_queue,
|
||||
"DynamoDbQueuePolicy",
|
||||
"AllowDynamoDbQueueToWriteToFanoutTopic",
|
||||
fanout_topic
|
||||
)
|
||||
|
||||
print(template.to_json())
|
||||
|
Loading…
Reference in New Issue