twelve factor applications

42
Twelve Factor Applications a methodology for building software-as-a- service

Upload: anthony-roja-buck

Post on 16-Apr-2017

440 views

Category:

Documents


0 download

TRANSCRIPT

Twelve Factor Applications

a methodology for building software-as-a-service

job: Head of Engineering @ Just Eatlives: Bristol

from: Stoke on Trent

Roja?

IntroductionA methodology, agnostic to language, to build applications that intend to

● Minimise developer onboarding cost

● Exhibit portability via a clean contract with the OS and wider

platform

● Are deployable on modern cloud platforms with low administration

● Embrace continuous, multi-environment deployment

● Scale without tooling, architecture or development practice changes

Background● Formalisation by the Heroku team

● The distillation from observing, measuring and managing millions of

SaaS apps and optimising best practices, dynamics of app growth,

developer collaboration while minimising software erosion

● Motivated to highlight some systemic problems and to offer a set of

broad conceptual solutions to those problems along with a shared

vocabulary

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Codebase● A single codebase tracked within a version

control system (git, svn etc.)

● Multiple code bases == distributed system

● Multiple apps sharing code == dependency

● Will be multiple deployments of the

codebase with potentially differing versions

Codebase - Why?● Ensures clear audit history

● Trivialises rollback; deploy v - 1

● Enables clear, visible progression to live; dev,

staging, production

● Facilitates concurrent team development

● Minimises inter-app refactoring risk

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Dependencies● Explicitly declare and isolate all dependencies; name, version, ...

● Make use of vendoring / bundling of dependencies

● Utilise tooling to automate the download and updating of

dependencies

● Never rely on the implicit existence of system tools

● Never rely on the implicit existence of system wide-packages

Dependencies - Why?● Ensures a clean contract with the execution environment

● Provides guarantees around inter-deployment consistency

● Outlines explicitly the real dependencies of the implementation

● Tooling simplifies the process of maintaining and updating

dependencies

● Minimises new-developer setup friction

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Config● Extract all config from code to ensure strict code / config separation

● Store config in the environment

● Store only environment agnostic config within config files

● Consider each config explicit to a deployment, not a config group;

development, test, staging, ...

Config - Why?● Config is everything that should change between deploys, it can be

seen as the “deployment variables”

● Config may contain credentials which should be restricted; Can the

codebase be made open source at any time without compromise?

● Grouped configs are not scalable; prod, qa, roja-laptop, branch-#232

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Backing Services● Treat backing services as attached resources

● Make no distinction between local and 3rd party services

● Each backing service is a resource; dev-db, prod-db, SQS

● Resources can be attached and

detached to deploys at will

Backing Services - Why?● Misbehaving resources can be swapped at will without code

modification

● Environment can expose relevant resources; test has test-db

● Prevents vendor lockin

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Build, release, run● Strictly separate integration stages

● Build; Create an executable bundle “build” from a version of the

codebase with vendored dependencies and assets

● Release; Combine build with deployment config to form a “release”

● Run; Execute bundle in an

environment enriched with

the config

Build, release, run - Why?● Restricts runtime code / config mutability to minimise non-determinism

● Facilitates continuous integration and automated rollback

● Ensures auditable versioned artifacts

● Allows for the automated re-execution and scaling of releases

dependent on hardware state

● Minimises run complexity

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Processes● Execute the app as one or more stateless processes

● All processes share nothing; all state must reside in a stateful backing

store

● No assumption is made around the state of the environments memory

● Any valid request should be severable from any executing instance

● Use of the transient filesystem should be highly discouraged

Processes - Why?● Robustness to restarts, re-deployments, configuration changes, …

● Agnostic to underlying hardware and memory state

● Simplified request routing and robustness to failure

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Port binding● Export services via port binding

● Do not rely on the injection of a web server within the execution

environment

● Not restricted to protocol; HTTP is just as valid as XMPP

● Any app can become a backing app to another app

● Port binding defined by environment

Port binding - Why?● Reliance upon a web server adds an un-vendored system

dependency

● Increased flexibility through protocol independence

● Simplifies multi-process and multi-environment hosting on singular

hardware

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Concurrency● Scale out via process model

● Processes can not span more than one

physical machine

● Should rely on the execution environment to

handle process crashes, restarts, shutdowns

Concurrency - Why?● Execution concurrency is simplified to the

execution environment running multiple

instances of a release

● No requirement for internal multiplexing or

threading, though does not preclude either

● Adding more concurrency becomes an

automatable trivial process

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Disposability● Applications are disposable; can be started and stopped with no

notice

● Startup and shutdown time is minimised

● Graceful shutdown is performed whenever a SIGTERM is received

● Workers shut down gracefully by returning their current job

● Job processing should be idempotent

● Crash-only design is implemented

Disposability - Why?● Enables fast elastic scaling, rapid (re)deployment or config changes

● Rapid startup aids production robustness by allowing process

migration

● Reentrant jobs ensure that work processing is recoverable

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Dev / prod parity● Keep development, staging, and production as similar as possible

● Keep backing services the same across environments; sqlite

● Minimise reliance on backing service adaptors; ORM etc

● Any adaptors that are used should be identical across environments

Dev / prod parity - Why?● Lightweight local services are less compelling than they once were

given trivial containerisation of most production alternatives

● Abstractions add complexity and minimise the exposed featureset of

the underlying service

● Even well aligned alternatives can introduce trivial difference and

thus expose differing behaviour between environments

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Logs● Treat logs as event streams

● Always log to stdout, and only stdout

● Let the environment handle the distribution, routing and storage of

logs

Logs - Why?● Logging code is substantially simplified

● Interception and re-routing becomes a concern of the environment and

therefore removes code change requirements

● Logs can be expanded to output ever-increased verbosity which can

then be fed into analysis tools; splunk, kibana, ...

● Log storage can be centralised trivially without application

awareness

The Twelve Factors

I. CodebaseII. DependenciesIII. ConfigIV. Backing ServicesV. Build, release, runVI. Processes

VII. Port bindingVIII. ConcurrencyIX. DisposabilityX. Dev / prod parityXI. LogsXII. Admin processes

Admin processes● Run admin / management tasks as one-off processes

● Tasks should be part of the codebase

● Tasks should be run within the environment within which they should

affect

● Environments should expose a REPL where feasible

Admin processes - Why?● Code synchronization issues are reduced through the shared code

base

● As config, release and dependencies are shared the task cannot

affect incorrect dependencies or act based on incorrect configuration

● REPL enables direct interaction and simple running of tasks from

within the environment

see: 12factor.netme: linkedin.com/in/rojabuckjobs: tech.just-eat.com/jobs/

Questions?