continuous deliveryfiles.meetup.com/16787152/cd_benny.pdf · terraform • declarative language for...

46
Continuous Delivery & Infrastructure

Upload: others

Post on 15-Jul-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Continuous Delivery &

Infrastructure

Page 2: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Introduction

Benny Cornelissen

• Infrastructure Architect @ Xebia

• Platform Architect @ TNT

Page 3: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

New demands for Infrastructure

Page 4: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

On-demand

• Experimentation

• Demos

• Deploy every feature branch

• No human intervention to get something done

Page 5: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Ownership• Promote to staging / production

• Define how your application should run

• Inspect application logs & metrics

• You build it, you run it

• Power and Responsibility

Page 6: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Pets vs Cattle

• Specific —> Generic

• Fix —> Replace

• Easily scalable

Page 7: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Building a Platform

Page 8: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Basic Pillars

• Infrastructure as Code

• Design for Failure

• Abstract applications from the OS, and vice versa

• Automate All The Things

Page 9: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Infrastructure as Code

Page 10: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Infrastructure as Code

• Repeatable

• Testable

• Predictable

• Self-Documenting

Page 11: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Terraform

• Declarative language for creating infrastructure across providers

• Codify the required end-state, not the way to get there

• Create cross-provider dependencies

resource "aws_instance" "myinstance" { instance_type = "t2.small" ami = "ami-cda312be" root_block_device { delete_on_termination = true volume_size = 20 } key_name = "${aws_key_pair.data-team.key_name}" security_groups = ["${aws_security_group.data-team.name}"]}

myinstance.tf

Page 12: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Terraform

• Declarative language for creating infrastructure across providers

• Codify the required end-state, not the way to get there

• Create cross-provider dependencies

resource "aws_instance" "myinstance" { count = 1000 instance_type = "t2.small" ami = "ami-cda312be" root_block_device { delete_on_termination = true volume_size = 20 } key_name = "${aws_key_pair.data-team.key_name}" security_groups = ["${aws_security_group.data-team.name}"]}

myinstance.tf

Page 13: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Terraform

• Develop

• Review / Plan

• Apply

• Destroy

$ vim myplatform.tf

$ terraform plan

$ terraform apply

$ terraform destroy

Page 14: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Flexibility with Terraform• Create multiple isolated instances of the platform

• The production platform

• A platform for testing our own stuff

• …

• Create a custom-sized platform

Page 15: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Design for FailureBecause everything that can fail, will fail at some point

Page 16: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Design for Graceful FailureBecause nobody likes to get paged at 3AM…

Page 17: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Graceful Failure

• Networking: Elastic Load Balancing, multiple Nginx proxies

• Compute: Auto Scaling Groups for various instance types

• Applications: HA deployments, automatic rescheduling

Page 18: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Example

Page 19: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

CoreOS CoreOSCoreOS CoreOS

Auto Scaling Group

App App App

Proxy Proxy Proxy Proxy

Backend

Backend

Backend

Elastic Load Balancer

Page 20: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

CoreOS CoreOS CoreOS

Auto Scaling Group

App App

Proxy Proxy Proxy

Backend

Backend

Elastic Load Balancer

Page 21: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

CoreOS CoreOS CoreOS

Auto Scaling Group

App App

Proxy Proxy Proxy

Backend

Backend

Elastic Load Balancer

App Backend

Page 22: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

CoreOS CoreOS CoreOS

Auto Scaling Group

App App

Proxy Proxy Proxy

Backend

Backend

Elastic Load Balancer

App Backend

CoreOS

Proxy

Page 23: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Abstract App ↔ OS

OS-agnostic apps, App-agnostic OSes

CoreOS

App 1 (v1.1) App 2 App 1

(v1.2)

Page 24: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Abstract OS / Apps• Run everything in a container

• Your runnable artifact is the container

• build once, run anywhere:

• On your laptop

• On an on-premise datacenter

• On a cloud-based platform

• your artifact only requires a 64-bit Linux machine with a Docker daemon

Page 25: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Containerize everything

• you can:

• upgrade a library (or OpenSSL) without breaking 10 other things

• run apps that require conflicting libraries on the same machine

• run 2 versions of the same app

Page 26: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Containers and DevOps

• identical dev/tst/acc/prd environments, because we use the same container

• ownership and responsibility move to the product team

Page 27: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Building Containers

• Repeatable

• Testable

• Predictable

• Self-documenting

Page 28: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Dockerfile

• Describes how a container should be configured

• Describes a configuration process starting from a known starting-point

FROM docker.example.com/expample/java:masterENTRYPOINT ["bin/myapp"]

USER rootWORKDIR /home/docker/appADD target/universal/myapp-*.tgz \ /home/docker/app/RUN ["chown", "-R", "docker:docker", "."]USER docker

EXPOSE 9000ENV SERVICE_9000_TAGS="app,http,private"

Dockerfile

Page 29: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Automate All The Things

Wiring, glue, and magic tricks

