SlideShare a Scribd company logo
ç
INCREMENTALISM
An Industrial Strategy For Adopting Modern Automation
MONOCULTURE
TROUBLEMAKER
RDBMS ARE RAD
OPERATOR AND ENGINEER
BACKGROUND
MONOCULTURE
TROUBLEMAKER
RDBMS ARE RAD
OPERATOR AND ENGINEER
BACKGROUND
Industrial Techno Revolution
Development and Operational Practices
1. Development Practices
2. Secrets Management
3. Packaging
4. Developer-centric, Self-Healing Applications
5. Data Center Aware Services
6. Infrastructure Manipulation
YOU ARE A BIT-CHUCKING TECHNO INDUSTRIALIST.
DATA CENTERS ARE YOUR FACTORIES.
NETWORKS ARE YOUR ROADS.
YOU APP PRODUCES WIDGETS.
MICROSERVICES ARE YOUR ROBOTS ON THE FACTORY LINE.
YOU ARE A BIT-CHUCKING TECHNO INDUSTRIALIST.
WIDGET SHIPPING
^
REDUNDANCY
CRITICAL INFRASTRUCTURE
PROFILE MESSAGES UPSELL CART RELATED COMMENTSSOCIAL
HTML/JSON/gRPC
Response
Response
Microservices
HTML/JSON/gRPC
Response
MYAPP
• New program!
• Use a piece of user data
• Talks to a database
• Returns something useful
• Highly-Available
• Self-Healing
• Feedback
• New program!
• Use a piece of user data
• Talks to a database
• Returns something useful
• Highly-Available
• Self-Healing
• Feedback
BUSINESS VALUE
• New program!
• Use a piece of user data
• Talks to a database
• Returns something useful
• Highly-Available
• Self-Healing
• Feedback
INPUT
• New program!
• Use a piece of user data
• Talks to a database
• Returns something useful
• Highly-Available
• Self-Healing
• Feedback
DEPENDENCY
• New program!
• Use a piece of user data
• Talks to a database
• Returns something useful
• Highly-Available
• Self-Healing
• Feedback
PROPERTIES OF

