Easy deployment & management of cloud apps

22
Easy Deployment & Management of Cloud Applications Dave Cunningham Software Engineer, Google Cloud Vail Computer Elements Workshop 2015-06-01

Transcript of Easy deployment & management of cloud apps

Page 1: Easy deployment & management of cloud apps

Easy Deployment & Managementof Cloud Applications

Dave CunninghamSoftware Engineer, Google Cloud

Vail Computer Elements Workshop2015-06-01

Page 2: Easy deployment & management of cloud apps

Overview

1. Intro to Cloud resource model

2. Intro to Terraform

3. Intro to Packer

4. Intro to Jsonnet

5. Application management(Fractal demo)

}

Page 3: Easy deployment & management of cloud apps

Resource: something that can be created / managed / referencedZone: failure domain

Examples...Instance: a virtual machinePersistent Disk: can be assigned to instances (more than 1 if read only)Image: data used to initialize a disk (e.g. Debian OS)Load balancer: forwards packets/requests to a target poolTarget pool: A dynamic group of instancesHealth check: A rule for auto-disqualifying broken instances in a poolAddress: can be assigned to an instance (1:1 NAT) or load balancer...

Cloud Terminology

Page 4: Easy deployment & management of cloud apps

Example: VM Instance API

Resources are represented as JSON objectse.g. Instance JSON describes:

● cores / RAM / scheduling policies / zone● attached disks, addresses● description / metadata / tags● startup script

Available operations:instances.insert(json)instances.delete(name)instances.get(name)instances.attach/detachDisk(name, json)instances.add/deleteAccessConfig(name, json) // change address...

All "providers" basically the same● GCP (Google)● AWS (Amazon)● Azure (Microsoft)● Digital Ocean● Rackspace● Openstack / cloudstack (on-prem)● ...

Page 5: Easy deployment & management of cloud apps

myservice.tf

apply

Resources

Forwarding Rule

ForwardingRule

Address

Disk

Route Firewall

Health Check

TargetPool

Network

Address

Instance

TargetPool

Address

Instance

Instance

InstanceInstanceInstance

Address

The first time:1. Builds plan

○ Ordered by Dependency

○ Parallelized2. Executes plan3. Writes local state file

Subsequent changes:1. Examine & refresh state2. Diff, build plan

○ Ordered by Dependency

○ Parallelized○ Minimally disruptive

3. Executes plan4. Updates local state file

Terraform By Hashicorphttp://www.terraform.io/

Provider & credentialsProvider & credentials

Page 6: Easy deployment & management of cloud apps

Build images, content defined by a JSON configuration file:

{ "builders": [{ "type": "googlecompute", "source_image": "debian-7-wheezy-v20140718", .. credentials .. }], "provisioners": [ { "type": "shell", "inline": [ "sudo apt-get update", "sudo apt-get install -y redis-server" ] }, ... ]}

Packer By Mitchell Hashimoto (Hashicorp founder)http://www.packer.io

Page 7: Easy deployment & management of cloud apps

Jsonnet https://google.github.io/jsonnet/doc/

Addresses the config language problem:

Write application

Simple config file

+ Comments + vars

+ String arith

+ conditionals+ repetition

+ int arith

Turing completeness!!1

+ templates

+ closures

+ user def. functions

Typical config language

Page 8: Easy deployment & management of cloud apps

"I don't know how to stop it, there was never any intent to write a programming language [...] I have absolutely no idea how to write a programming language, I just kept adding the next logical step on the way."

Rasmus Lerdorf (Author of PHP)

Page 9: Easy deployment & management of cloud apps

Hazards of ad-hoc language design:

Jsonnet https://google.github.io/jsonnet/doc/

Complex / surprising behaviorNo specification:

difficult to develop tools

Feature creep(overlapping

features)

Ugly implementation

Hard to improve / replace

implementation with same semantics

Hard to port implementation (e.g.

to Javascript)

Page 10: Easy deployment & management of cloud apps

Jsonnet https://google.github.io/jsonnet/doc/

// Trivial Example{ person1: { name: "Alice", welcome: "Hello " + self.name + "!", }, person2: self.person1 { name: "Bob" },}

{ "person1": { "name": "Alice", "welcome": "Hello Alice!" }, "person2": { "name": "Bob", "welcome": "Hello Bob!" }}

A configuration language designed like a programming language

● Simple: Just 9 features, (3 are from JSON)

○ Literals, arrays, objects, variables, conditionals, arithmetic, closures, mixins, errors

● Powerful: Multi-paradigm (supports OO and functional)

● Hermetic: Repeatable evaluation, code/data interchangeable

● Familiar: All syntax and semantics compatible with JSON / Python

● Concise: Code / data interleaving, prototype inheritance

● Formal: Complete operational semantics

Page 11: Easy deployment & management of cloud apps

Jsonnet configurationJsonnet

configurationJsonnet configuration

Micromanage

JSON

Blueprint(just data)

Packer

Terraform

Side-effects(deployment time)

No side-effects(elaboration time)

Local elaboration

"Micromanage"

(900 lines of Python glue)

Providers(AWS, Google, etc)

Can be verified with JSON Schema

Packer + Terraform provide:● Hybrid cloud support● Diff-update management model

"Glue" changes Terraform config in 2 subtle but impactful ways:

