Slide 1

Slide 1 text

.co.il www. Serverless Architecture

Slide 2

Slide 2 text

.co.il www.

Slide 3

Slide 3 text

.co.il www.

Slide 4

Slide 4 text

.co.il www.

Slide 5

Slide 5 text

.co.il www. www.devops.co.il Evgeny Zislis on.fb.me/Ops-IL

Slide 6

Slide 6 text

.co.il www. dvps.me/martinfowler-bliki-serverless

Slide 7

Slide 7 text

.co.il www. cpu memory I/O time keeping customer box Why am I doing repetitive work here? :( I will be rich soon!

Slide 8

Slide 8 text

.co.il www. I'm watching you!

Slide 9

Slide 9 text

.co.il www.

Slide 10

Slide 10 text

.co.il www. Case Study

Slide 11

Slide 11 text

.co.il www.

Slide 12

Slide 12 text

.co.il www.

Slide 13

Slide 13 text

.co.il www. JavaScript / ECMAScript 6 + AWS SDK ○ Usable in browser, backend, lambda ○ Plenty of programmers and freelancers ○ Avoid variability

Slide 14

Slide 14 text

.co.il www. API Gateway Cognito S3 SNS SQS IAM ElastiCache DynamoDB Backend Services

Slide 15

Slide 15 text

.co.il www. S3 Web Applications ○ Vue.js ○ S3 as web server ○ CloudFront CDN

Slide 16

Slide 16 text

.co.il www. Deploy Web Assets ○ Atlassian BitBucket Pipelines (free, fast) ○ minimal babel compile ○ execute transpiled tests ○ Upload to S3

Slide 17

Slide 17 text

.co.il www. # package.json { ... "scripts": { "build": "babel src -d dist/src && babel test -d dist/test", "build:test": "tap -Rspec --cov \"dist/test/**/*.test.js\"", }, } CI / CD

Slide 18

Slide 18 text

.co.il www. CI / CD # bitbucket-pipelines.yml --- image: kopterio/node-yarn:7.7 pipelines: default: - step: script: - yarn - npm run -s build - npm run -s build:test

Slide 19

Slide 19 text

.co.il www. Authenticate with Service ● Cognito ● Vue-Auth-Cognito OSS

Slide 20

Slide 20 text

.co.il www.

Slide 21

Slide 21 text

.co.il www.

Slide 22

Slide 22 text

.co.il www.

Slide 23

Slide 23 text

.co.il www. $context $context.identity.cognitoIdentityId $context.requestId docs.aws.amazon.com/apigateway/latest/developerguide/ api-gateway-mapping-template-reference.html

Slide 24

Slide 24 text

.co.il www.

Slide 25

Slide 25 text

.co.il www. aws apigateway put-rest-api \ --rest-api-id 1234123412 \ --mode overwrite \ --body 'file:///path/to/API_Swagger_template.json' \ --region us-west-2 aws apigateway put-rest-api \ --rest-api-id 1234123412 \ --mode merge \ --body 'file:///path/to/API_Swagger_template.json' \ --region us-west-2

Slide 26

Slide 26 text

.co.il www. /: &path_with_cors options: summary: CORS Response responses: 200: description: Stub CORS response headers: &cors_headers Access-Control-Allow-Origin: { type: string } Access-Control-Allow-Methods: { type: string } Access-Control-Allow-Headers: { type: string } schema: $ref: "#/definitions/Empty" x-amazon-apigateway-integration: passthroughBehavior: "never" type: "mock" responses: default: statusCode: 200 responseParameters: &cors_response_params method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'" method.response.header.Access-Control-Allow-Headers: "'Content-Type, ... '" method.response.header.Access-Control-Allow-Origin: "'*'" requestTemplates: application/json: '{"statusCode": 200}' none of that nonsense ... docs.aws.amazon.com /apigateway/latest/ developerguide/how-to-cors.html

Slide 27

Slide 27 text

.co.il www. /v1/audit/aws: <<: *path_with_cors get: summary: Get the audit log. security: - kopter.io: [] parameters: - $ref: '#/parameters/authorization' - $ref: '#/parameters/identityId' - $ref: '#/parameters/requestId' responses: 200: description: An array of audit log events headers: <<: *cors_headers schema: $ref: '#/definitions/AuditLogEvents' 520: description: Error response schema: $ref: '#/definitions/Error' x-amazon-apigateway-integration: requestParameters: integration.request.header.authorization: "'Basic $nginx_auth'" integration.request.header.identityId: "context.identity.cognitoIdentityId" integration.request.header.requestId: "context.requestId" responses:

Slide 28

Slide 28 text

.co.il www. Backend API x

Slide 29

Slide 29 text

.co.il www. Kopter AWS account Process Customer AWS Events CloudTrail S3 Customer AWS account SNS SQS ECS DynamoDB Elastic Beanstalk

Slide 30

Slide 30 text

.co.il www.

Slide 31

Slide 31 text

.co.il www. app.post('/', sqsHandler); app.post('/cron', cronHandler); export async function sqsHandler(req, res) { const queueName = req.get('X-Aws-Sqsd-Queue'); try { switch (queueName) { case process.env.AGGREGATOR_QUEUE_NAME: await new Aggregator(req.body).start(); break; case process.env.CLOUD_TRAIL_INGEST_QUEUE_NAME: await new CloudTrailIngest(req.body).start(); break; default: throw new Error(`no worker found with X-Aws-Sqsd-Queue: ${queueName}`); } } catch (error) { log.error(error); res.status(500).send({}); } res.status(200).send({}); }

Slide 32

Slide 32 text

.co.il www. cron.yaml version: 1 cron: - name: "backup-job" url: "/cron/backup" schedule: "0 */12 * * *" - name: "audit" url: "/cron/audit" schedule: "0 23 * * *"

Slide 33

Slide 33 text

.co.il www.

Slide 34

Slide 34 text

.co.il www. EC2 Events Queue kopter workers Describer Cron EC2 Describer Aggregator Cron SNS *Hourly* CRON Aggregator *Hourly* CRON EC2 Pricing *Hourly* CRON EC2 Describer ? ? CloudTrail Ingest sqsd AWS Accounts sqsd Aggregator Queue sqsd Aggregator sqsd EC2 Pricing Audit Log Queue sqsd Audit Logs Frontend Notifications sqsd Frontend Notifications CloudTrail Ingest EC2 Snapshots EC2 Pricing Backend API sqsd Describer Queue sqsd EC2 Events Price Graph Data Audit Logs Frontend Notifications Frontend Notifications Global ? Legend DB Table Queue Worker sqsd kopter workers kopter workers ᵣ function

Slide 35

Slide 35 text

.co.il www. Lambda $$$$$ $$$$ $$$ $$ $

Slide 36

Slide 36 text

.co.il www. nodejs.org/en/blog/uncategorized/profiling-node-js/

Slide 37

Slide 37 text

.co.il www. export class Handler { static async start() { const queueUrl = process.env.AGGREGATOR_QUEUE_URL; const message = await sqsCheck(queueUrl); await new Aggregator(message).start(); await sqsDeleteMessage(queueUrl, message); } } export async function handler(event, context, callback) { try { await Handler.start(); callback(); } catch (error) { callback(error); } }

Slide 38

Slide 38 text

.co.il www. DynamoDB permissions

Slide 39

Slide 39 text

.co.il www. Version: '2012-10-17' Statement: - Sid: AllowAccessToOnlyItemsMatchingUserID Effect: Allow Action: - dynamodb:GetItem - dynamodb:Query Resource: - arn:aws:dynamodb:us-west-2:123456789012:table/GameScores Condition: ForAllValues:StringEquals: dynamodb:LeadingKeys: - "${www.amazon.com:user_id}" dynamodb:Attributes: - UserId - GameTitle - Wins - Losses - TopScore - TopScoreDateTime StringEqualsIfExists: dynamodb:Select: SPECIFIC_ATTRIBUTES

Slide 40

Slide 40 text

.co.il www. Version: '2012-10-17' Statement: - Sid: LimitAccessToSpecificAttributes Effect: Allow Action: - dynamodb:UpdateItem - dynamodb:GetItem - dynamodb:Query - dynamodb:BatchGetItem - dynamodb:Scan Resource: - arn:aws:dynamodb:us-west-2:123456789012:table/GameScores Condition: ForAllValues:StringEquals: dynamodb:Attributes: - UserId - TopScore StringEqualsIfExists: dynamodb:Select: SPECIFIC_ATTRIBUTES dynamodb:ReturnValues: - NONE - UPDATED_OLD - UPDATED_NEW

Slide 41

Slide 41 text

.co.il www. --- Version: '2012-10-17' Statement: - Action: - s3:ListBucket Effect: Allow Resource: - arn:aws:s3:::mybucket Condition: StringLike: s3:prefix: - "${cognito-identity.amazonaws.com:sub}/*" - Action: - s3:GetObject - s3:PutObject Effect: Allow Resource: - arn:aws:s3:::mybucket/${cognito-identity.amazonaws.com:sub}/* S3 permissions

Slide 42

Slide 42 text

.co.il www. DynamoDB scaling aws.amazon.com/blogs/aws/auto-scale-dynamodb-with-dynamic-dynamodb/

Slide 43

Slide 43 text

.co.il www. ElastiCache "FNR4GZ675EW5UXJW" : { "FNR4GZ675EW5UXJW.JRTCKXETXF" : { "offerTermCode" : "JRTCKXETXF", "sku" : "FNR4GZ675EW5UXJW", "effectiveDate" : "2015-10-01T00:00:00Z", "priceDimensions" : { "FNR4GZ675EW5UXJW.JRTCKXETXF.6YS6EN2CT7" : { "rateCode" : "FNR4GZ675EW5UXJW.JRTCKXETXF.6YS6EN2CT7", "rateType" : "Fixed", "description" : "$0.044 per RDS T2 Small Instance hour (or partial hour) running SQL Server EX - LI", "beginRange" : "0", "endRange" : "Inf", "unit" : "Hrs", "pricePerUnit" : { "USD" : "0.0440000000" AWS EC2 Pricing API ~ 100mb aws.amazon.com/blogs/aws/new-aws-price-list-api/

Slide 44

Slide 44 text

.co.il www. Thank you! Join Operations Israel community on on.fb.me/Ops-IL www.devops.co.il

Slide 45

Slide 45 text

.co.il www. Join Operations Israel community on on.fb.me/Ops-IL www.devops.co.il

Slide 46

Slide 46 text

.co.il www.