Skip to content

Instantly share code, notes, and snippets.

@plourenco
Created August 1, 2020 23:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save plourenco/0a942b23e3e4b7f76c47583b63d8ed0b to your computer and use it in GitHub Desktop.
Save plourenco/0a942b23e3e4b7f76c47583b63d8ed0b to your computer and use it in GitHub Desktop.
Using CodePipeline to automate serverless applications deployment
const express = require('express')
const app = express()
const port = 3000
const awsServerlessExpress = require('aws-serverless-express')
const server = awsServerlessExpress.createServer(app)
app.get('/', (request, response) => {
response.send('Hello Medium universe!');
});
app.listen(port, (err) => {
if (err) {
return console.log(err)
}
console.log('Server is listening on ${port}.')
});
exports.handler = (event, context) => { awsServerlessExpress.proxy(server, event, context) };
version: 0.2
phases:
install:
runtime-versions:
nodejs: 10
commands:
- echo Installing NPM dependencies...
- npm install
post_build:
commands:
- echo Build completed on `date`
artifacts:
files:
- '**/*'
discard-paths: no
name: app-$(date +%Y-%m-%d)
{
"Statement": [
{
"Action": [
"apigateway:*",
"codedeploy:*",
"lambda:*",
"cloudformation:CreateChangeSet",
"iam:GetRole",
"iam:CreateRole",
"iam:DeleteRole",
"iam:PutRolePolicy",
"iam:AttachRolePolicy",
"iam:DeleteRolePolicy",
"iam:DetachRolePolicy",
"iam:PassRole",
"s3:GetObjectVersion",
"s3:GetBucketVersioning"
],
"Resource": "*",
"Effect": "Allow"
}
],
"Version": "2012-10-17"
}
AWSTemplateFormatVersion: '2010-09-09'
Description: The backend serverless deployment
Parameters:
ProjectName:
Default: medium-demo
Type: String
BuildBucketName:
Type: String
BuildObjectKey:
Type: String
Resources:
# Api Gateway - responsible for exposing the lambda function as RESTful API to the Internet
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
StageName: live
DefinitionBody:
swagger: 2.0
info:
title: !Ref ProjectName
schemes:
- https
paths:
/:
x-amazon-apigateway-any-method:
produces:
- application/json
responses:
'200':
description: 200 response
schema:
$ref: "#/definitions/Empty"
x-amazon-apigateway-integration:
responses:
default:
statusCode: 200
uri:
Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdafunction.Arn}/invocations"
passthroughBehavior: when_no_match
httpMethod: POST
type: aws_proxy
options:
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: 200 response
schema:
$ref: "#/definitions/Empty"
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
contentHandling: CONVERT_TO_TEXT
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: when_no_match
requestTemplates:
application/json: "{\"statusCode\": 200}"
type: mock
/{proxy+}:
x-amazon-apigateway-any-method:
produces:
- application/json
parameters:
- name: proxy
in: path
required: true
type: string
responses: {}
x-amazon-apigateway-integration:
uri:
Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdafunction.Arn}/invocations"
httpMethod: POST
type: aws_proxy
options:
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: 200 response
schema:
$ref: "#/definitions/Empty"
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
contentHandling: CONVERT_TO_TEXT
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: when_no_match
requestTemplates:
application/json: "{\"statusCode\": 200}"
type: mock
x-amazon-apigateway-binary-media-types:
- "*/*"
# Lambda function - responsible for invoking your application server
lambdafunction:
Type: AWS::Serverless::Function
Properties:
AutoPublishAlias: live
Role: !GetAtt lambdarole.Arn
CodeUri:
Bucket:
Ref: BuildBucketName
Key:
Ref: BuildObjectKey
DeploymentPreference:
Role: !GetAtt DeployRole.Arn
Type: AllAtOnce
FunctionName: 'lambda-function'
Timeout: 30
Handler: app.handler
Runtime: nodejs8.10
lambdarole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
Policies:
- PolicyName: BasicLambda
PolicyDocument:
Version: "2012-10-17"
Statement: # Any permission you need inside the Lambda show be here
- Effect: Allow
Action:
- ec2:DescribeNetworkInterfaces
- ec2:CreateNetworkInterface
- ec2:DeleteNetworkInterface
Resource: "*"
LambdaApiGatewayExecutionPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt lambdafunction.Arn
Principal: apigateway.amazonaws.com
SourceArn: !Join
- ''
- - 'arn:aws:execute-api:'
- !Ref AWS::Region
- ":"
- !Ref AWS::AccountId
- ":"
- !Ref ApiGatewayApi
- "/*/*"
DeployRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${ProjectName}-DeployRole"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- codedeploy.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSCodeDeployRoleForLambda"
Policies:
- PolicyName: IAM
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- iam:GetRole
Resource: "*"
- PolicyName: Lambda
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- lambda:CreateFunction
- lambda:UpdateEventSourceMapping
- lambda:ListFunctions
- lambda:GetEventSourceMapping
- lambda:ListEventSourceMappings
- lambda:GetAccountSettings
- lambda:CreateEventSourceMapping
- lambda:DeleteEventSourceMapping
Resource: "*"
Outputs:
ApiUrl:
Description: Invoke API URL.
Value: !Join
- ''
- - https://
- !Ref ApiGatewayApi
- ".execute-api."
- !Ref AWS::Region
- ".amazonaws.com/live/"
Transform: AWS::Serverless-2016-10-31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment