March 24

Tags

What you could learn from ‘Infrastructure as Code’ by Kief Morris (2016, 326 pages)

Good book about modern software development are hard to find. Infrasturcre as code balance explaini the high-level pricnilpes with detail in a clear and compelling way.

Infrastructure as code emphasises ‘consistent, repeatable routines for provision and changing systems and their configurations’. Changes are made to definitions, which are then automatically validated and cascaded across the whole system.

Infrastructure as Code principles

  1. Systems can be easily reproduced – every element can be rebuilt with no effort
  2. System are disposable – team tracks Mean Time To Recovery, rather than Mean Time Between Failure
  3. Systems are consistent – patched and up-to-date
  4. Processes are repeatable – standard service requests can be done in minutes without involving infrastructure team
  5. Design is always changing

Infrastructure as Code practices

  1. Use defintion files
  2. Self docuemtned systems and processes
  3. Version all the things
  4. Continiously test systems and proccesses
  5. Small changes rather than big batches
  6. Keep servies avalible continiously

There are three core components of cloud infrastructure are:

  1. Compute resources
  2. Storage resources
  3. Network resources

Provisioning means:

  1. Assignning resources to an element
  2. instantiating the element
  3. Installnjg softeware onto the element
  4. Configuring the element
  5. Registering the element with infrastructure services

Goals for automated server management:

  • A server can be provision <5 minutes, without human involvement
  • Server configuration changes are applied without human involvement
  • Changes are applied to all existing and new relevant servers
  • All processes are repeatable, consistent, self-contained and transparent
  • Processes can be changed easily
  • Automated tests are run whenever anything is changed
  • All changes are versioned and are applied across all environments

Test Driven Development (TDD) is essential to complex and critical software.

  • Every module has automated tests that test the module in isolation
  • When tests are hard to maintain, it shows code is too large or complex, or tighly couppled

Continuous Delivery is not Continuous Deployment. The point should be to make sure that each change could go to production immediately (not must go to production). There are three ways to deploying changes that you do not want users to see or use:

  1. feature hiding – make the code not visible to users
  2. feature toggles/flags – enable a feature to be turned on/off in production (must be removed after use)
  3. branch by abstraction – deploy old and new component and allow a switch between the two

Testing. High quality means a fast system. You identify errors early and fix them quickly. There are some top tips:

  • The whole team needs to be involved in testing, rather than an isolated group
  • When a test fails it must be the No1 priority to fix
  • When a bug is found, write a test which exposes the bug. Run the test it should fail. Fix the bug. Run the test. When it passes – deploy.
  • Have a balanced test suit. Lots of low-level tests to find problems early and quickly find the problem, some medium-level tests to make sure coupled code works together, and a few high-level tests to make sure everything works together
  • All builds should pass automated tests, and the results should be seen in minutes
  • Test at the lowest possible level. The tests are faster, feedback is quicker and it is easier to narrow down which part of the code is responsible
  • Do not use arbitary targets. Avoid the temptation to set thresholds for coverage and number of tests. Different code will need different testing, let the experts decide
  • Have good code hygiene. Use static analysis tools to maintain clear, high-quality code.
  • Independent tests. Tests should be able to be run in any order or run any test by itself and get the same result
  • Those that build the code should write the tests. Testers/QA should help, provide advice and run additional/exploratory testing

Change management. You should be continuously be changing your infrastructure through a change managment pipeline. Every deployment must pass automated tests first, before human testing. Feedback must be immediate

Build

  • Syntax checking and static analysis
  • Compile code (where relevant)
  • Unit tests
  • Local execution tests (use test doubles)
  • Generate and publish reports & documentation
  • Package for deployment

Publishing an artefact

  • Build a package and upload it to a repository
  • Upload a set of definition files
  • Create a template server

Artefacts

  • Atomic – can be assembled, tested and applied together as a single unit
  • Portable – progressed through the pipeline, with different versions can be applied to different environments or instances
  • Versioned – reliably, repeatably and unambiguously applied to any environment
  • Complete – must have everything needed to provision or configure the component
  • Consistent – apply the artefact to any two component instances and it should have the same results

Pipeline practices

  • Prove production readiness for every change (i.e., do not branch)
  • Start every change from the beginning of the pipeline
  • Emergencies fixes must use the pipeline (it is a lot less risky)
  • Keep pipeline short (this makes them fast)
  • Decouple pipelines – each component must be deployable separately
  • Use components like a library if other parts of the code need its functionality (be sure to keep it up-to-date)

Manage interfaces between components

  • Ensure backwards compatibility (don’t break other people code)
  • Decouple deployments from released – deploy, but not to customers as a test
  • Use version tolerance – make sure your code can understand which versions of code it interacts with and can adjust automatically
  • Provide test doubles to others – you have already built these for you to test, so share them with others to help them (they may also make your doubles better)
  • Test providers with contract testing – this means you know early if you are going to break
  • Test with a reference consumer – if you need a lot of testing, automate a reference consumer that gets automatically updated with each new deployment
  • Smoke test with the provider interface
  • Run consumer-driven contract tests (CDC)

Infrastructure teams. Focus on automating everything that moves.

  1. Redesign or reconfigure all repetitive or time consuming tasks
  2. Implement automation that handles everything transparenlty with out oversight
  3. Self-serve everything –
  4. Good, conscise documentation that allow people to carry out tasks on thier own

How to ensure the operational quality of production infrastructure.

  • Service continuity – keep services available to end users in the face of problems and changes
  • Data continuity – keep data available and consistant
  • Disaster recovery – coping well when the worst happens
  • Security – keeping bad actors at bay

Heroku guidelines

  1. One code base tracked in version control, many deploys
  2. Explicitly declare and isolate dependencies
  3. Store config in the environment
  4. Treat backing services as attached resources
  5. Strictly separate build and run stages
  6. Execute the app as one or more stateless processes
  7. Export services via port binding
  8. Scale our via process model
  9. Maximise robustness with fast startup and graceful shutdown
  10. Keep development, staging and production as similar as possible
  11. Treat logs as event streams
  12. Run admin/management tasks as one-off processes

Zero downtime changes

  • Blue-green replacements. Run two instances keep, one live while upgrading the other
  • Phoenix replacements. Build a new instance every time something is changed
  • Reduced the scope of replacement. Blue/green will not work above a certain size/complexity you then need to split services up
  • Canary replacement. Deploy a new instance along side the old one. A subset of traffic is directed to the new instance to test it

Infrastructure as Code is one of the best books I have read on software development. The book uses principles, anti-patterns and patterns to help the reader gain an in-depth understanding of modern engineering infrastructure.

You can buy Infrastructure as Code from Amazon UK using this link https://amzn.to/2Uamjac