Page 30: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Automate!

• Proxy (Nginx) configuration

• Application Dashboard

• CI/CD (Jenkins) configuration

Page 31: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Proxy configuration

• Which services are running?

• Where are they running?

• How many containers are running?

• Do they have special properties? (HTTPS-redirects, Proxy endpoints, BasicAuth, Auth exceptions)

Page 32: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

ConsulService Registry, Service Discovery,

Key-value store, Health checking

Page 33: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Service Discovery

• Each application is registered in the Service Registry

• Metadata (key/value) is registered in the KV-tree

• When an application is stopped, it is removed from the Service Registry

Page 34: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Service Lookup

• Lookup through:

• DNS

• REST API

$ dig srv +short dev-mytnt-master.service.consul1 1 57753 infra-prod-dev-10.9.8.95.node.dc1.consul.

$ curl http://consul:8500/v1/catalog/service/dev-mytnt-master[{"Node":"infra-prod-dev-10.9.8.95","Address":"10.9.8.95","ServiceID":"registrator:dev-mytnt-master:3000","ServiceName":"dev-mytnt-master","ServiceTags":["app","http","https-redirect","dev"],"ServiceAddress":"10.9.8.95","ServicePort":57753,"ServiceEnableTagOverride":false,"CreateIndex":15689987,"ModifyIndex":15699641}]

Page 35: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Consul to ConfigA bit of magic..

Page 36: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Consul-template

• Create a configuration template

• Generate configuration files based on a template and data in consul

Page 37: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Configuring a Proxy

• Get all services tagged with ‘http’ and ‘public’

• Render basic Nginx config

• Based on additional tags and K/V data, render additional config blocks

Page 38: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Example

Page 39: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

$ curl http://consul:8500/v1/catalog/service/dev-mytnt-master | jq .[ { "Node": "infra-prod-dev-10.9.8.95", "Address": "10.9.8.95", "ServiceID": "registrator:dev-mytnt-master:3000", "ServiceName": "dev-mytnt-master", "ServiceTags": [ "app", "http", "https-redirect", "dev" ], "ServiceAddress": "10.9.8.95", "ServicePort": 57753, "ServiceEnableTagOverride": false, "CreateIndex": 15689987, "ModifyIndex": 15699641 }]

Page 40: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

$ curl http://consul:8500/v1/kv/services/dev-mytnt-master/?keys | jq .[ "services/dev-mytnt-master/ci_build_number", "services/dev-mytnt-master/creation_time", "services/dev-mytnt-master/git_branch_sanitized", "services/dev-mytnt-master/git_commit", "services/dev-mytnt-master/git_repository", "services/dev-mytnt-master/git_url", "services/dev-mytnt-master/noauth", "services/dev-mytnt-master/server_aliases"]

Page 41: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

$ curl http://consul:8500/v1/kv/services/dev-mytnt-master/noauth | jq .

[ { "LockIndex": 0, "Key": "services/dev-mytnt-master/noauth", "Flags": 0, "Value": "fiogLyhwdWJsaWNhcGlzfGFwaSk=", "CreateIndex": 15690001, "ModifyIndex": 15787949 }]

$ curl http://consul:8500/v1/kv/services/dev-mytnt-master/noauth?raw

~* /(publicapis|api)

Page 42: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

upstream dev-mytnt-master { least_conn; server 10.9.8.95:57753 max_fails=3 fail_timeout=60 weight=1;}

server { listen 80; server_name mytnt-master.* mytnt.*; client_max_body_size 0;

location / { include includes/basic-auth.conf; proxy_pass http://dev-mytnt-master; include includes/proxy-headers.conf; include includes/cors-headers.conf; }

location ~* /(publicapis|api) { auth_basic off; proxy_pass http://dev-mytnt-master; include includes/proxy-headers.conf; include includes/cors-headers.conf; }}

nginx.conf

Page 43: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

FROM docker.tntdigital.io/tnt/node:master

COPY package.json /home/docker/app/COPY .npmrc /home/docker/app/RUN npm install > /dev/null

COPY . /home/docker/app/RUN gosu root chown -R docker:docker /home/docker/app/

EXPOSE 3000ENV SERVICE_3000_TAGS="app,http,https-redirect"ENV SERVICE_NOAUTH="~* /(publicapis|api)"ENV SERVICE_SERVER_ALIASES="mytnt.net mytnt.com *.mytnt.net *.mytnt.com"

ENTRYPOINT ["gulp"]CMD ["serve:ci"]

Dockerfile

Page 44: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Platform Development

Page 45: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

• Low level infra: deploy a separate platform using Terraform

• Platform components:

• local dev setup (Vagrant, Docker Compose, Docker)

• Automated Docker builds

• lab platform

Page 46: Continuous Deliveryfiles.meetup.com/16787152/CD_Benny.pdf · Terraform • Declarative language for creating infrastructure across providers • Codify the required end-state, not

Thank You$ while true; do echo "Hello, World!"; done