THE APPLICATION
• New program!
• Use a piece of user data
• Talks to a database
• Returns something useful
• Highly-Available
• Self-Healing
• Feedback
VALUE
• New program!
• Use a piece of user data
• Talks to a database
• Returns something useful
• Highly-Available
• Self-Healing
• Feedback
DISTRACTING,
REQUIRED,
NECESSARY COMPLEXITY
• New program!
• Use a piece of user data
• Talks to a database
• Returns something useful
• Highly-Available
• Self-Healing
• Feedback
WIDGET
• New program!
• Use a piece of user data
• Talks to a database
• Returns something useful
• Highly-Available
• Self-Healing
• Feedback
INDUSTRIAL COMPUTING
RAW MATERIAL
REDUNDANT ROBOTS
REPLACEABLE PARTS
QUALITY-MANAGEMENT
WIDGET
STORAGE
MY RESULT
MYAPP
Codified Development Environment
Reproducible Dev Environments
Disposable R&D Workspace
Shared Developer Workspace
Developer-driven Infrastructure
Terminal
$ $EDITOR Vagrantfile
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.box_url = "https://cloud-images.ubuntu.com/
xenial/current/xenial-server-cloudimg-amd64-vagrant.box"
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.provision "shell", path: "setup.sh"
end
$ cat setup.sh
apt-get install postgresql-server tmux
Terminal
my-laptop$ vagrant up --destroy-on-error
my-laptop$ vagrant ssh
vm$ uname -a | tee /vagrant/uname.out
Linux compton 2.6.24-19-server #1 SMP Sat Jul 12 00:40:01
UTC 2008 i686 GNU/Linux
vm$ logout
Shared connection to 192.168.39.130 closed.
my-laptop$ cat uname.out
Linux compton 2.6.24-19-server #1 SMP Sat Jul 12 00:40:01
UTC 2008 i686 GNU/Linux
Terminal
$ $EDITOR Vagrantfile
Vagrant.configure("2") do |config|
config.ssh.shell = "sh"
config.vm.synced_folder ".", "/vagrant", nfs: true, id:
"vagrant-root"
end
Terminal
my-laptop$ $EDITOR myapp.go
my-laptop$ GOOS=linux GOARCH=amd64 go build -o myapp-linux
my-laptop$ GOOS=freebsd GOARCH=amd64 go build -o myapp-freebsd
my-laptop$ vagrant ssh
vm$ /vagrant/myapp-linux
vm$ logout
my-laptop$ vagrant up freebsd-vm1
my-laptop$ vagrant ssh freebsd-vm1
freebsd-vm1$ /vagrant/myapp-freebsd
freebsd-vm1$ logout
$HOME/go/src/github.com/hashicorp/myapp/Vagrantfile
Secret Sprawl
Break Glass Procedures
Audit Logs
Secrets Lifecycle Management
"I want to deploy this app to prod. Password-less logins are disabled on
the databases! Now what?"
"I want to deploy this app to prod. Password-less logins are disabled on
the databases! Now what?"
Private GitHub repo
Commit passwords inline in SCM
Switch creds based on $HOSTNAME?
Establish a protocol for acquiring credentials at runtime
Terminal
$ vault read postgresql/creds/readonly
Key Value
--- -----
lease_id postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6
lease_duration 1h0m0s
lease_renewable true
password f8a93086-b11d-10cd-8795-f537a10de712
username token-9e57c18f-ac99-8e29-48f2-3fb09066d2b4
Terminal
$ VAULT_ADDR=http://vault.service.consul vault read postgresql/creds/readonly
Key Value
--- -----
lease_id postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6
lease_duration 1h0m0s
lease_renewable true
password f8a93086-b11d-10cd-8795-f537a10de712
username token-9e57c18f-ac99-8e29-48f2-3fb09066d2b4
Terminal
$ psql -U postgres
psql (9.6.1)
Type "help" for help.
postgres=# du
Role name | Attributes | Member of
-------------------------------------------+--------------------------+------------
postgres | Superuser, Create ... | {}
token-9e57c18f-ac99-8e29-48f2-3fb09066d2b4 | Password valid until ... | {}
Terminal
$ vault renew postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6
Key Value
--- -----
lease_id postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6
lease_duration 1h0m0s
lease_renewable true
Terminal
$ cat myapp-db-config.yml.ctmpl
---
{{- with secret "postgresql/creds/readonly" }}
username: "{{ .Data.username }}"
password: "{{ .Data.password }}"
database: "myapp"
{{- end }}
$ consul-template -template="myapp-db-config.yml.ctmpl:myapp-db-config.yml" ./myapp
<CTRL+C>
Received interrupt, cleaning up...
Terminal
$ vault write postgresql/roles/readonly 
sql="CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO "{{name}}";"
Success! Data written to: postgresql/roles/readonly
Terminal
$ tee my-policy.vault | vault write postgresql/roles/readonly sql=-
CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO "{{name}}";
Success! Data written to: postgresql/roles/readonly
v2.0.0
Codified Build Environment
Reproducible Packaging
Shared Packaging Instructions
Developer-driven Build and Packaging Steps
compile.json 1/3
{
"builders": [{
"name": "myapp",
"type": "docker",
"image": "centos:6",
"commit": true,
"privileged": true
}],
"provisioners": [
{
"type": "file",
"source": "myapp-linux",
"destination": "/usr/local/bin/myapp"
},
{
"type": "file",
"source": "local-config-file.repo",
"destination": "/usr/local/etc/myapp.conf"
},
{
"type": "file",
"source": "start_myapp.sh",
"destination": "/sbin/start_myapp"
},
compile.json 2/3
{
"type": "shell",
"inline": [
"/usr/bin/yum -y update",
"/usr/bin/yum -y install util-linux-ng patch",
"/bin/chmod 0600 /usr/local/etc/myapp.conf",
"/bin/chmod 0744 /sbin/start_myapp /usr/local/bin/myapp-linux",
"/usr/bin/curl -o /usr/local/etc/some-ca.crt https://host.example.com/pki/
ca.crt",
]
}
],
"post-processors": [
[
{
"type": "docker-tag",
"repository": "myorg/myapp"
},
{
"type": "docker-save",
"path": "myapp.tar"
},
compile.json 3/3
{
"type": "artifice",
"files": ["myapp.tar"]
},
{
"type": "compress",
"output": "myapp.tar.gz",
"compression_level": 9
},
{
"type": "atlas",
"artifact": "myorg/myapp",
"artifact_type": "archive",
"metadata": {
"created_at": "{{ timestamp }}"
}
}
]
]
}
compile.json 1/3
{
"builders": [{
"name": "myapp",
"type": "docker",
"image": "centos:6",
"commit": true,
"privileged": true
}],
"provisioners": [
{
"type": "shell",
"scripts": [
"setup.sh",
"prod-app-script.sh"
]
}
v2.0.0
v1.1.2 v2.0.0
What's a Cluster Scheduler?
redis.job
job "redis" {
datacenters = ["asia-east1", "asia-northeast1"]
task "redis" {
driver = "docker"
config {
image = "redis:latest"
}
resources {
cpu = 500 # Mhz
memory = 256 # MB
network {
mbits = 10
port "redis" {}
}
}
}
}
redis-service.job
job "redis" {
datacenters = ["asia-east1", "asia-northeast1"]
task "redis" {
service {
name = "redis" # redis.service.consul
port = "redis"
check {
type = "tcp"
interval = "30s"
timeout = "2s"
}
}
...
resources {
network {
mbits = 10
port "redis" {
static = "6379"
}
}
}
Declare what you want to run
Scheduler determines where and
manages how to run
v1.1.2
QTY: 1
Developer-centric Release Management
Reproducible Runtime Environments
Provider Agnostic Runtime
Native Hybrid-Cloud Consumption Model
Self-Healing Infrastructure
* Service Discovery and Secure Introduction Support
myapp.job
job "myapp" {
region = "apac"
datacenters = ["asia-east1", "asia-northeast1"]
type = "service"
group "myapp" {
count = 1
task "api" {
driver = "docker"
artifact {
source = "https://s3.amazonaws.com/myorg/myapp.tar.gz"
options {
archive = "tar.gz"
}
}
...
myapp.job
config {
load = ["myapp.tar"]
image = "myorg/myapp"
command = "/sbin/start_myapp"
args = [ "-mode=api" ]
network_mode = "host"
pid_mode = "host"
}
service {
name = "${TASKGROUP}" # myapp.service.consul
tags = [ "api" ] # api.myapp.service.consul
port = "api"
check {
type = "http"
path = "/health.txt"
interval = "5s"
timeout = "2s"
}
}
}
myapp.job
task "web" {
driver = "docker"
config {
load = ["myapp.tar"]
image = "myorg/myapp"
command = "/sbin/start_myapp"
args = [ "-mode=web" ]
network_mode = "host"
pid_mode = "host"
}
service {
name = "${TASKGROUP}" # myapp.service.consul
tags = [ "web" ] # web.myapp.service.consul
port = "web"
check {
type = "http"
path = "/health.txt"
interval = "5s"
timeout = "2s"
}
}
myapp.job
$ nomad plan myapp.job
$ nomad run -check-index 12515398 myapp.job
v1.1.2 v2.0.0
QTY: 0QTY: 20
myapp-green.job
job "myapp-green" {
region = "apac"
datacenters = ["asia-east1", "asia-northeast1"]
type = "service"
group "myapp" {
count = 19
task "api" {
driver = "docker"
artifact {
source = "https://s3.amazonaws.com/myorg/myapp-v123.tar.gz"
options {
archive = "tar.gz"
}
}
...
myapp-blue.job
job "myapp-blue" {
region = "apac"
datacenters = ["asia-east1", "asia-northeast1"]
type = "service"
group "myapp" {
count = 1
task "api" {
driver = "docker"
artifact {
source = "https://s3.amazonaws.com/myorg/myapp-v124.tar.gz"
options {
archive = "tar.gz"
}
}
...
myapp-blue.job
$ nomad plan myapp-blue.job
+ Job: "myapp-blue"
+ Task Group: "myapp" (1 create)
+ Task: "api" (forces create)
Scheduler dry-run:
- All tasks successfully allocated.
100%
Green
95%
Green
70%
Green
90%
Blue
100%
Bluegreen: myapp-v123
blue: myapp-v124
v1.1.2 v2.0.0
QTY: 0QTY: 20
myapp-green.job
job "myapp-green" {
region = "apac"
datacenters = ["asia-east1", "asia-northeast1"]
type = "service"
group "myapp" {
count = 0
task "api" {
driver = "docker"
artifact {
source = "https://s3.amazonaws.com/myorg/myapp-v123.tar.gz"
options {
archive = "tar.gz"
}
}
...
myapp-blue.job
job "myapp-blue" {
region = "apac"
datacenters = ["asia-east1", "asia-northeast1"]
type = "service"
group "myapp" {
count = 20
task "api" {
driver = "docker"
artifact {
source = "https://s3.amazonaws.com/myorg/myapp-v124.tar.gz"
options {
archive = "tar.gz"
}
}
...
myapp-blue.job
job "myapp-blue" {
region = "apac"
datacenters = ["asia-east1", "asia-northeast1"]
type = "service"
update {
# Stagger updates every 120 seconds
stagger = "120s"
# Update a single task at a time
max_parallel = 1
}
...
myapp-blue.job
$ nomad status myapp-blue
ID = myapp-blue
Name = myapp-blue
Type = service
Priority = 50
Datacenters = asia-east1
Status = running
Periodic = false
Summary
Task Group Queued Starting Running Failed Complete Lost
myapp 0 0 1 0 0 0
Allocations
ID Eval ID Node ID Task Group Desired Status Created At
24cfd201 81efc2fa 8d0331e9 myapp run running 11/11/16 21:03:19 AEDT
myapp-blue.job
$ nomad alloc-status --verbose a7365fe4
ID = a7365fe4-cb28-a6e9-f3d4-f99e49c89776
Eval ID = c3c9a1db-dbeb-8afa-0a83-4f1b8b5a03f5
Name = myapp-blue.myapp[0]
Node ID = 1f029d38-8d4b-a552-261f-e457b60f9b4b
Job ID = myapp-blue
Client Status = running
Created At = 11/11/16 22:04:53 AEDT
Evaluated Nodes = 1
Filtered Nodes = 0
Exhausted Nodes = 0
Allocation Time = 1.085001ms
Failures = 0
==> Task Resources
Task: "api"
CPU Memory MB Disk MB IOPS Addresses
500 256 300 0 db: 127.0.0.1:38537
Task: "web"
CPU Memory MB Disk MB IOPS Addresses
Terminal
$ vault read postgresql/creds/readonly
Key Value
--- -----
lease_id postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6
lease_duration 1h0m0s
lease_renewable true
password f8a93086-b11d-10cd-8795-f537a10de712
username token-9e57c18f-ac99-8e29-48f2-3fb09066d2b4
Terminal
$ env VAULT_TOKEN=.... vault read postgresql/creds/readonly
Key Value
--- -----
lease_id postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6
lease_duration 1h0m0s
lease_renewable true
password f8a93086-b11d-10cd-8795-f537a10de712
username token-9e57c18f-ac99-8e29-48f2-3fb09066d2b4
myapp.job
job "myapp" {
region = "apac"
datacenters = ["asia-east1", "asia-northeast1"]
type = "service"
group "myapp" {
count = 1
task "api" {
driver = "docker"
env {
VAULT_TOKEN = "7ea47d76-a653-4d43-9507-dbeed3b3747f"
}
artifact {
source = "https://s3.amazonaws.com/myorg/myapp.tar.gz"
options {
archive = "tar.gz"
}
}
myapp.job
job "myapp" {
region = "apac"
datacenters = ["asia-east1", "asia-northeast1"]
type = "service"
group "myapp" {
count = 1
task "api" {
driver = "docker"
vault {
policies = ["myapp", "api"]
change_mode = "signal"
change_signal = "SIGUSR1"
}
artifact {
source = "https://s3.amazonaws.com/myorg/myapp.tar.gz"
options {
archive = "tar.gz"
}
Containerized
Virtualized
Standalone
Docker
Windows Server Containers
Qemu / KVM
Hyper-V
Xen
Java Jar
Static Binaries
C#
Rkt
Key Value Store
HTTP API
Host & Service Level Health
Checks
Datacenter Aware
Service
Discovery
HTTP + DNS
CLIENT CLIENT CLIENT CLIENT CLIENT CLIENT
SERVER SERVER SERVER
REPLICATION REPLICATION
RPC
RPC
LAN GOSSIP
CLIENT CLIENT CLIENT CLIENT CLIENT CLIENT
SERVER SERVER SERVER
REPLICATION REPLICATION
RPC
RPC
LAN GOSSIP
SERVERSERVER SERVER
REPLICATION REPLICATION
WAN GOSSIP
DB 1
DB 2
DB N
HEALTH
CHECKING
SERVICE
"Are you healthy?"
"What about you?"
"Yessir!"
"Nah"
DB 1
DB 2
DB N
HEALTH
CHECKING
SERVICE
1,000'S OF
REQUESTS
CONSUL
DB 1
DB 2
DB N
My status has changed
CONSUL
DB 1
DB 2
DB N
10'S OF
REQUESTS
v1.1.2
QTY: 0QTY: 20
v2.0.0
v1.1.2
QTY: 0QTY: 20
v2.0.0
Terminal
$ terraform plan -var-file=yow2016.tfvars -out=yow2016.tfplan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.
Your plan was also saved to the path below. Call the "apply" subcommand
with this plan file and Terraform will exactly execute this execution
plan.
Path: yow2016.tfplan
+ consul_key_prefix.myservice_config
datacenter: "<computed>"
path_prefix: "myservice/mycomponent/"
subkeys.%: "3"
subkeys.appParam1: "val1"
subkeys.appParam2: "var2"
subkeys.dbHostname: "my-db.service.consul"
Plan: 1 to add, 0 to change, 0 to destroy.
Terminal
$ cat myservice-consul-kv-config.tf
variable "path_prefix" {
default = "myservice/mycomponent"
}
resource "consul_key_prefix" "myservice_config" {
path_prefix = "${var.path_prefix}/"
subkeys = {
"appParam1" = "val1"
"appParam2" = "var2"
"dbHostname" = "my-db.service.consul"
}
}
Terminal
$ git diff myservice-consul-kv-config.tf
diff --git a/myservice-consul-kv-config.tf b/myservice-consul-kv-config.tf
index 76533d8..990d595 100644
--- a/myservice-consul-kv-config.tf
+++ b/myservice-consul-kv-config.tf
@@ -5,7 +5,5 @@ resource "consul_key_prefix" "myservice_config" {
"appParam1" = "val1"
"appParam2" = "var2"
"dbHostname" = "my-db.service.consul"
+ "dbHostnameFollower" = "slave.my-db.query.consul"
+ "dbHostnameLeader" = "master.my-db.query.consul"
}
}
Terminal
$ terraform plan -var-file=yow2016.tfvars -out=yow2016.tfplan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.
consul_key_prefix.myservice_config: Refreshing state... (ID: myservice/mycomponent/)
Your plan was also saved to the path below. Call the "apply" subcommand
with this plan file and Terraform will exactly execute this execution
plan.
Path: yow2016.tfplan
~ consul_key_prefix.myservice_config
subkeys.%: "3" => "5"
subkeys.dbHostnameFollower: "" => "slave.my-db.query.consul"
subkeys.dbHostnameLeader: "" => "master.my-db.query.consul"
Plan: 0 to add, 1 to change, 0 to destroy.
Terminal
$ terraform apply yow2016.tfplan
consul_key_prefix.myservice_config: Modifying...
subkeys.%: "3" => "5"
subkeys.dbHostnameFollower: "" => "slave.my-db.query.consul"
subkeys.dbHostnameLeader: "" => "master.my-db.query.consul"
consul_key_prefix.myservice_config: Modifications complete
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.
State path: terraform.tfstate
Terminal
$ terraform fmt cat myservice-consul-kv-config.tf
cat myservice-consul-kv-config.tf
$ cat cat myservice-consul-kv-config.tf
resource "consul_key_prefix" "myservice_config" {
path_prefix = "${var.path_prefix}/"
subkeys = {
"appParam1" = "val1"
"appParam2" = "var2"
"dbHostname" = "my-db.service.consul"
"dbHostnameFollower" = "slave.my-db.query.consul"
"dbHostnameLeader" = "master.my-db.query.consul"
}
Terminal
$ cat myservice-consul-kv-config.tf
variable "path_prefix" {
default = "myservice/mycomponent"
}
variable "service_db_name" {}
resource "consul_key_prefix" "myservice_config" {
path_prefix = "${var.path_prefix}/"
subkeys = {
"appParam1" = "val1"
"appParam2" = "var2"
"dbHostname" = "${var.service_db_name}.service.consul"
"dbHostnameFollower" = "slave.${var.service_db_name}.query.consul"
"dbHostnameLeader" = "master.${var.service_db_name}.query.consul"
}
}
Terminal
$ cat yow2016.tfvars
"address" = "127.0.0.1:8500"
"datacenter" = "yow2016"
"token" = ""
"service_db_name" = "my-db"
Terminal
$ terraform plan -var-file=yow2016.tfvars -out=yow2016.tfplan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.
consul_key_prefix.myservice_config: Refreshing state... (ID: myservice/mycomponent/)
No changes. Infrastructure is up-to-date. This means that Terraform
could not detect any differences between your configuration and
the real physical resources that exist. As a result, Terraform
doesn't need to do anything.
Terminal
$ cat myservice-consul-kv-config.tf
variable "db_leader_tag" { default = "leader" }
variable "db_follower_tag" { default = "follower" }
# snip
resource "consul_key_prefix" "myservice_config" {
path_prefix = "${var.path_prefix}/"
subkeys = {
"appParam1" = "val1"
"appParam2" = "var2"
"dbHostname" = "${var.service_db_name}.service.consul"
"dbHostnameFollower" = "${var.db_follower_tag}.${var.service_db_name}.query.consul"
"dbHostnameLeader" = "${var.db_leader_tag}.${var.service_db_name}.query.consul"
}
}
Terminal
% git diff
diff --git a/myservice-consul-kv-config.tf b/myservice-consul-kv-config.tf
index 76590ef..e22eff0 100644
--- a/myservice-consul-kv-config.tf
+++ b/myservice-consul-kv-config.tf
@@ -1,9 +1,9 @@
variable "db_leader_tag" {
- default = "leader"
+ default = "rw"
}
variable "db_follower_tag" {
- default = "follower"
+ default = "ro"
}
variable "path_prefix" {
Terminal
$ terraform plan -var-file=yow2016.tfvars -out=yow2016.tfplan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.
consul_key_prefix.myservice_config: Refreshing state... (ID: myservice/mycomponent/)
Your plan was also saved to the path below. Call the "apply" subcommand
with this plan file and Terraform will exactly execute this execution
plan.
Path: yow2016.tfplan
~ consul_key_prefix.myservice_config
subkeys.dbHostnameFollower: "follower.my-db.query.consul" => "ro.my-db.query.consul"
subkeys.dbHostnameLeader: "leader.my-db.query.consul" => "rw.my-db.query.consul"
Plan: 0 to add, 1 to change, 0 to destroy.
$ git reset --hard
HEAD is now at 2ab88f9 Revise terminology from master/slave to leader/follower
1. Codify Everything
2. Pre-Plan outcomes at build-time
3. Create reproducible artifacts
4. Idempotent APIs and Tooling
5. Developer-Centric Operations
6. Make small, well understood changes changes
7. Start where it makes sense for your organization
CONTACT INFO
@SeanChittenden
sean@hashicorp.com
THANK YOU! Questions?
IMBUED TRUST
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
SMALL SUCCESS
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
VAULT
WIDE EYES
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
VAULT
HA BACKEND
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
VAULT
ROBUSTVAULT!
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
VAULT
HA CONSUL + HAVAULT
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
VAULT
SECRETS AT LAST
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
SECRETS
VAULT
AUTOMATION
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
NOMAD
SECRETS
VAULT
FULL STACK VALUE
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
BUSINESS OBJECTIVE
MYAPP
NOMAD
SECRETS
VAULT
RISK MITIGATED
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
BUSINESS OBJECTIVE
MYAPP
NOMAD
SECRETS
VAULT
SECRETS CONSUL CLUSTERAPPLICATION CONSUL CLUSTER
SELF-HEALING SYSTEMS
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
TRIAGE DIAGNOSE
TREATPREVENT
SELF-ASSEMBLING SYSTEMS
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
SELF-ASSEMBLING SYSTEMS
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
FOUNDATION
SELF-ASSEMBLING SYSTEMS
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
FOUNDATION
PLATFORM
SELF-ASSEMBLING SYSTEMS
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
FOUNDATION
PLATFORM
APP
SELF-ASSEMBLING SYSTEMS
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
FOUNDATION
PLATFORM
APP
"Easy"
SELF-ASSEMBLING SYSTEMS
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
FOUNDATION
PLATFORM
APP
"Easy"
Tough
SELF-ASSEMBLING SYSTEMS
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
FOUNDATION
PLATFORM
APP
"Easy"
Hard
Tough
SELF-ASSEMBLING SYSTEMS
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
FOUNDATION
PLATFORM
APP
ERROR BUDGET
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
ERROR BUDGET
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
Big Budget

Less Important
Smaller Budget

More Important
PLAN FOR KNOWN FAILURE
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
PLAN FOR KNOWN FAILURE
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
KNOWN KNOWNS
PLAN FOR KNOWN FAILURE
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
KNOWN UNKNOWN
PLAN FOR KNOWN FAILURE
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
PLAN FOR KNOWN FAILURE
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
UNKNOWN UNKNOWN
PLAN FOR KNOWN FAILURE
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
PLAN FOR KNOWN FAILURE
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
PLAN FOR KNOWN FAILURE
RISK MANAGEMENT
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
RISK MANAGEMENT
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
Insiders
OpenSSL
Application

Vulnerabilities
RISK MANAGEMENT
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
AUTOMATION
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
AUTOMATION
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
GOOD
BAD
UGLY
EMBRACE AUTOMATION
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
Creative
Industrious
Lazy
Mental Drift
• Self-Healing
• Self-Assembly
• Error Budgeting
• Failure Planning
• Risk Management
• Automation
THINGS WE EMBRACE
INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2

More Related Content

What's hot

Supercharging Content Delivery with Varnish
Supercharging Content Delivery with VarnishSupercharging Content Delivery with Varnish
Supercharging Content Delivery with Varnish
Samantha Quiñones
 
Herd your chickens: Ansible for DB2 configuration management
Herd your chickens: Ansible for DB2 configuration managementHerd your chickens: Ansible for DB2 configuration management
Herd your chickens: Ansible for DB2 configuration management
Frederik Engelen
 
Integrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suiteIntegrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suite
Bram Vogelaar
 
Universal Userland
Universal UserlandUniversal Userland
Universal Userland
Sean Chittenden
 
Build Automation 101
Build Automation 101Build Automation 101
Build Automation 101
Martin Jackson
 
Automated Java Deployments With Rpm
Automated Java Deployments With RpmAutomated Java Deployments With Rpm
Automated Java Deployments With Rpm
Martin Jackson
 
IT Infrastructure Through The Public Network Challenges And Solutions
IT Infrastructure Through The Public Network   Challenges And SolutionsIT Infrastructure Through The Public Network   Challenges And Solutions
IT Infrastructure Through The Public Network Challenges And Solutions
Martin Jackson
 
Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點
William Yeh
 
LinkRest at JeeConf 2017
LinkRest at JeeConf 2017LinkRest at JeeConf 2017
LinkRest at JeeConf 2017
Andrus Adamchik
 
10 Million hits a day with WordPress using a $15 VPS
10 Million hits a day  with WordPress using a $15 VPS10 Million hits a day  with WordPress using a $15 VPS
10 Million hits a day with WordPress using a $15 VPS
Paolo Tonin
 
Stop Worrying & Love the SQL - A Case Study
Stop Worrying & Love the SQL - A Case StudyStop Worrying & Love the SQL - A Case Study
Stop Worrying & Love the SQL - A Case Study
All Things Open
 
Fixing Growing Pains With Puppet Data Patterns
Fixing Growing Pains With Puppet Data PatternsFixing Growing Pains With Puppet Data Patterns
Fixing Growing Pains With Puppet Data Patterns
Martin Jackson
 
bootstrapping containers with confd
bootstrapping containers with confdbootstrapping containers with confd
bootstrapping containers with confd
m_richardson
 
Running High Performance and Fault Tolerant Elasticsearch Clusters on Docker
Running High Performance and Fault Tolerant Elasticsearch Clusters on DockerRunning High Performance and Fault Tolerant Elasticsearch Clusters on Docker
Running High Performance and Fault Tolerant Elasticsearch Clusters on Docker
Sematext Group, Inc.
 
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance TuningPyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
Graham Dumpleton
 
Consul - service discovery and others
Consul - service discovery and othersConsul - service discovery and others
Consul - service discovery and others
Walter Liu
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server
Masahiro Nagano
 
Deploying VMware vCloud Hybrid Service with Puppet - PuppetConf 2013
Deploying VMware vCloud Hybrid Service with Puppet - PuppetConf 2013Deploying VMware vCloud Hybrid Service with Puppet - PuppetConf 2013
Deploying VMware vCloud Hybrid Service with Puppet - PuppetConf 2013
Puppet
 
Replacing Squid with ATS
Replacing Squid with ATSReplacing Squid with ATS
Replacing Squid with ATS
Kit Chan
 
Failsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo HomepageFailsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo Homepage
Kit Chan
 

What's hot (20)

Supercharging Content Delivery with Varnish
Supercharging Content Delivery with VarnishSupercharging Content Delivery with Varnish
Supercharging Content Delivery with Varnish
 
Herd your chickens: Ansible for DB2 configuration management
Herd your chickens: Ansible for DB2 configuration managementHerd your chickens: Ansible for DB2 configuration management
Herd your chickens: Ansible for DB2 configuration management
 
Integrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suiteIntegrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suite
 
Universal Userland
Universal UserlandUniversal Userland
Universal Userland
 
Build Automation 101
Build Automation 101Build Automation 101
Build Automation 101
 
Automated Java Deployments With Rpm
Automated Java Deployments With RpmAutomated Java Deployments With Rpm
Automated Java Deployments With Rpm
 
IT Infrastructure Through The Public Network Challenges And Solutions
IT Infrastructure Through The Public Network   Challenges And SolutionsIT Infrastructure Through The Public Network   Challenges And Solutions
IT Infrastructure Through The Public Network Challenges And Solutions
 
Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點
 
LinkRest at JeeConf 2017
LinkRest at JeeConf 2017LinkRest at JeeConf 2017
LinkRest at JeeConf 2017
 
10 Million hits a day with WordPress using a $15 VPS
10 Million hits a day  with WordPress using a $15 VPS10 Million hits a day  with WordPress using a $15 VPS
10 Million hits a day with WordPress using a $15 VPS
 
Stop Worrying & Love the SQL - A Case Study
Stop Worrying & Love the SQL - A Case StudyStop Worrying & Love the SQL - A Case Study
Stop Worrying & Love the SQL - A Case Study
 
Fixing Growing Pains With Puppet Data Patterns
Fixing Growing Pains With Puppet Data PatternsFixing Growing Pains With Puppet Data Patterns
Fixing Growing Pains With Puppet Data Patterns
 
bootstrapping containers with confd
bootstrapping containers with confdbootstrapping containers with confd
bootstrapping containers with confd
 
Running High Performance and Fault Tolerant Elasticsearch Clusters on Docker
Running High Performance and Fault Tolerant Elasticsearch Clusters on DockerRunning High Performance and Fault Tolerant Elasticsearch Clusters on Docker
Running High Performance and Fault Tolerant Elasticsearch Clusters on Docker
 
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance TuningPyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
 
Consul - service discovery and others
Consul - service discovery and othersConsul - service discovery and others
Consul - service discovery and others
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server
 
Deploying VMware vCloud Hybrid Service with Puppet - PuppetConf 2013
Deploying VMware vCloud Hybrid Service with Puppet - PuppetConf 2013Deploying VMware vCloud Hybrid Service with Puppet - PuppetConf 2013
Deploying VMware vCloud Hybrid Service with Puppet - PuppetConf 2013
 
Replacing Squid with ATS
Replacing Squid with ATSReplacing Squid with ATS
Replacing Squid with ATS
 
Failsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo HomepageFailsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo Homepage
 

Viewers also liked

PostgreSQL + ZFS best practices
PostgreSQL + ZFS best practicesPostgreSQL + ZFS best practices
PostgreSQL + ZFS best practices
Sean Chittenden
 
1
11
Strategic Incrementalism & Resource Targeting for the Revitalization of Legac...
Strategic Incrementalism & Resource Targeting for the Revitalization of Legac...Strategic Incrementalism & Resource Targeting for the Revitalization of Legac...
Strategic Incrementalism & Resource Targeting for the Revitalization of Legac...
greaterohio
 
PostgreSQL Hooks for Fun and Profit
PostgreSQL Hooks for Fun and ProfitPostgreSQL Hooks for Fun and Profit
PostgreSQL Hooks for Fun and Profit
David Fetter
 
Stategic Drift
Stategic Drift Stategic Drift
Stategic Drift
Benedetta Piva
 
Gophers Riding Elephants: Writing PostgreSQL tools in Go
Gophers Riding Elephants: Writing PostgreSQL tools in GoGophers Riding Elephants: Writing PostgreSQL tools in Go
Gophers Riding Elephants: Writing PostgreSQL tools in Go
AJ Bahnken
 
Strategic Drift- A Snapshot
Strategic Drift- A SnapshotStrategic Drift- A Snapshot
Strategic Drift- A Snapshot
Joe Praveen
 
How Change Happens
How Change HappensHow Change Happens
How Change Happens
Michael Edson
 
SM Lecture Nine (B) - Strategy Development Process
SM Lecture Nine (B) - Strategy Development ProcessSM Lecture Nine (B) - Strategy Development Process
SM Lecture Nine (B) - Strategy Development Process
StratMgt Advisor
 
THEORETICAL APPROACHES TO PUBLIC POLICY
THEORETICAL APPROACHES TO PUBLIC POLICYTHEORETICAL APPROACHES TO PUBLIC POLICY
THEORETICAL APPROACHES TO PUBLIC POLICY
Tanzania Public Service College
 
State of the Word 2011
State of the Word 2011State of the Word 2011
State of the Word 2011
photomatt
 

Viewers also liked (11)

PostgreSQL + ZFS best practices
PostgreSQL + ZFS best practicesPostgreSQL + ZFS best practices
PostgreSQL + ZFS best practices
 
1
11
1
 
Strategic Incrementalism & Resource Targeting for the Revitalization of Legac...
Strategic Incrementalism & Resource Targeting for the Revitalization of Legac...Strategic Incrementalism & Resource Targeting for the Revitalization of Legac...
Strategic Incrementalism & Resource Targeting for the Revitalization of Legac...
 
PostgreSQL Hooks for Fun and Profit
PostgreSQL Hooks for Fun and ProfitPostgreSQL Hooks for Fun and Profit
PostgreSQL Hooks for Fun and Profit
 
Stategic Drift
Stategic Drift Stategic Drift
Stategic Drift
 
Gophers Riding Elephants: Writing PostgreSQL tools in Go
Gophers Riding Elephants: Writing PostgreSQL tools in GoGophers Riding Elephants: Writing PostgreSQL tools in Go
Gophers Riding Elephants: Writing PostgreSQL tools in Go
 
Strategic Drift- A Snapshot
Strategic Drift- A SnapshotStrategic Drift- A Snapshot
Strategic Drift- A Snapshot
 
How Change Happens
How Change HappensHow Change Happens
How Change Happens
 
SM Lecture Nine (B) - Strategy Development Process
SM Lecture Nine (B) - Strategy Development ProcessSM Lecture Nine (B) - Strategy Development Process
SM Lecture Nine (B) - Strategy Development Process
 
THEORETICAL APPROACHES TO PUBLIC POLICY
THEORETICAL APPROACHES TO PUBLIC POLICYTHEORETICAL APPROACHES TO PUBLIC POLICY
THEORETICAL APPROACHES TO PUBLIC POLICY
 
State of the Word 2011
State of the Word 2011State of the Word 2011
State of the Word 2011
 

Similar to Incrementalism: An Industrial Strategy For Adopting Modern Automation

Modern Scheduling for Modern Applications with Nomad
Modern Scheduling for Modern Applications with NomadModern Scheduling for Modern Applications with Nomad
Modern Scheduling for Modern Applications with Nomad
Mitchell Pronschinske
 
Kubernetes Navigation Stories – DevOpsStage 2019, Kyiv
Kubernetes Navigation Stories – DevOpsStage 2019, KyivKubernetes Navigation Stories – DevOpsStage 2019, Kyiv
Kubernetes Navigation Stories – DevOpsStage 2019, Kyiv
Aleksey Asiutin
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
Lindsay Holmwood
 
Apache Druid Auto Scale-out/in for Streaming Data Ingestion on Kubernetes
Apache Druid Auto Scale-out/in for Streaming Data Ingestion on KubernetesApache Druid Auto Scale-out/in for Streaming Data Ingestion on Kubernetes
Apache Druid Auto Scale-out/in for Streaming Data Ingestion on Kubernetes
DataWorks Summit
 
Nomad Multi-Cloud
Nomad Multi-CloudNomad Multi-Cloud
Nomad Multi-Cloud
Nic Jackson
 
Automatically scaling your Kubernetes workloads - SVC201-S - Chicago AWS Summit
Automatically scaling your Kubernetes workloads - SVC201-S - Chicago AWS SummitAutomatically scaling your Kubernetes workloads - SVC201-S - Chicago AWS Summit
Automatically scaling your Kubernetes workloads - SVC201-S - Chicago AWS Summit
Amazon Web Services
 
Speed up R with parallel programming in the Cloud
Speed up R with parallel programming in the CloudSpeed up R with parallel programming in the Cloud
Speed up R with parallel programming in the Cloud
Revolution Analytics
 
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
DECK36
 
Living the Nomadic life - Nic Jackson
Living the Nomadic life - Nic JacksonLiving the Nomadic life - Nic Jackson
Living the Nomadic life - Nic Jackson
Paris Container Day
 
Scaling up Near Real-time Analytics @Uber &LinkedIn
Scaling up Near Real-time Analytics @Uber &LinkedInScaling up Near Real-time Analytics @Uber &LinkedIn
Scaling up Near Real-time Analytics @Uber &LinkedIn
C4Media
 
Why Kubernetes? Cloud Native and Developer Experience at Zalando - OWL Tech &...
Why Kubernetes? Cloud Native and Developer Experience at Zalando - OWL Tech &...Why Kubernetes? Cloud Native and Developer Experience at Zalando - OWL Tech &...
Why Kubernetes? Cloud Native and Developer Experience at Zalando - OWL Tech &...
Henning Jacobs
 
Altitude SF 2017: Nomad and next-gen application architectures
Altitude SF 2017: Nomad and next-gen application architecturesAltitude SF 2017: Nomad and next-gen application architectures
Altitude SF 2017: Nomad and next-gen application architectures
Fastly
 
Building a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkBuilding a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless framework
Luciano Mammino
 
Deploying Percona XtraDB Cluster in Openshift
Deploying Percona XtraDB Cluster in OpenshiftDeploying Percona XtraDB Cluster in Openshift
Deploying Percona XtraDB Cluster in Openshift
Alexander Rubin
 
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit Sydney
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit SydneyAutoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit Sydney
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit Sydney
Amazon Web Services
 
6 tips for improving ruby performance
6 tips for improving ruby performance6 tips for improving ruby performance
6 tips for improving ruby performance
Engine Yard
 
A Hitchhiker’s Guide to the Cloud Native Stack. #CDS17
A Hitchhiker’s Guide to the Cloud Native Stack. #CDS17A Hitchhiker’s Guide to the Cloud Native Stack. #CDS17
A Hitchhiker’s Guide to the Cloud Native Stack. #CDS17
Mario-Leander Reimer
 
A hitchhiker‘s guide to the cloud native stack
A hitchhiker‘s guide to the cloud native stackA hitchhiker‘s guide to the cloud native stack
A hitchhiker‘s guide to the cloud native stack
QAware GmbH
 
iguazio - nuclio overview to CNCF (Sep 25th 2017)
iguazio - nuclio overview to CNCF (Sep 25th 2017)iguazio - nuclio overview to CNCF (Sep 25th 2017)
iguazio - nuclio overview to CNCF (Sep 25th 2017)
Eran Duchan
 
MySQL on Docker and Kubernetes
MySQL on Docker and KubernetesMySQL on Docker and Kubernetes
MySQL on Docker and Kubernetes
Balasubramanian Kandasamy
 

Similar to Incrementalism: An Industrial Strategy For Adopting Modern Automation (20)

Modern Scheduling for Modern Applications with Nomad
Modern Scheduling for Modern Applications with NomadModern Scheduling for Modern Applications with Nomad
Modern Scheduling for Modern Applications with Nomad
 
Kubernetes Navigation Stories – DevOpsStage 2019, Kyiv
Kubernetes Navigation Stories – DevOpsStage 2019, KyivKubernetes Navigation Stories – DevOpsStage 2019, Kyiv
Kubernetes Navigation Stories – DevOpsStage 2019, Kyiv
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
Apache Druid Auto Scale-out/in for Streaming Data Ingestion on Kubernetes
Apache Druid Auto Scale-out/in for Streaming Data Ingestion on KubernetesApache Druid Auto Scale-out/in for Streaming Data Ingestion on Kubernetes
Apache Druid Auto Scale-out/in for Streaming Data Ingestion on Kubernetes
 
Nomad Multi-Cloud
Nomad Multi-CloudNomad Multi-Cloud
Nomad Multi-Cloud
 
Automatically scaling your Kubernetes workloads - SVC201-S - Chicago AWS Summit
Automatically scaling your Kubernetes workloads - SVC201-S - Chicago AWS SummitAutomatically scaling your Kubernetes workloads - SVC201-S - Chicago AWS Summit
Automatically scaling your Kubernetes workloads - SVC201-S - Chicago AWS Summit
 
Speed up R with parallel programming in the Cloud
Speed up R with parallel programming in the CloudSpeed up R with parallel programming in the Cloud
Speed up R with parallel programming in the Cloud
 
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
 
Living the Nomadic life - Nic Jackson
Living the Nomadic life - Nic JacksonLiving the Nomadic life - Nic Jackson
Living the Nomadic life - Nic Jackson
 
Scaling up Near Real-time Analytics @Uber &LinkedIn
Scaling up Near Real-time Analytics @Uber &LinkedInScaling up Near Real-time Analytics @Uber &LinkedIn
Scaling up Near Real-time Analytics @Uber &LinkedIn
 
Why Kubernetes? Cloud Native and Developer Experience at Zalando - OWL Tech &...
Why Kubernetes? Cloud Native and Developer Experience at Zalando - OWL Tech &...Why Kubernetes? Cloud Native and Developer Experience at Zalando - OWL Tech &...
Why Kubernetes? Cloud Native and Developer Experience at Zalando - OWL Tech &...
 
Altitude SF 2017: Nomad and next-gen application architectures
Altitude SF 2017: Nomad and next-gen application architecturesAltitude SF 2017: Nomad and next-gen application architectures
Altitude SF 2017: Nomad and next-gen application architectures
 
Building a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkBuilding a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless framework
 
Deploying Percona XtraDB Cluster in Openshift
Deploying Percona XtraDB Cluster in OpenshiftDeploying Percona XtraDB Cluster in Openshift
Deploying Percona XtraDB Cluster in Openshift
 
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit Sydney
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit SydneyAutoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit Sydney
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit Sydney
 
6 tips for improving ruby performance
6 tips for improving ruby performance6 tips for improving ruby performance
6 tips for improving ruby performance
 
A Hitchhiker’s Guide to the Cloud Native Stack. #CDS17
A Hitchhiker’s Guide to the Cloud Native Stack. #CDS17A Hitchhiker’s Guide to the Cloud Native Stack. #CDS17
A Hitchhiker’s Guide to the Cloud Native Stack. #CDS17
 
A hitchhiker‘s guide to the cloud native stack
A hitchhiker‘s guide to the cloud native stackA hitchhiker‘s guide to the cloud native stack
A hitchhiker‘s guide to the cloud native stack
 
iguazio - nuclio overview to CNCF (Sep 25th 2017)
iguazio - nuclio overview to CNCF (Sep 25th 2017)iguazio - nuclio overview to CNCF (Sep 25th 2017)
iguazio - nuclio overview to CNCF (Sep 25th 2017)
 
MySQL on Docker and Kubernetes
MySQL on Docker and KubernetesMySQL on Docker and Kubernetes
MySQL on Docker and Kubernetes
 

Recently uploaded

办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
uehowe
 
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
vmemo1
 
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
xjq03c34
 
Understanding User Behavior with Google Analytics.pdf
Understanding User Behavior with Google Analytics.pdfUnderstanding User Behavior with Google Analytics.pdf
Understanding User Behavior with Google Analytics.pdf
SEO Article Boost
 
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
uehowe
 
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
zyfovom
 
Gen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needsGen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needs
Laura Szabó
 
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalmanuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
wolfsoftcompanyco
 
Design Thinking NETFLIX using all techniques.pptx
Design Thinking NETFLIX using all techniques.pptxDesign Thinking NETFLIX using all techniques.pptx
Design Thinking NETFLIX using all techniques.pptx
saathvikreddy2003
 
Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!
Toptal Tech
 
国外证书(Lincoln毕业证)新西兰林肯大学毕业证成绩单不能毕业办理
国外证书(Lincoln毕业证)新西兰林肯大学毕业证成绩单不能毕业办理国外证书(Lincoln毕业证)新西兰林肯大学毕业证成绩单不能毕业办理
国外证书(Lincoln毕业证)新西兰林肯大学毕业证成绩单不能毕业办理
zoowe
 
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
cuobya
 
Discover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to IndiaDiscover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to India
davidjhones387
 
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
cuobya
 
[HUN][hackersuli] Red Teaming alapok 2024
[HUN][hackersuli] Red Teaming alapok 2024[HUN][hackersuli] Red Teaming alapok 2024
[HUN][hackersuli] Red Teaming alapok 2024
hackersuli
 
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
cuobya
 
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
fovkoyb
 
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
ukwwuq
 
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
bseovas
 
7 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 20247 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 2024
Danica Gill
 

Recently uploaded (20)

办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
 
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
 
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
 
Understanding User Behavior with Google Analytics.pdf
Understanding User Behavior with Google Analytics.pdfUnderstanding User Behavior with Google Analytics.pdf
Understanding User Behavior with Google Analytics.pdf
 
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
 
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
 
Gen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needsGen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needs
 
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalmanuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
 
Design Thinking NETFLIX using all techniques.pptx
Design Thinking NETFLIX using all techniques.pptxDesign Thinking NETFLIX using all techniques.pptx
Design Thinking NETFLIX using all techniques.pptx
 
Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!
 
国外证书(Lincoln毕业证)新西兰林肯大学毕业证成绩单不能毕业办理
国外证书(Lincoln毕业证)新西兰林肯大学毕业证成绩单不能毕业办理国外证书(Lincoln毕业证)新西兰林肯大学毕业证成绩单不能毕业办理
国外证书(Lincoln毕业证)新西兰林肯大学毕业证成绩单不能毕业办理
 
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
 
Discover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to IndiaDiscover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to India
 
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
 
[HUN][hackersuli] Red Teaming alapok 2024
[HUN][hackersuli] Red Teaming alapok 2024[HUN][hackersuli] Red Teaming alapok 2024
[HUN][hackersuli] Red Teaming alapok 2024
 
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
 
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
 
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
 
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
 
7 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 20247 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 2024
 

Incrementalism: An Industrial Strategy For Adopting Modern Automation

  • 1. ç INCREMENTALISM An Industrial Strategy For Adopting Modern Automation
  • 4. Industrial Techno Revolution Development and Operational Practices
  • 5. 1. Development Practices 2. Secrets Management 3. Packaging 4. Developer-centric, Self-Healing Applications 5. Data Center Aware Services 6. Infrastructure Manipulation
  • 6.
  • 7. YOU ARE A BIT-CHUCKING TECHNO INDUSTRIALIST.
  • 8.
  • 9. DATA CENTERS ARE YOUR FACTORIES. NETWORKS ARE YOUR ROADS. YOU APP PRODUCES WIDGETS. MICROSERVICES ARE YOUR ROBOTS ON THE FACTORY LINE.
  • 10. YOU ARE A BIT-CHUCKING TECHNO INDUSTRIALIST. WIDGET SHIPPING ^
  • 11.
  • 12.
  • 13.
  • 16.
  • 17. PROFILE MESSAGES UPSELL CART RELATED COMMENTSSOCIAL HTML/JSON/gRPC Response
  • 20. • New program! • Use a piece of user data • Talks to a database • Returns something useful • Highly-Available • Self-Healing • Feedback
  • 21. • New program! • Use a piece of user data • Talks to a database • Returns something useful • Highly-Available • Self-Healing • Feedback BUSINESS VALUE
  • 22. • New program! • Use a piece of user data • Talks to a database • Returns something useful • Highly-Available • Self-Healing • Feedback INPUT
  • 23. • New program! • Use a piece of user data • Talks to a database • Returns something useful • Highly-Available • Self-Healing • Feedback DEPENDENCY
  • 24. • New program! • Use a piece of user data • Talks to a database • Returns something useful • Highly-Available • Self-Healing • Feedback PROPERTIES OF
 THE APPLICATION
  • 25. • New program! • Use a piece of user data • Talks to a database • Returns something useful • Highly-Available • Self-Healing • Feedback VALUE
  • 26. • New program! • Use a piece of user data • Talks to a database • Returns something useful • Highly-Available • Self-Healing • Feedback DISTRACTING, REQUIRED, NECESSARY COMPLEXITY
  • 27. • New program! • Use a piece of user data • Talks to a database • Returns something useful • Highly-Available • Self-Healing • Feedback WIDGET
  • 28. • New program! • Use a piece of user data • Talks to a database • Returns something useful • Highly-Available • Self-Healing • Feedback INDUSTRIAL COMPUTING RAW MATERIAL REDUNDANT ROBOTS REPLACEABLE PARTS QUALITY-MANAGEMENT WIDGET STORAGE
  • 30.
  • 31.
  • 32. Codified Development Environment Reproducible Dev Environments Disposable R&D Workspace Shared Developer Workspace Developer-driven Infrastructure
  • 33. Terminal $ $EDITOR Vagrantfile Vagrant.configure("2") do |config| config.vm.box = "ubuntu/xenial64" config.vm.box_url = "https://cloud-images.ubuntu.com/ xenial/current/xenial-server-cloudimg-amd64-vagrant.box" config.vm.network "private_network", ip: "192.168.33.10" config.vm.provision "shell", path: "setup.sh" end $ cat setup.sh apt-get install postgresql-server tmux
  • 34. Terminal my-laptop$ vagrant up --destroy-on-error my-laptop$ vagrant ssh vm$ uname -a | tee /vagrant/uname.out Linux compton 2.6.24-19-server #1 SMP Sat Jul 12 00:40:01 UTC 2008 i686 GNU/Linux vm$ logout Shared connection to 192.168.39.130 closed. my-laptop$ cat uname.out Linux compton 2.6.24-19-server #1 SMP Sat Jul 12 00:40:01 UTC 2008 i686 GNU/Linux
  • 35. Terminal $ $EDITOR Vagrantfile Vagrant.configure("2") do |config| config.ssh.shell = "sh" config.vm.synced_folder ".", "/vagrant", nfs: true, id: "vagrant-root" end
  • 36. Terminal my-laptop$ $EDITOR myapp.go my-laptop$ GOOS=linux GOARCH=amd64 go build -o myapp-linux my-laptop$ GOOS=freebsd GOARCH=amd64 go build -o myapp-freebsd my-laptop$ vagrant ssh vm$ /vagrant/myapp-linux vm$ logout my-laptop$ vagrant up freebsd-vm1 my-laptop$ vagrant ssh freebsd-vm1 freebsd-vm1$ /vagrant/myapp-freebsd freebsd-vm1$ logout
  • 38.
  • 39. Secret Sprawl Break Glass Procedures Audit Logs Secrets Lifecycle Management
  • 40. "I want to deploy this app to prod. Password-less logins are disabled on the databases! Now what?"
  • 41. "I want to deploy this app to prod. Password-less logins are disabled on the databases! Now what?" Private GitHub repo Commit passwords inline in SCM Switch creds based on $HOSTNAME? Establish a protocol for acquiring credentials at runtime
  • 42.
  • 43.
  • 44.
  • 45.
  • 46. Terminal $ vault read postgresql/creds/readonly Key Value --- ----- lease_id postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6 lease_duration 1h0m0s lease_renewable true password f8a93086-b11d-10cd-8795-f537a10de712 username token-9e57c18f-ac99-8e29-48f2-3fb09066d2b4
  • 47. Terminal $ VAULT_ADDR=http://vault.service.consul vault read postgresql/creds/readonly Key Value --- ----- lease_id postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6 lease_duration 1h0m0s lease_renewable true password f8a93086-b11d-10cd-8795-f537a10de712 username token-9e57c18f-ac99-8e29-48f2-3fb09066d2b4
  • 48. Terminal $ psql -U postgres psql (9.6.1) Type "help" for help. postgres=# du Role name | Attributes | Member of -------------------------------------------+--------------------------+------------ postgres | Superuser, Create ... | {} token-9e57c18f-ac99-8e29-48f2-3fb09066d2b4 | Password valid until ... | {}
  • 49. Terminal $ vault renew postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6 Key Value --- ----- lease_id postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6 lease_duration 1h0m0s lease_renewable true
  • 50. Terminal $ cat myapp-db-config.yml.ctmpl --- {{- with secret "postgresql/creds/readonly" }} username: "{{ .Data.username }}" password: "{{ .Data.password }}" database: "myapp" {{- end }} $ consul-template -template="myapp-db-config.yml.ctmpl:myapp-db-config.yml" ./myapp <CTRL+C> Received interrupt, cleaning up...
  • 51. Terminal $ vault write postgresql/roles/readonly sql="CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO "{{name}}";" Success! Data written to: postgresql/roles/readonly
  • 52. Terminal $ tee my-policy.vault | vault write postgresql/roles/readonly sql=- CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO "{{name}}"; Success! Data written to: postgresql/roles/readonly
  • 54. Codified Build Environment Reproducible Packaging Shared Packaging Instructions Developer-driven Build and Packaging Steps
  • 55. compile.json 1/3 { "builders": [{ "name": "myapp", "type": "docker", "image": "centos:6", "commit": true, "privileged": true }], "provisioners": [ { "type": "file", "source": "myapp-linux", "destination": "/usr/local/bin/myapp" }, { "type": "file", "source": "local-config-file.repo", "destination": "/usr/local/etc/myapp.conf" }, { "type": "file", "source": "start_myapp.sh", "destination": "/sbin/start_myapp" },
  • 56. compile.json 2/3 { "type": "shell", "inline": [ "/usr/bin/yum -y update", "/usr/bin/yum -y install util-linux-ng patch", "/bin/chmod 0600 /usr/local/etc/myapp.conf", "/bin/chmod 0744 /sbin/start_myapp /usr/local/bin/myapp-linux", "/usr/bin/curl -o /usr/local/etc/some-ca.crt https://host.example.com/pki/ ca.crt", ] } ], "post-processors": [ [ { "type": "docker-tag", "repository": "myorg/myapp" }, { "type": "docker-save", "path": "myapp.tar" },
  • 57. compile.json 3/3 { "type": "artifice", "files": ["myapp.tar"] }, { "type": "compress", "output": "myapp.tar.gz", "compression_level": 9 }, { "type": "atlas", "artifact": "myorg/myapp", "artifact_type": "archive", "metadata": { "created_at": "{{ timestamp }}" } } ] ] }
  • 58. compile.json 1/3 { "builders": [{ "name": "myapp", "type": "docker", "image": "centos:6", "commit": true, "privileged": true }], "provisioners": [ { "type": "shell", "scripts": [ "setup.sh", "prod-app-script.sh" ] }
  • 61. What's a Cluster Scheduler?
  • 62. redis.job job "redis" { datacenters = ["asia-east1", "asia-northeast1"] task "redis" { driver = "docker" config { image = "redis:latest" } resources { cpu = 500 # Mhz memory = 256 # MB network { mbits = 10 port "redis" {} } } } }
  • 63. redis-service.job job "redis" { datacenters = ["asia-east1", "asia-northeast1"] task "redis" { service { name = "redis" # redis.service.consul port = "redis" check { type = "tcp" interval = "30s" timeout = "2s" } } ... resources { network { mbits = 10 port "redis" { static = "6379" } } }
  • 64. Declare what you want to run
  • 65. Scheduler determines where and manages how to run
  • 67. Developer-centric Release Management Reproducible Runtime Environments Provider Agnostic Runtime Native Hybrid-Cloud Consumption Model Self-Healing Infrastructure * Service Discovery and Secure Introduction Support
  • 68. myapp.job job "myapp" { region = "apac" datacenters = ["asia-east1", "asia-northeast1"] type = "service" group "myapp" { count = 1 task "api" { driver = "docker" artifact { source = "https://s3.amazonaws.com/myorg/myapp.tar.gz" options { archive = "tar.gz" } } ...
  • 69. myapp.job config { load = ["myapp.tar"] image = "myorg/myapp" command = "/sbin/start_myapp" args = [ "-mode=api" ] network_mode = "host" pid_mode = "host" } service { name = "${TASKGROUP}" # myapp.service.consul tags = [ "api" ] # api.myapp.service.consul port = "api" check { type = "http" path = "/health.txt" interval = "5s" timeout = "2s" } } }
  • 70. myapp.job task "web" { driver = "docker" config { load = ["myapp.tar"] image = "myorg/myapp" command = "/sbin/start_myapp" args = [ "-mode=web" ] network_mode = "host" pid_mode = "host" } service { name = "${TASKGROUP}" # myapp.service.consul tags = [ "web" ] # web.myapp.service.consul port = "web" check { type = "http" path = "/health.txt" interval = "5s" timeout = "2s" } }
  • 71. myapp.job $ nomad plan myapp.job $ nomad run -check-index 12515398 myapp.job
  • 73.
  • 74. myapp-green.job job "myapp-green" { region = "apac" datacenters = ["asia-east1", "asia-northeast1"] type = "service" group "myapp" { count = 19 task "api" { driver = "docker" artifact { source = "https://s3.amazonaws.com/myorg/myapp-v123.tar.gz" options { archive = "tar.gz" } } ...
  • 75. myapp-blue.job job "myapp-blue" { region = "apac" datacenters = ["asia-east1", "asia-northeast1"] type = "service" group "myapp" { count = 1 task "api" { driver = "docker" artifact { source = "https://s3.amazonaws.com/myorg/myapp-v124.tar.gz" options { archive = "tar.gz" } } ...
  • 76. myapp-blue.job $ nomad plan myapp-blue.job + Job: "myapp-blue" + Task Group: "myapp" (1 create) + Task: "api" (forces create) Scheduler dry-run: - All tasks successfully allocated.
  • 79. myapp-green.job job "myapp-green" { region = "apac" datacenters = ["asia-east1", "asia-northeast1"] type = "service" group "myapp" { count = 0 task "api" { driver = "docker" artifact { source = "https://s3.amazonaws.com/myorg/myapp-v123.tar.gz" options { archive = "tar.gz" } } ...
  • 80. myapp-blue.job job "myapp-blue" { region = "apac" datacenters = ["asia-east1", "asia-northeast1"] type = "service" group "myapp" { count = 20 task "api" { driver = "docker" artifact { source = "https://s3.amazonaws.com/myorg/myapp-v124.tar.gz" options { archive = "tar.gz" } } ...
  • 81. myapp-blue.job job "myapp-blue" { region = "apac" datacenters = ["asia-east1", "asia-northeast1"] type = "service" update { # Stagger updates every 120 seconds stagger = "120s" # Update a single task at a time max_parallel = 1 } ...
  • 82. myapp-blue.job $ nomad status myapp-blue ID = myapp-blue Name = myapp-blue Type = service Priority = 50 Datacenters = asia-east1 Status = running Periodic = false Summary Task Group Queued Starting Running Failed Complete Lost myapp 0 0 1 0 0 0 Allocations ID Eval ID Node ID Task Group Desired Status Created At 24cfd201 81efc2fa 8d0331e9 myapp run running 11/11/16 21:03:19 AEDT
  • 83. myapp-blue.job $ nomad alloc-status --verbose a7365fe4 ID = a7365fe4-cb28-a6e9-f3d4-f99e49c89776 Eval ID = c3c9a1db-dbeb-8afa-0a83-4f1b8b5a03f5 Name = myapp-blue.myapp[0] Node ID = 1f029d38-8d4b-a552-261f-e457b60f9b4b Job ID = myapp-blue Client Status = running Created At = 11/11/16 22:04:53 AEDT Evaluated Nodes = 1 Filtered Nodes = 0 Exhausted Nodes = 0 Allocation Time = 1.085001ms Failures = 0 ==> Task Resources Task: "api" CPU Memory MB Disk MB IOPS Addresses 500 256 300 0 db: 127.0.0.1:38537 Task: "web" CPU Memory MB Disk MB IOPS Addresses
  • 84. Terminal $ vault read postgresql/creds/readonly Key Value --- ----- lease_id postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6 lease_duration 1h0m0s lease_renewable true password f8a93086-b11d-10cd-8795-f537a10de712 username token-9e57c18f-ac99-8e29-48f2-3fb09066d2b4
  • 85. Terminal $ env VAULT_TOKEN=.... vault read postgresql/creds/readonly Key Value --- ----- lease_id postgresql/creds/readonly/5fec46f2-ab40-d9b8-61a2-887c7946eeb6 lease_duration 1h0m0s lease_renewable true password f8a93086-b11d-10cd-8795-f537a10de712 username token-9e57c18f-ac99-8e29-48f2-3fb09066d2b4
  • 86. myapp.job job "myapp" { region = "apac" datacenters = ["asia-east1", "asia-northeast1"] type = "service" group "myapp" { count = 1 task "api" { driver = "docker" env { VAULT_TOKEN = "7ea47d76-a653-4d43-9507-dbeed3b3747f" } artifact { source = "https://s3.amazonaws.com/myorg/myapp.tar.gz" options { archive = "tar.gz" } }
  • 87. myapp.job job "myapp" { region = "apac" datacenters = ["asia-east1", "asia-northeast1"] type = "service" group "myapp" { count = 1 task "api" { driver = "docker" vault { policies = ["myapp", "api"] change_mode = "signal" change_signal = "SIGUSR1" } artifact { source = "https://s3.amazonaws.com/myorg/myapp.tar.gz" options { archive = "tar.gz" }
  • 88. Containerized Virtualized Standalone Docker Windows Server Containers Qemu / KVM Hyper-V Xen Java Jar Static Binaries C# Rkt
  • 89.
  • 90. Key Value Store HTTP API Host & Service Level Health Checks Datacenter Aware Service Discovery HTTP + DNS
  • 91.
  • 92. CLIENT CLIENT CLIENT CLIENT CLIENT CLIENT SERVER SERVER SERVER REPLICATION REPLICATION RPC RPC LAN GOSSIP
  • 93. CLIENT CLIENT CLIENT CLIENT CLIENT CLIENT SERVER SERVER SERVER REPLICATION REPLICATION RPC RPC LAN GOSSIP SERVERSERVER SERVER REPLICATION REPLICATION WAN GOSSIP
  • 94. DB 1 DB 2 DB N HEALTH CHECKING SERVICE "Are you healthy?" "What about you?" "Yessir!" "Nah"
  • 95. DB 1 DB 2 DB N HEALTH CHECKING SERVICE 1,000'S OF REQUESTS
  • 96. CONSUL DB 1 DB 2 DB N My status has changed
  • 97. CONSUL DB 1 DB 2 DB N 10'S OF REQUESTS
  • 99.
  • 100.
  • 101.
  • 103. Terminal $ terraform plan -var-file=yow2016.tfvars -out=yow2016.tfplan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. Your plan was also saved to the path below. Call the "apply" subcommand with this plan file and Terraform will exactly execute this execution plan. Path: yow2016.tfplan + consul_key_prefix.myservice_config datacenter: "<computed>" path_prefix: "myservice/mycomponent/" subkeys.%: "3" subkeys.appParam1: "val1" subkeys.appParam2: "var2" subkeys.dbHostname: "my-db.service.consul" Plan: 1 to add, 0 to change, 0 to destroy.
  • 104. Terminal $ cat myservice-consul-kv-config.tf variable "path_prefix" { default = "myservice/mycomponent" } resource "consul_key_prefix" "myservice_config" { path_prefix = "${var.path_prefix}/" subkeys = { "appParam1" = "val1" "appParam2" = "var2" "dbHostname" = "my-db.service.consul" } }
  • 105. Terminal $ git diff myservice-consul-kv-config.tf diff --git a/myservice-consul-kv-config.tf b/myservice-consul-kv-config.tf index 76533d8..990d595 100644 --- a/myservice-consul-kv-config.tf +++ b/myservice-consul-kv-config.tf @@ -5,7 +5,5 @@ resource "consul_key_prefix" "myservice_config" { "appParam1" = "val1" "appParam2" = "var2" "dbHostname" = "my-db.service.consul" + "dbHostnameFollower" = "slave.my-db.query.consul" + "dbHostnameLeader" = "master.my-db.query.consul" } }
  • 106. Terminal $ terraform plan -var-file=yow2016.tfvars -out=yow2016.tfplan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. consul_key_prefix.myservice_config: Refreshing state... (ID: myservice/mycomponent/) Your plan was also saved to the path below. Call the "apply" subcommand with this plan file and Terraform will exactly execute this execution plan. Path: yow2016.tfplan ~ consul_key_prefix.myservice_config subkeys.%: "3" => "5" subkeys.dbHostnameFollower: "" => "slave.my-db.query.consul" subkeys.dbHostnameLeader: "" => "master.my-db.query.consul" Plan: 0 to add, 1 to change, 0 to destroy.
  • 107. Terminal $ terraform apply yow2016.tfplan consul_key_prefix.myservice_config: Modifying... subkeys.%: "3" => "5" subkeys.dbHostnameFollower: "" => "slave.my-db.query.consul" subkeys.dbHostnameLeader: "" => "master.my-db.query.consul" consul_key_prefix.myservice_config: Modifications complete Apply complete! Resources: 0 added, 1 changed, 0 destroyed. The state of your infrastructure has been saved to the path below. This state is required to modify and destroy your infrastructure, so keep it safe. To inspect the complete state use the `terraform show` command. State path: terraform.tfstate
  • 108. Terminal $ terraform fmt cat myservice-consul-kv-config.tf cat myservice-consul-kv-config.tf $ cat cat myservice-consul-kv-config.tf resource "consul_key_prefix" "myservice_config" { path_prefix = "${var.path_prefix}/" subkeys = { "appParam1" = "val1" "appParam2" = "var2" "dbHostname" = "my-db.service.consul" "dbHostnameFollower" = "slave.my-db.query.consul" "dbHostnameLeader" = "master.my-db.query.consul" }
  • 109. Terminal $ cat myservice-consul-kv-config.tf variable "path_prefix" { default = "myservice/mycomponent" } variable "service_db_name" {} resource "consul_key_prefix" "myservice_config" { path_prefix = "${var.path_prefix}/" subkeys = { "appParam1" = "val1" "appParam2" = "var2" "dbHostname" = "${var.service_db_name}.service.consul" "dbHostnameFollower" = "slave.${var.service_db_name}.query.consul" "dbHostnameLeader" = "master.${var.service_db_name}.query.consul" } }
  • 110. Terminal $ cat yow2016.tfvars "address" = "127.0.0.1:8500" "datacenter" = "yow2016" "token" = "" "service_db_name" = "my-db"
  • 111. Terminal $ terraform plan -var-file=yow2016.tfvars -out=yow2016.tfplan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. consul_key_prefix.myservice_config: Refreshing state... (ID: myservice/mycomponent/) No changes. Infrastructure is up-to-date. This means that Terraform could not detect any differences between your configuration and the real physical resources that exist. As a result, Terraform doesn't need to do anything.
  • 112. Terminal $ cat myservice-consul-kv-config.tf variable "db_leader_tag" { default = "leader" } variable "db_follower_tag" { default = "follower" } # snip resource "consul_key_prefix" "myservice_config" { path_prefix = "${var.path_prefix}/" subkeys = { "appParam1" = "val1" "appParam2" = "var2" "dbHostname" = "${var.service_db_name}.service.consul" "dbHostnameFollower" = "${var.db_follower_tag}.${var.service_db_name}.query.consul" "dbHostnameLeader" = "${var.db_leader_tag}.${var.service_db_name}.query.consul" } }
  • 113. Terminal % git diff diff --git a/myservice-consul-kv-config.tf b/myservice-consul-kv-config.tf index 76590ef..e22eff0 100644 --- a/myservice-consul-kv-config.tf +++ b/myservice-consul-kv-config.tf @@ -1,9 +1,9 @@ variable "db_leader_tag" { - default = "leader" + default = "rw" } variable "db_follower_tag" { - default = "follower" + default = "ro" } variable "path_prefix" {
  • 114. Terminal $ terraform plan -var-file=yow2016.tfvars -out=yow2016.tfplan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. consul_key_prefix.myservice_config: Refreshing state... (ID: myservice/mycomponent/) Your plan was also saved to the path below. Call the "apply" subcommand with this plan file and Terraform will exactly execute this execution plan. Path: yow2016.tfplan ~ consul_key_prefix.myservice_config subkeys.dbHostnameFollower: "follower.my-db.query.consul" => "ro.my-db.query.consul" subkeys.dbHostnameLeader: "leader.my-db.query.consul" => "rw.my-db.query.consul" Plan: 0 to add, 1 to change, 0 to destroy. $ git reset --hard HEAD is now at 2ab88f9 Revise terminology from master/slave to leader/follower
  • 115. 1. Codify Everything 2. Pre-Plan outcomes at build-time 3. Create reproducible artifacts 4. Idempotent APIs and Tooling 5. Developer-Centric Operations 6. Make small, well understood changes changes 7. Start where it makes sense for your organization
  • 117. IMBUED TRUST INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
  • 118. SMALL SUCCESS INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 VAULT
  • 119. WIDE EYES INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 VAULT
  • 120. HA BACKEND INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 VAULT
  • 121. ROBUSTVAULT! INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 VAULT
  • 122. HA CONSUL + HAVAULT INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 VAULT
  • 123. SECRETS AT LAST INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 SECRETS VAULT
  • 124. AUTOMATION INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 NOMAD SECRETS VAULT
  • 125. FULL STACK VALUE INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 BUSINESS OBJECTIVE MYAPP NOMAD SECRETS VAULT
  • 126.
  • 127. RISK MITIGATED INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 BUSINESS OBJECTIVE MYAPP NOMAD SECRETS VAULT SECRETS CONSUL CLUSTERAPPLICATION CONSUL CLUSTER
  • 128.
  • 129. SELF-HEALING SYSTEMS INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 TRIAGE DIAGNOSE TREATPREVENT
  • 130. SELF-ASSEMBLING SYSTEMS INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
  • 131. SELF-ASSEMBLING SYSTEMS INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 FOUNDATION
  • 132. SELF-ASSEMBLING SYSTEMS INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 FOUNDATION PLATFORM
  • 133. SELF-ASSEMBLING SYSTEMS INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 FOUNDATION PLATFORM APP
  • 134. SELF-ASSEMBLING SYSTEMS INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 FOUNDATION PLATFORM APP "Easy"
  • 135. SELF-ASSEMBLING SYSTEMS INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 FOUNDATION PLATFORM APP "Easy" Tough
  • 136. SELF-ASSEMBLING SYSTEMS INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 FOUNDATION PLATFORM APP "Easy" Hard Tough
  • 137. SELF-ASSEMBLING SYSTEMS INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 FOUNDATION PLATFORM APP
  • 138. ERROR BUDGET INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
  • 139. ERROR BUDGET INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 Big Budget
 Less Important Smaller Budget
 More Important
  • 140. PLAN FOR KNOWN FAILURE INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
  • 141. INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 PLAN FOR KNOWN FAILURE
  • 142. INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 KNOWN KNOWNS PLAN FOR KNOWN FAILURE
  • 143. INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 KNOWN UNKNOWN PLAN FOR KNOWN FAILURE
  • 144. INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 PLAN FOR KNOWN FAILURE
  • 145. INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 UNKNOWN UNKNOWN PLAN FOR KNOWN FAILURE
  • 146. INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 PLAN FOR KNOWN FAILURE
  • 147. INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 PLAN FOR KNOWN FAILURE
  • 148. RISK MANAGEMENT INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
  • 149. RISK MANAGEMENT INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 Insiders OpenSSL Application
 Vulnerabilities
  • 150. RISK MANAGEMENT INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
  • 151. AUTOMATION INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2
  • 152. AUTOMATION INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 GOOD BAD UGLY
  • 153. EMBRACE AUTOMATION INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2 Creative Industrious Lazy Mental Drift
  • 154. • Self-Healing • Self-Assembly • Error Budgeting • Failure Planning • Risk Management • Automation THINGS WE EMBRACE INCREMENTALISM LIFE CYCLE CODIFY EXAMPLE 1TENETS EXAMPLE 2