saving money by optimizing your cloud add-on infrastructure
TRANSCRIPT
KLAUS IHLBERG TEAM LEAD • CONFLUENCE
Saving Money By Optimising Your Cloud Infrastructure
PATRICK STREULE ARCHITECT • ECOSYSTEM
Static Site
Static Add-onHTML
JSCSS
HTML
JSCSS
BrowserStatic HostingCDN
Host
API
Iframe bridge
JS (and REST) API
Caching
<script src="//d2q4nobwyhnvov.cloudfront.net/8c9e5743ca3d/editor.js"></script>
Version 1
<script src="//d2q4nobwyhnvov.cloudfront.net/7a8h273ac3c1/editor.js"></script>
Version 2
Cache-Control: public, max-age=31536000
Tell browser to cache for a year
Cache-Control: public, max-age=31536000
New version hash: No cache hit
Lifecycle Hooks JWT Opt-Out
No Yes
installable": {
"callbackUrl": "https://addon…", "allowRoom": true,
"allowGlobal": false
}
{
"key": "editor",
"title": {
"value": "Image editor"
},
"url": "https://image-editor…",
"authentication": "none" },
No Webhooks(or other server-side modules)
Scopes are still needed
No Yes
"webhook": {
"url": "https://addon…",
"event": "room_message",
"pattern": "something"
}
"hipchatApiConsumer": {
"scopes": [
"send_notification",
"view_room"
]
}
Free up to two add-onsIntegrated in BitbucketHosted on Aerobatic Automatic asset
versioning, CDN, SSLGit push deployments Yes, free!
Hosting
JSON Properties
var property = { key: "usage", value: { views: [ { date: "2016-08-26T03:35:57.138Z", views: 122, },{ date: "2016-08-27T03:35:57.138Z", views: 65, }
], users: [ { fullName: "Klaus Ihlberg", id: "kihlberg" }, { fullName: "Patrick Streule", id: "pstreule" } ] }, };
var property = { key: "usage", value: { views: [ { date: "2016-08-26T03:35:57.138Z", views: 122, },{ date: "2016-08-27T03:35:57.138Z", views: 65, }
], users: [ { fullName: "Klaus Ihlberg", id: "kihlberg" }, { fullName: "Patrick Streule", id: "pstreule" } ] }, };
Property Key
var property = { key: "usage", value: { views: [ { date: "2016-08-26T03:35:57.138Z", views: 122, },{ date: "2016-08-27T03:35:57.138Z", views: 65, }
], users: [ { fullName: "Klaus Ihlberg", id: "kihlberg" }, { fullName: "Patrick Streule", id: "pstreule" } ] }, };
Value Object
var property = { key: "usage", value: { views: [ { date: "2016-08-26T03:35:57.138Z", views: 122, },{ date: "2016-08-27T03:35:57.138Z", views: 65, }
], users: [ { fullName: "Klaus Ihlberg", id: "kihlberg" }, { fullName: "Patrick Streule", id: "pstreule" } ] }, };
Array of Page Views
var property = { key: "usage", value: { views: [ { date: "2016-08-26T03:35:57.138Z", views: 122, },{ date: "2016-08-27T03:35:57.138Z", views: 65, }
], users: [ { fullName: "Klaus Ihlberg", id: "kihlberg" }, { fullName: "Patrick Streule", id: "pstreule" } ] }, };
Array of Users
AP.request({ url: "/rest/api/content/" + contentId + “/property/usage", success: function(response) { var property = JSON.parse(response); console.log(property); } });
Connect AP.request Module
AP.request({ url: "/rest/api/content/" + contentId + “/property/usage", success: function(response) { var property = JSON.parse(response); console.log(property); } });
Content Property URL
with Content ID…
…and property key
AP.request({ url: "/rest/api/content/" + contentId + “/property/usage", success: function(response) { var property = JSON.parse(response); console.log(property); } });
Success function
GET /rest/api/content/{id}/property
GET /rest/api/space/{key}/property
GET /rest/api/2/issue/{id}/properties
GET /rest/api/2/project/{key}/properties
GET /rest/api/2/user/properties
GET /rest/atlassian-connect/1/addons/{add-on-key}/properties
Client-accessible backend services.
Pay for what you use.
Run short-lived backend code.
Don't pay for idle time.
Backend as a Service
Functions as a Service
Functions as a Service
time𝝺 𝝺𝝺
Invocation
Deployed, but not running
𝝺
Invocation
Started when called
𝝺
Stopped wheninactive
𝝺
May stay active across multiplecalls
Elastic ScalingLess OpsNo Infrastructure Cheap Pre-prod
Benefits
No base image updates, no instance
provisioning
Monitoring, deployment infrastructure etc. still
needed. Serverless != NoOps
Low-traffic dev and staging environments
don't add cost
Managed and automatic
Dev
Staging
Production
Start-up penaltyExpensive at scaleTooling
Less mature tooling for development,
deployment, debugging, …
Possibly cheaper to run instances and containers at scale
Increased latency on requests that spin up
the function
Downsides
AWS API GatewayAWS LambdaRuns the code.
Pay only for execution time
HTTP to Lambda gateway. Pay for # of
calls and data transfer.
What is being used?
Blueprint
/wolfram 1+1
API G
atew
ay
𝝺 Implementation
webhook
webhook response
Wolfram Lambda - 8:12 PM
1+1: 2
Deployed to AWS
Test dataBusiness Logic
Test helperAPI token config
Lambda entry pointDeployment
descriptor
Exclude files not
needed at runtime
Keep them as
low as possible
This is the
entry point POST /wolfram
This is theentry point
Reply to the HipChat web hook
Call Wolfram Alpha API
TransformAPI Result
(removed error handling)
Monthly cost?
2000 calls/month
Free calls to Wolfram Alpha API
API responses
10KB data per call+ =$0.01
AWS DynamoDBAWS API GatewayAWS LambdaRuns the code.
Pay only for execution time.
HTTP to Lambda gateway.
Pay for # of calls and data transfer.
Stores the data. Pay for storage and
access.
What is being used?
AerobaticHosts static assets.
Free for two add-ons.
Blueprint
Browser
git push
API G
atew
ay
𝝺 Implementation
Dyn
amoD
B
Aero
batic
iframe
webhook
data and assets
Static page, ajax call to /activity for data
Webhook called on every push
Base URL, replaced by Aerobatic
Monthly cost?
100'000 views/day
One query per view
One writeper commit
≈$15+ 20'000 commits/day
1KB data size+
Counters are small
Links
Wolfram Lambda Code: https://bitbucket.org/pstreule/wolfram-lambda
Commit Stats Code: https://bitbucket.org/pstreule/bb-activity-graph
Usage Tracking Code: https://bitbucket.org/kihlberg/usage-tracking