● Top-level services● Packer integration

Page 12: Easy deployment & management of cloud apps

Top-level services# Example Terraform config...{ provider: { /* credentials */ }, resource: { google_compute_address: { foo: { ... }, bar: { ... }, }, google_compute_forwarding_rule: { foo: { ... }, bar: { ... }, }, google_compute_health_check: { foo: { ... }, bar: { ... }, }, google_compute_instance: { foo-1: { ... }, foo-2: { ... }, bar-1: { ... }, bar-2: { ... },} } }

# Example blueprint { environment: { default: { /* credentials */ } } foo: { infrastructure: { google_compute_address: { "${-}": { ... } } google_compute_forwarding_rule: { "${-}": { ... } } google_compute_health_check: { "${-}": { ... }, } google_compute_instance: { "${-}-1": { ... }, "${-}-2": { ... }, } } }, bar: { ... }}

Compile to

Page 13: Easy deployment & management of cloud apps

Abstracting top-level services# App.jsonnetlocal LbPair = import "LbPair.jsonnet"; { foo: LbPair { BaseInstance+: { disk: {image: "foo-image"}, tags: ["foo"], "startup-script": ..., } }, bar: LbPair { BaseInstance+: { disk: {image: "bar-image"}, tags: ["bar"], "startup-script": ..., } },}

# LbPair.jsonnet{ BaseInstance:: { ... }, infrastructure: { google_compute_address: { "${-}": { ... } } google_compute_forwarding_rule: { "${-}": { ... } } google_compute_health_check: { "${-}": { ... }, } google_compute_instance: { "${-}-1": $.BaseInstance, "${-}-2": $.BaseInstance, } }}

Page 14: Easy deployment & management of cloud apps

Variants# Prod.jsonnetimport "App.jsonnet" { environment: { default: { /* credentials */ } }, bar+: { BaseInstance+: { machine_type: "n1-standard-4", } },}

# Dev.jsonnetimport "App.jsonnet" { environment: { default: { /* credentials */ } }, foo+: { BaseInstance+: { machine_type: "f1-micro", } },}

More interesting abstractions in the demo...

Page 15: Easy deployment & management of cloud apps

# Example terraform config fragmentgoogle_compute_instance: { myinst: { disks: [ { image: "myimage" } ] }},google_compute_disk: { mydisk: { image: "myimage" }}

Packer Integration

"myimage" must already exist

# Example terraform config fragmentgoogle_compute_instance: { myinst: { disks: [ { image: { source: "debian-wheezy", cmds: [ ... ] } } ] }},google_compute_disk: { mydisk: { image: { /*similarly */ } }}

● Image name chosen automatically by hashing confige.g. "micromanage-XXXXXXXXXXXX"

● Image built if it does not already exist● Unused images garbage-collected if older than n days

Also allow

● sh lines● file copies● dir copies

Page 16: Easy deployment & management of cloud apps

Packer Integration# Example terraform config fragmentgoogle_compute_instance: { myinst: { disks: [ { "image": { source: "debian-wheezy", cmds: [ ... ] } } ] cmds: [ ... ] # Same syntax, compiles to startup-script. }}

Images are frozen instances!

cmdcmdcmd---------- freeze image herecmdcmd

Tension: More in image => faster instance boot timeMore in instance => less likely to have to rebuild image

Best practice: Downloads / builds in the image cmdsSmall config files in the instance cmds

Page 17: Easy deployment & management of cloud apps

Application ServerApplication ServerApplication Server

Application ServerApplication ServerTile Generation Service

CassandraCassandra

Cassandra

HTTP

HTTP

Cassandra protocol

Live version: www.fractaldemo.com

Fractal Application Architecture

Page 18: Easy deployment & management of cloud apps

● Deploy & Manage complex web applications

● Declarative config at the lowest level

● Leverage OSS community: support all platforms

● Encourage micro-service architecture

● Build multiple layers of abstraction to hide complexity

● Allow complete control of low-level details if needed

Conclusions

Page 19: Easy deployment & management of cloud apps

Appendix

Page 20: Easy deployment & management of cloud apps

Use existing general purpose scripting language?

Write application

Simple config file

Python / Ruby / Lua / etc.

Jsonnet https://google.github.io/jsonnet/doc/

Not hermetic: Can yield different config in

different environment

Designed for specifying

behavior, not data

Code cannot be substituted with data

(side effects)

Heavyweight implementations

Page 21: Easy deployment & management of cloud apps

● Currently implementing instance "cmds" with startup-script

○ GCE has 32k limit for all files, AWS 16k

○ Have to base64 binary files

● Solution:

○ Push material into a GCS / S3 bucket

○ Filename is a hash of content

○ curl -s it to the instance from startup-script

Future Work

Page 22: Easy deployment & management of cloud apps

● Abstraction - say less

○ Build template libraries, factor out repetitive code

■ Both tilegen and appserv use Nginx + uWSGI + Flask

○ Override bits of default Nginx / uWSGI / Cassandra configs as needed

○ Higher level templates allow listing of apt packages, repos, keys, etc

○ Define variants with deep control and no repetition

● Synchronize details

○ Backend endpoints / credentials feature in

■ frontend / backend application config (packer configs)

■ infrastructure (metadata, firewalls, health checks, load balancer...)

Conclusions