Automating Testing with Open Source Tools.ppt - Confluence - Sakai
Automating Cloud Applications Using Open Source
-
Upload
signal -
Category
Technology
-
view
6.072 -
download
5
description
Transcript of Automating Cloud Applications Using Open Source
![Page 1: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/1.jpg)
Automating Life in the Cloud!
Joshua Buss, Matthew Kemp & Cody Ray!
![Page 2: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/2.jpg)
2
![Page 3: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/3.jpg)
Add more features!!!This widget is too slow!!!No more downtime!!!Weʼre losing potential customers in Asia!!
Use Case 0: Scalability and Reliability!Designing for the Cloud!
3
![Page 4: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/4.jpg)
Focus on scaling applications horizontally.!
Use Case 0: Scalability and Reliability!Scalability!
4
![Page 5: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/5.jpg)
Wikipedia Definition:!SOA as an architecture relies on service-orientation as its fundamental design principle. If a service presents a simple interface that abstracts away its underlying complexity, users can access independent services without knowledge of the service's platform implementation.!!Laymanʼs terms:!A complex system is broken into simple components that are able to interact with each other (and possibly outside sources).!
Use Case 0: Scalability and Reliability!Service Oriented Architecture!
5
![Page 6: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/6.jpg)
What is a Service in SOA?!
6
An independent unit that's composable with other components.!
Use Case 0: Scalability and Reliability!
Presenta(on (web, api, etc)
Business Logic
Data Access
Data Access
Business Logic
Data Access
Data Stores
![Page 7: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/7.jpg)
Use Case 0: Scalability and Reliability!Services at BrightTag!
7
database
stathub
datahub
ui database
tagserve
![Page 8: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/8.jpg)
When should you split services up?!
Use Case 0: Scalability and Reliability!Service Division of Labor!
8
![Page 9: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/9.jpg)
Keep failures self contained.!
Use Case 0: Scalability and Reliability!Design for Failure!
9
Release It! by Nyard is a great resource for stability patterns
![Page 10: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/10.jpg)
stathub database
database datahub tagserve
ui
Run a full stack in each region.!Use Case 0: Scalability and Reliability!Redundancy at BrightTag!
10
database
stathub
datahub
ui database
tagserve
![Page 11: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/11.jpg)
Services are over HTTP.!!Able to use standard tools and components without extra effort.!
Use Case 0: Scalability and Reliability!!
Load Balancers!
11
![Page 12: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/12.jpg)
Changes need to be allowed, but compatibility needs to be maintained.!!
Use Case 0: Scalability and Reliability!Backwards Compatibility!
12
![Page 13: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/13.jpg)
Need some data available in all regions, but keep inter-region communication to a minimum.!!
Case 1: Inter-Region Communication!Cross-Region Data Replication!
13
![Page 14: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/14.jpg)
Google's BigTable data model on Amazon's Dynamo infrastructure.!
Case 1: Inter-Region Communication!What is Cassandra?!
14
![Page 15: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/15.jpg)
Case 1: Inter-Region Communication!Cassandra Token Ring!
15
cassandra01 [0-‐63]
cassandra02 [64-‐127]
cassandra03 [128-‐191]
cassandra04 [192-‐255]
East
cassandra01 [1-‐64]
cassandra02 [65-‐128]
cassandra03 [129-‐192]
cassandra04 [193-‐0]
West
Key hashes to 157?
![Page 16: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/16.jpg)
Case 1: Inter-Region Communication!How Cassandra Writes!
16
cassandra01 [0-‐63]
cassandra02 [64-‐127]
cassandra03 [128-‐191]
cassandra04 [192-‐255]
East
cassandra01 [1-‐64]
cassandra02 [65-‐128]
cassandra03 [129-‐192]
cassandra04 [193-‐0]
West
Writes goes here.
![Page 17: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/17.jpg)
Cross region messaging over HTTPS with compression.!
Case 1: Inter-Region Communication!Cross Region Messaging (Hiveway)!
17
local hiveway
remote hiveway
Mes
sage
s
Mes
sage
s
![Page 18: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/18.jpg)
Use Case 2: Zero Downtime Builds!Smooth Code Pushes!
18
![Page 19: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/19.jpg)
Easy migrations and upgrade path.!
Can be more expensive.!
Use Case 2: Zero Downtime Builds!Mirror Environment Cutover!
19
![Page 20: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/20.jpg)
More complicated migrations and upgrades.!!Longer deploy window.!!Usually cheaper.!!
Use Case 2: Zero Downtime Builds!Rolling Deploy!
20
![Page 21: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/21.jpg)
for region in regions: for app in apps: for server in region: if app on server: maintenance app scp new code to <deployment_tag> dir symlink app/current to app/<deployment_tag> restart app wait for healthy!
Use Case 2: Zero Downtime Builds!Fabric Pseudocode!
21
![Page 22: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/22.jpg)
Use Case 2: Zero Downtime Builds!!
Health Checks at BrightTag!
22
Standardized health checks across services.!!!$ curl -‐si 'http://service/bthc' HTTP/1.1 204 No Content $ curl -‐si 'http://service/bthc?action=maint' HTTP/1.1 500 Internal Server Error Connection: close Content-‐Length: 5 MAINT
![Page 23: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/23.jpg)
At a glance environment health.!Use Case 2: Zero Downtime Builds!Keeping an Eye on the Pulse!
23
![Page 24: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/24.jpg)
Provide multiple modes of operation.!
Use Case 2: Zero Downtime Builds!Runtime Controls!
24
![Page 25: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/25.jpg)
Use Case 3: Generating /etc/hosts Connectivity
![Page 26: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/26.jpg)
Use Case 3: Generating /etc/host What is Zerg?!
26
+ =
![Page 27: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/27.jpg)
DRIVER_MAPPING = { "dev": { "office": get_driver(Provider.EUCALYPTUS)( DEV_ID, secret=DEV_KEY, host="openmaster", port=8773, secure=False, path="/services/Cloud") }, "prod": { "us-‐east-‐1": get_driver(Provider.EC2_US_EAST)(PROD_ID, PROD_KEY), "eu-‐west-‐1": get_driver(Provider.EC2_EU_WEST)(PROD_ID, PROD_KEY) } }
@app.route("/hosts/<env>/<region>") def hosts(env, region): hosts = DRIVER_MAPPING[env][region].list_nodes() return str([d.extra['private_dns'] for host in hosts])
!
Use Case 3: Generating /etc/hosts Flask and libcloud Working Together!
27
![Page 28: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/28.jpg)
@app.route("/etchosts/<env>/<region>") def etchosts(env, region): driver = DRIVER_MAPPING[env][region] sorted_nodes = sorted((node.name, node.private_ips, node.public_ips) for node
in driver.list_nodes()) hosts = [{'private_ip':private_ips[0], 'name':name, 'public_ip':public_ips[0]}
for (name, private_ips, public_ips) in sorted_nodes] response = render_template('etc_hosts.txt', hosts=hosts) return Response(response, content_type='text/plain')
Template:!# The following lines are desirable for IPv6 capable hosts ::1 ip6-‐localhost ip6-‐loopback
{% for host in hosts %} {{ "%-‐21s%-‐21s# External: %s"|format(host.private_ip, host.name,
host.public_ip) }} {%-‐ endfor %}
Use Case 3: Generating /etc/hosts The Zerg Code!
28
![Page 29: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/29.jpg)
$ curl –s 'http://zerg/etchosts/prod/eu-west-1'
# The following lines are desirable for IPv6 capable hosts"
::1 ip6-localhost ip6-loopback
10.0.0.10 server01 # External: 123.123.123.123
10.0.0.11 server02 # External: 123.123.123.124
10.0.0.12 server03 # External: 123.123.123.125
10.0.0.13 server04 # External: 123.123.123.126
10.0.0.14 server05 # External: 123.123.123.127
10.0.0.15 server06 # External: 123.123.123.128
Use Case 3: Generating /etc/hosts !
The Zerg HTTP Response!
29
![Page 30: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/30.jpg)
# Set variables read -‐r -‐d '' STATIC_HOSTS << static_hosts # The following lines are included by default 127.0.0.1 localhost # DO NOT EDIT THIS COMMENT -‐ everything after this line is managed by zerg! static_hosts cp /etc/hosts ${TMPDIR}/old_hosts grep -‐B 5000000 '# DO NOT' ${TMPDIR}/old_hosts >> ${TMPDIR}/static_hosts cp ${TMPDIR}/static_hosts ${TMPDIR}/new_hosts wget -‐qO-‐ "http://${ZERG_IP}/etchosts/${E}/${R}" >> ${TMPDIR}/new_hosts && if [[ $(diff ${TMPDIR}/new_hosts /etc/hosts | wc -‐l | awk '{print $1}') < 7
|| ${FORCE} == '-‐-‐force' ]]; then cp ${TMPDIR}/new_hosts /etc/hosts; fi
Use Case 3: Generating /etc/hosts The bash update_hosts.sh script!
30
![Page 31: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/31.jpg)
Update timing tricky to get right!
Too important to leave completely autonomous!
Use Case 4: Generating Load Balancer Configuration!Configuring Load Balanced Services!
31
![Page 32: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/32.jpg)
Need a rock-solid foundation to deploy onto.
Use Case 4: Generating Load Balancer Configuration!Consistency > *
![Page 33: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/33.jpg)
Set environment per-instance: /etc/puppet/puppet.conf
Symlink /etc/puppet/environments/ on master to various git checkouts of the source:
$ cd /etc/puppet/environments $ ln –s ~/src/puppet/prod_stable prod_stable $ ln –s ~/src/puppet/dev_stable dev_stable $ ln –s ~/src/puppet/dev_test dev_test
Use cron to keep all branches up-to-date
Use Case 4: Generating Load Balancer Configuration!Single Puppet Master
![Page 34: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/34.jpg)
Each environment has its own branch.
Make a new branch for every new feature.
Merge into a test branch to test.
Merge into stable.
Use Case 4: Generating Load Balancer Configuration!Source Controlled Puppet Configs
![Page 35: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/35.jpg)
APP_DEFS : { "zerg": { "type": "http", "healthcheck": {"port": 19999, "resource": "/zerghealth"} }, "awesome": { "type": "http", "healthcheck": {"port": 20000, "resource": "/ahc"}, "frontend" : "10080" }, "haproxy_awesome":{ "type": "http", "healthcheck": {"port": 20001, "resource": "/"} }, "foo": { "type": "http", "healthcheck": {"port": 20002, "resource": "/"}, "frontend" : "10081" }, "mashed_potatoes": { "type": "http", "healthcheck": {"port": 20003, "resource": ”/"}, "frontend" : "10082" }, "haproxy_foo": { "type": "http", "healthcheck": {"port": 20004, "resource": "/hc"} }, "thehardproblem": { "type": "http", "healthcheck": {"port": 20006, "resource": "/"} }, "redis": { "type": "tcp", "healthcheck": {"port": 20007, "resource": "/rhc"} }, "dataserver": { "type": "http", "healthcheck": {"port": 20008, "resource": "/"} }, "frontend" : "10083" }, "itshards":{ "type": "http", "healthcheck": {"port": 20009, "resource": "/"} }, "devnull": { "type": "http", "healthcheck": {"port": 200010, "resource": "/hc"} } }
Use Case 4 – Load Balancer Configs!The App Definitions in Zerg!
35
![Page 36: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/36.jpg)
@app.route("/haproxy/<env>/<region>/<type>") def haproxy(env, region, type): instances = get_region_manifest(region) apps = {} for app in APP_DEFS[env]: if 'frontend' in APP_PORTS[env][app].keys(): app_object = { 'servers':[], 'backend_port': APP_PORTS[env][app]['healthcheck']['port'], 'frontend_port': APP_PORTS[env][app]['frontend'] } for server in instances: if app in instances[server]['roles']: app_object['servers'].append({'name':server, 'details':instances[server]}) apps[app] = app_object return render_template('haproxy_%s_%s_%s.txt' % (env, region, type), vips=apps)
Use Case 4 – Load Balancer Configs!The Zerg Code!
36
![Page 37: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/37.jpg)
global blah blah defaults blah blah frontend dataserver_vip bind *:{{ vips.dataserver.frontend_port }} default_backend dataserver frontend mashed_potatoes_vip bind *:{{ vips.mashed_potatoes.frontend_port }} default_backend mashed_potatoes backend dataserver balance roundrobin {%-‐ for server in vips.dataserver.servers %} server {{ server['name'] }} {{ server.details['private ip'] }}:{{ vips.dataserver.backend_port }} check {%-‐ endfor %} backend mashed_potatoes balance roundrobin {%-‐ for server in vips.mashed_potatoes.servers %} server {{ server['name'] }} {{ server.details['private ip'] }}:{{ vips.mashed_potatoes.backend_port }} check {%-‐ endfor %}
Use Case 4 – Load Balancer Configs!The Zerg Flask Template!
37
![Page 38: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/38.jpg)
$ curl –s http://zerg/haproxy/<env>/<region>/<type>
globals and defaults blah blah frontend dataserver_vip
bind *:10083 default_backend dataserver frontend mashed_potatoes_vip
bind *:10082 default_backend mashed_potatoes
backend dataserver
blah blah options server dataserv01 10.0.0.28:20008 check server dataserv02 10.0.0.29:20008 check
backend mashed_potatoes
blah blah options server taters01 10.0.0.30:20003 check server taters02 10.0.0.31:20003 check
Use Case 4 – Load Balancer Configs!The Zerg HTTP Response!
38
![Page 39: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/39.jpg)
Use Case 4 – Load Balancer Configs!The Config Workflow!
39
Large changes to templates (human)
Git (ops)
Zerg (genera(on)
Script (human)
Git (puppet)
Server Server Server
![Page 40: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/40.jpg)
./update_haproxy.sh <env> <region> <service> ** Git is clean and in sync with origin.. now waiting for zerg http response.. [prod_stable 012345] [puppet] Haproxy Auto-‐Commit for <env> <region> <service> 1 files changed, 2 insertions(+), 2 deletions(-‐) ** Template pulled and committed ** Here is the diff from origin to the new version: diff -‐-‐git a/modules/haproxy/templates/haproxy_<env>_<region>_<service>_cfg.erb b/modules/haproxy/templates/haproxy_<env>_<region>_<service>_cfg.erb -‐-‐-‐ a/modules/haproxy/templates/haproxy_prod_us-‐east-‐1_tagserve_cfg.erb +++ b/modules/haproxy/templates/haproxy_prod_us-‐east-‐1_tagserve_cfg.erb -‐ server oldandslow01 10.0.0.23:20003 check -‐ server oldandslow02 10.0.0.24:20003 check + server taters01 10.0.0.30:20003 check + server taters01 10.0.0.31:20003 check ** Do you want to push this change? (y/n) y blah blah successful git push message ** Commit successfully pushed to origin ** All done!
Use Case 4 – Load Balancer Configs!The bash update_haproxy.sh script!
40
![Page 41: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/41.jpg)
Alerting, Monitoring & Visualization!!
Use Case 5: Dashboards & Alerting!!
What's really going on?!
41
![Page 42: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/42.jpg)
Identify metrics that act as signals.!!Add alerts after every incident.!
Use Case 5: Dashboards & Alerting!What to monitor?!
42
![Page 43: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/43.jpg)
Use Case 5: Dashboards & Alerting!Metric Polling at BrightTag!
43
graphite carbon mpoller
tagserve haproxy
datahub redis
cassandra
graphite carbon
tagserve haproxy mpoller
datahub redis
mpoller cassandra mpoller
![Page 44: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/44.jpg)
Storage of historical metrics allows for trending and comparisons.!!Aggregation is performed on data retrieval via the webapp.!
Use Case 5: Dashboards & Alerting!Graphite!
44
![Page 45: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/45.jpg)
Expose a "metrics" service per region.!!Enables a flexible topology.!!
Use Case 5: Dashboards & Alerting!Branches and Leaves!
45
![Page 46: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/46.jpg)
Use Case 5: Dashboards & Alerting!Metric Aggregation at BrightTag!
46
tagserve haproxy
datahub redis
cassandra metrics
metrics metrics
dashboard
![Page 47: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/47.jpg)
Use Case 5: Dashboards & Alerting!Realtime Numbers Across Regions!
47
Requests are farmed out to each metrics service.
![Page 48: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/48.jpg)
Different visualizations tell you different things.!Use Case 5: Dashboards & Alerting!!
Visualization!
48
![Page 49: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/49.jpg)
Tattle allows us to alert on any metric in Graphite.!!Alerting is done per region.!
Use Case 5: Dashboards & Alerting!Alerting!
49
![Page 50: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/50.jpg)
Fabric is push, puppet is pull.!!Businesses don't move as fast as infrastructure changes, but configs have to stay up to date all the time.!
(/etc/hosts) (systempoller.py) (mashed_potatoes.env) (dataserver.war)
puppet ===================================== fabric (real-‐time up-‐to-‐date) (moderately up-‐to-‐date) (weekly)
!
Deployment!Fabric vs Puppet!
50
![Page 51: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/51.jpg)
Have to go with what cloud provider offers.!!Not always ideal for every workload.!
Designing for the Cloud!Virtual Machines!
51
![Page 52: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/52.jpg)
(but if you find one let us know)!There are no Silver Bullets!
52
![Page 53: Automating Cloud Applications Using Open Source](https://reader031.fdocuments.us/reader031/viewer/2022020207/54c381a14a79598b558b456d/html5/thumbnails/53.jpg)
Questions?!
53