1. Preface
    1. Why I Wrote This Book
    2. What This Book Is and Isn’t
    3. Who This Book Is For
    4. Principles, Practices, and Patterns
    5. The FoodSpin Examples
    6. For More
    7. Conventions Used in This Book
    8. O’Reilly Online Learning
    9. How to Contact Us
    10. Acknowledgments
  2. I. Foundations
  3. 1. What Is Infrastructure as Code?
    1. Infrastructure as Code
    2. From the Iron Age to the Cloud Age
      1. Cloud Age Approaches to Change Management
      2. The Path to the Cloud Age
    3. Strategic Goals and Infrastructure as Code
    4. System Architecture Goals and Infrastructure as Code
    5. Use Infrastructure as Code to Optimize for Change
      1. Myth: Infrastructure Doesn’t Change Very Often
      2. Myth: We Can Build the Infrastructure First and Automate It Later
      3. Myth: Speed and Quality Are Trade-Offs
    6. The Four Key Metrics
    7. Core Practices for Infrastructure as Code
      1. Define Everything as Code
      2. Continually Test and Deliver All Work in Progress
      3. Build Small, Simple Pieces That Can Change Independently
    8. Conclusion
  4. 2. Principles of Cloud Infrastructure
    1. Assume Systems Are Unreliable
    2. Make Everything Reproducible
    3. Avoid Snowflake Systems
    4. Create Disposable Things
    5. Minimize Variation
    6. Ensure That Any Procedure Can Be Repeated
    7. Apply Software Design Principles to Infrastructure Code
    8. Conclusion
  5. 3. Infrastructure Platforms
    1. Infrastructure Platforms
      1. Infrastructure Resources
      2. IaaS in the Data Center
      3. Multicloud
    2. Engineering Platforms
      1. Platform Services
      2. Providing Platform Service Functionality
    3. Platform Delivery Services
      1. Application Delivery Services
      2. Infrastructure Delivery Services
      3. Platform Management Services
    4. Conclusion
  6. 4. Infrastructure as Code Tools and Languages
    1. Coding Infrastructure
      1. Moving Beyond Task-Based Scripting
      2. Understanding What You Can Define as Code
      3. Code or Configuration?
      4. Defining Configuration as Code
      5. Managing Your Code in a Source Code Repository
    2. Infrastructure Code Processing
      1. Understanding When Code Executes
      2. Processing and Deploying Infrastructure Code
      3. Previewing Changes
      4. Tracing Infrastructure Code Execution
      5. Managing Infrastructure State
    3. Infrastructure as Code Tools
    4. Types of Languages for Coding Infrastructure
      1. Procedural and Idempotent Code
      2. Imperative and Declarative Languages and Tools
      3. Domain-Specific and General-Purpose Languages
      4. Low-Level and High-Level Languages
      5. Infrastructure from Code
    5. Conclusion
  7. II. Design
  8. 5. Design Principles for Infrastructure as Code
    1. Design Considerations for Infrastructure as Code
      1. CUPID Properties for Design
      2. Cohesion and Coupling
      3. Providers, Consumers, and Interfaces
      4. Management of Interfaces Between Components
      5. Use of Interfaces for Composability
    2. Design Across Infrastructure Code Lifecycle Stages
    3. Design Forces
      1. Design Forces for Source Code
      2. Design Forces for Infrastructure Packaging and Deployment
      3. Design Forces for Runtime
      4. Design Forces Across Lifecycle Stages
    4. Conclusion
  9. 6. Infrastructure Components
    1. The Infrastructure Components
      1. The Start of Infrastructure Design: Workloads
      2. Infrastructure Compositions
      3. Infrastructure Deployment Stacks
      4. Infrastructure Code Libraries
      5. Libraries as Deployable Stacks
    2. Sharing and Reuse of Infrastructure Code
      1. Sharing Infrastructure Code Components
      2. Sharing Stack Code Across Multiple Instances
      3. Sharing Stack Instances Across Workloads
    3. Application-Driven Infrastructure Design
      1. Horizontal Design
      2. Vertical Design
      3. Shared Infrastructure Included in Vertical Design
      4. Reference Application-Driven Infrastructure Design
    4. Design Workflow
    5. Conclusion
  10. 7. Designing Deployable Infrastructure Stacks
    1. Patterns for Sizing and Structuring Stacks
      1. Full System Stack
      2. Monolithic Stack
      3. Application Group Stack
      4. Single Service Stack
      5. Micro Stacks
      6. Shared Stack
    2. Stack Patterns for Multiple Instances of Infrastructure
      1. Multi-Environment Stack
      2. Snowflakes as Code
      3. Reusable Stack
    3. Conclusion
  11. 8. Configuring Infrastructure Stack Instances
    1. Key Concepts
      1. Use Stack Parameters to Create Unique Identifiers
      2. Keep Parameters Simple
    2. Example Stack
    3. Patterns for Configuring Stacks
      1. Configuration in Code
      2. Manual Stack Parameters
      3. Stack Environment Variables
      4. Scripted Parameters
      5. Stack Configuration Files
      6. Deployment Wrapper Stack
      7. Pipeline Stack Parameters
      8. Stack Parameter Registry
    4. Implementing a Configuration Registry
      1. Integrated Infrastructure Automation Tool Registries
      2. Standalone Packaged Configuration Registries
      3. IaaS Platform Registry Services
      4. Your Own Configuration Registry
      5. Single or Multiple Configuration Registries
    5. Handling Secrets
      1. Generating Secrets
      2. Storing Secrets in Encrypted Files
      3. Using a Secrets Storage Service
      4. Injecting Secrets at Runtime
    6. Conclusion
  12. 9. Integrating Infrastructure Stacks
    1. Example Infrastructure Deployment Stacks
    2. Resource Discovery Patterns
      1. Resource Matching
      2. Stack State Lookup
      3. Integration Registry Lookup
    3. Implementing Resource Discovery
      1. Implementing Discovery in Stack Code
      2. Using Dependency Injection
      3. Managing Dependencies in a Deployment Script
      4. Wiring Stacks Together with a Composition
    4. Conclusion
  13. 10. Designing Infrastructure Code Libraries
    1. Facade Module
      1. Also Known As
      2. Motivation
      3. Applicability
      4. Consequences
      5. Implementation
      6. Related Patterns
    2. Obfuscation Module
      1. Motivation
      2. Applicability
      3. Consequences
      4. Implementation
      5. Related Patterns
    3. Unshared Module
      1. Motivation
      2. Applicability
      3. Consequences
      4. Implementation
    4. Bundle Module
      1. Motivation
      2. Applicability
      3. Consequences
      4. Implementation
      5. Related Patterns
    5. Spaghetti Module
      1. Motivation
      2. Consequences
      3. Implementation
      4. Related Patterns
    6. Infrastructure Domain Entity
      1. Motivation
      2. Applicability
      3. Implementation
      4. Related Patterns
    7. Stack Module
      1. Also Known As
      2. Motivation and Applicability
      3. Implementation
    8. Modular Monolith
      1. Motivation
      2. Consequences
      3. Implementation
      4. Related Patterns
    9. Conclusion
  14. 11. Building Servers as Code
    1. Defining Servers
      1. What’s on a Server
      2. Where Things Come From
      3. Server Configuration Code
      4. Server Roles
    2. Creating and Provisioning a New Server Instance
      1. Creating a Server by Using Network Provisioning
      2. Creating an IaaS Server by Hand
      3. Creating a Server as Part of a Stack
      4. Creating a Server from an Event
    3. Configuring a New Server Instance
      1. Baking Images and Frying Instances
      2. Pull Configuration with Initialization Scripts
      3. Push Configuration with External Commands
    4. Updating and Changing Servers
      1. Push on Change
      2. Continuous Configuration Synchronization
      3. Changing Servers by Replacement
      4. Immutable Server
    5. Building Server Images
      1. Hot-Cloning an Existing Server
      2. Booting an OS Installer
      3. Modifying a Stock Image
      4. Orchestrating Image Building
    6. Conclusion
  15. 12. Designing Environments
    1. Multi-Environment Architectures
    2. Multiple Delivery Environments
    3. Environments Split for Alignment
      1. Aligning Environments to System Architecture
      2. Aligning Environments to Organizational Structure
      3. Aligning Environments to Governance Concerns
    4. Multiple Environment Replicas
      1. Designing Environments for Operability Scenarios
      2. Distributing Environments Geographically
      3. Replicating Environments for User Bases
    5. Environment Implementation Layers
      1. Using Design Forces to Choose the Environment Implementation Layer
      2. Testing and Delivering Changes to Environment Infrastructure
    6. IaaS Resource Groups and Environments
    7. Environments with Multiple Stacks
    8. Conclusion
  16. 13. Providing Application Runtime Infrastructure
    1. Application-Driven Infrastructure Design
    2. Application Runtime Platforms
      1. Servers as Code
      2. Server Clusters as Code
      3. Application Clusters as Code
      4. Serverless Application Infrastructure
    3. Cluster Topologies
      1. Multiple Environments in One Cluster
      2. One Cluster per Environment
      3. Multiple Clusters per Environment
      4. Cross-Environment Clusters
    4. Conclusion
  17. III. Delivery
  18. 14. Core Infrastructure Delivery Workflows
    1. Continuous Delivery Principles for Infrastructure as Code
      1. Automate the Full Process
      2. Make Changes Using Only the Automated Process
      3. Ensure That Environments Are Consistent
      4. Deliver Changes Comprehensively
      5. Keep Delivery Cycles Short
      6. Keep All Code Production-Ready
      7. Ensure That Code and Deployed Resources Are Consistent
      8. Minimize Disruption When Deploying Changes
    2. Core Infrastructure Delivery Workflow
      1. Development Stage
      2. Build Stage
      3. Test Stages
      4. Release Stage
      5. Run Stage
      6. Workflow Cycles
    3. Workflows and Team Topologies for Delivering Software and Infrastructure
      1. Infrastructure Instance Management Teams
      2. Full Stack Infrastructure Team
      3. Infrastructure Enablement Team
    4. Measuring Infrastructure Delivery Effectiveness
    5. Conclusion
  19. 15. Building and Distributing Infrastructure as Code
    1. Build Stage: Preparing for Distribution
      1. Code Processing Steps for Building and Deploying
      2. Build on Deploy Workflow
      3. Build Once, Deploy Many Workflow
      4. Bundling or Locking Dependencies
      5. Pull Requests and Trunk-Based Development
    2. Distribution of Infrastructure Code
      1. Distributing Code Branches as Artifacts
      2. Distributing Stack Packages as Artifacts
      3. Distributing Libraries as Artifacts
    3. Integration Workflows
      1. Fan-in: Integrating Components During Delivery
      2. Federation: Integrating Components at Runtime
      3. Monorepo: Integrating Components in the Build
      4. Pretesting Infrastructure
    4. Infrastructure Service Teams
      1. Shared Infrastructure as a Service
      2. Provisioning an Infrastructure Instance on Demand
      3. Providing Deployable Infrastructure as a Component
      4. Multiple Infrastructure Platform Teams
    5. Conclusion
  20. 16. Implementing Infrastructure Delivery with Pipelines
    1. Organizing Projects in a Codebase
      1. Organizing Build Projects and Repositories
      2. Organizing Types of Code
    2. Working on Code Locally
      1. Local IaaS Emulators
      2. Personal IaaS Environments
      3. Just Enough Environment
    3. Designing Infrastructure Delivery Pipelines
      1. Pipeline Stage Content
      2. Pipeline Stage Actions
      3. Pipeline Stage Context
      4. Delivery Pipeline Software and Services
    4. Using Delivery Orchestration Scripts
    5. Conclusion
  21. 17. Infrastructure Code Testing Strategy
    1. Why Continually Test Infrastructure Code?
      1. What Continual Testing Means
      2. Immediate Testing and Eventual Testing
    2. What Should We Test with Infrastructure?
    3. Challenges with Testing Infrastructure Code
      1. Tests for Declarative Code Often Have Low Value
      2. Unit Testing Code Generation
      3. Testing Infrastructure Code Is Slow
      4. Dependencies Complicate Testing Infrastructure
    4. Progressive Testing
      1. Test Pyramid
      2. Swiss Cheese Testing Model
    5. Testing in Production
      1. What You Can’t Replicate Outside Production
      2. Managing the Risks of Testing in Production
    6. Conclusion
  22. 18. Infrastructure Code Testing Implementation
    1. Offline Testing Stages for Stacks
      1. Syntax Checking
      2. Offline Static Code Analysis
      3. Connected Static Code Analysis
      4. Supply-Chain Checks
      5. Local Infrastructure Emulators
    2. Use Test Fixtures to Handle Dependencies
      1. Use Test Fixtures to Replace Providers
      2. Use Test Fixtures to Replace Consumers
      3. Refactor Components So They Can Be Isolated
    3. Online Testing Stages for Stacks
      1. Preview: Seeing What Changes Will Be Made
      2. Verification: Making Assertions About Infrastructure Resources
      3. Outcomes: Proving Infrastructure Works Correctly
    4. Test Instance Lifecycles
      1. Persistent Test Stack
      2. Ephemeral Test Stack
      3. Dual Persistent and Ephemeral Stack Stages
      4. Periodic Stack Rebuild
      5. Continuous Stack Reset
    5. Test Orchestration
      1. Consider Test Orchestration Tools
      2. Support Local Testing
      3. Avoid Tight Coupling with Pipeline Tools
    6. Conclusion
  23. 19. Deploying Infrastructure
    1. Understanding Software Deployment Strategies
      1. Push Deployment for Software
      2. Pull Deployment for Software
      3. GitOps Deployment for Software
    2. Using Infrastructure Deployment Strategies
      1. Siloed Infrastructure Deployment
      2. Application Infrastructure Descriptor
      3. Infrastructure from Code
    3. Running Infrastructure Deployments
      1. Deploying Infrastructure Code from Your Computer
      2. Deploying from a Central Service
      3. Deploying from a Delivery Pipeline
      4. Using an Infrastructure Code Deployment Service
      5. Infrastructure as Data
      6. Infrastructure Deployment Scripts
    4. Triggering Infrastructure Deployments
      1. Using Input Materials for Deployment
      2. Manually Triggering Deployment
      3. Automatically Triggering Deployment
      4. Implementing Triggers
    5. Conclusion
  24. 20. Changing Existing Infrastructure
    1. Changing a System Incrementally
      1. Break a Change into Increments
      2. Handle Incomplete Changes
    2. Safely Changing Live Infrastructure
      1. Manually Remap Live Infrastructure
      2. Remap Live Infrastructure in Pipelines
      3. Define Changes to Live Infrastructure in Code
      4. Script Live Infrastructure Changes
      5. Use Expand and Contract to Incrementally Change Live Infrastructure
    3. Minimizing Disruption When Deploying Changes
      1. Blue-Green Deployments
      2. Rolling Upgrades and Canary Releases
    4. Managing Data When Changing Live Infrastructure
      1. Store and Load
      2. Use Continuous Data Transfer
      3. Segregate Data Infrastructure
      4. Separate Software and Data Changes
      5. Use Continuous Disaster Recovery
    5. Conclusion
  25. 21. Governance
    1. Shift Left
      1. Workflow for Shifting Left
      2. Team Topologies for Shifting Left
    2. Compliance as Code
      1. Controls by Component Design Layer
      2. Controls by Workflow
    3. Conclusion
  26. Index
  27. About the Author