

# Everything as code


 *Everything as code* is a software development practice that seeks to apply the same principles of version control, testing, and deployment to enhance maintainability and scalability of all aspects of the development lifecycle, including networking infrastructure, documentation, and configuration. This practice adds the ability to automate more, leading to faster, more consistent, and more reliable development cycles. By using code for as many use cases as possible, developers can achieve a higher level of quality, reduce the risk of errors, and increase the speed at which they can deploy new features and updates. 

**Topics**
+ [

# Indicators for everything as code
](indicators-for-everything-as-code.md)
+ [

# Anti-patterns for everything as code
](anti-patterns-for-everything-as-code.md)
+ [

# Metrics for everything as code
](metrics-for-everything-as-code.md)

# Indicators for everything as code


Adopt a code-centric approach across the development lifecycle for enhanced maintainability, scalability, and automation.

**Topics**
+ [

# [DL.EAC.1] Organize infrastructure as code for scale
](dl.eac.1-organize-infrastructure-as-code-for-scale.md)
+ [

# [DL.EAC.2] Modernize networks through infrastructure as code
](dl.eac.2-modernize-networks-through-infrastructure-as-code.md)
+ [

# [DL.EAC.3] Codify data operations
](dl.eac.3-codify-data-operations.md)
+ [

# [DL.EAC.4] Implement continuous configuration for enhanced application management
](dl.eac.4-implement-continuous-configuration-for-enhanced-application-management.md)
+ [

# [DL.EAC.5] Integrate technical and operational documentation into the development lifecycle
](dl.eac.5-integrate-technical-and-operational-documentation-into-the-development-lifecycle.md)
+ [

# [DL.EAC.6] Use general-purpose programming languages to generate Infrastructure-as-Code
](dl.eac.6-use-general-purpose-programming-languages-to-generate-infrastructure-as-code.md)
+ [

# [DL.EAC.7] Automate compute image generation and distribution
](dl.eac.7-automate-compute-image-generation-and-distribution.md)

# [DL.EAC.1] Organize infrastructure as code for scale


 **Category:** FOUNDATIONAL 

 Infrastructure as code (IaC) provides consistent and automated infrastructure management capabilities which are important to DevOps adoption. Effectively organizing and scaling IaC within your organization enhances flexibility, readability, and reusability across multiple teams, while streamlining infrastructure provisioning and maintenance. 

 When working with IaC files and artifacts, apply modern practices such as modular design for improved management and reuse, and maintain thorough in-code documentation for clarity. Adopt IaC-specific design patterns, like breaking down infrastructure templates into reusable modules. Treat IaC testing with the same rigor as other software, focusing on security risks like excessive privileges or open security groups, while upholding quality standards. Use version control for IaC templates to ensure traceable changes, reliable rollbacks, and efficient sharing across the organization. 

 You must carefully consider your organization's governance structure when deciding how to implement IaC at scale. Depending on the specific needs, your organization might find one model more suitable than the other, or even adopt a hybrid approach that combines elements of both. The right approach to scaling is dependent on factors such as team dynamics, operating model, application type, and the desired rate of change. 

 For example, services like [AWS Service Catalog](https://aws.amazon.com/servicecatalog/) and [AWS Proton](https://aws.amazon.com/proton/) provide distinct methods to distribute and consume secure-by-default software components and IaC in different ways. Service Catalog suits organizations favoring predefined deployment standards and centrally defined resource provisioning, while AWS Proton is ideal for organizations that allow development teams to maintain infrastructure and application autonomy. Some organizations might prefer to adopt a fully decentralized approach, where individual teams provision and manage their own [AWS CloudFormation](https://aws.amazon.com/cloudformation/) IaC templates. Choose the tools and distribution methods that best support your governance model and business goals. 

**Related information:**
+  [Infrastructure as code - Introduction to DevOps on AWS](https://docs.aws.amazon.com/whitepapers/latest/introduction-devops-aws/infrastructure-as-code.html) 
+  [Infrastructure as Code on AWS - An Introduction](https://blog.awsfundamentals.com/infrastructure-as-code-on-aws-an-introduction) 
+  [Accelerate deployments on AWS with effective governance](https://aws.amazon.com/blogs/architecture/accelerate-deployments-on-aws-with-effective-governance/) 
+  [Source Control concepts](https://aws.amazon.com/devops/source-control/) 
+  [Design Patterns](https://refactoring.guru/design-patterns) 
+  [Amazon's approach to security during development: Octane](https://youtu.be/NeR7FhHqDGQ?t=1571) 

# [DL.EAC.2] Modernize networks through infrastructure as code


 **Category:** FOUNDATIONAL 

 The practice of managing networking configurations through code, including network automation, version control, and rigorous testing to ensure quality and stability. Apply DevOps practices to networking systems to streamline network operations, reduce human errors, and speed up network deployments. *Networking as code* enables the predictable and repeatable provisioning of networking components, making infrastructure more modular and less prone to error. 

 Managing networking components as code requires cultural, process, and tool changes. Shift from a centralized, manual model of network management to a more autonomous model where individual teams can operate independently. Loosely couple networking architectures to create modular components that can be managed, maintained, and scaled individually. Use infrastructure as code (IaC) tools to define network infrastructure and configurations and use development lifecycle capabilities like continuous integration and continuous delivery (CI/CD) for deploying networking changes. Like other systems, networking changes should undergo automated testing to provide assurance that they meet functional, non-functional, and security requirements before deployment. 

 Often, platform teams manage network components on behalf of individual teams when possible so that all teams do not need to become networking experts. However, for cases where this is not possible, use shared resources or predefined network configuration templates which have embedded best practices and secure defaults. This approach encourages predictable and repeatable provisioning of self-service networking components. Have guardrails in place within the environment to enforce compliance of networking requirements. 

**Related information:**
+  [NetDevOps: A modern approach to AWS networking deployments](https://aws.amazon.com/blogs/networking-and-content-delivery/netdevops-a-modern-approach-to-aws-networking-deployments/) 
+  [NetDevSecOps to modernize AWS networking deployments](https://aws.amazon.com/blogs/networking-and-content-delivery/netdevsecops-to-modernize-aws-networking-deployments/) 
+  [Field Notes: Using Infrastructure as Code to Manage Your AWS Networking Environment](https://aws.amazon.com/blogs/architecture/field-notes-using-infrastructure-as-code-to-manage-your-aws-networking-environment/) 

# [DL.EAC.3] Codify data operations


 **Category:** FOUNDATIONAL 

 Codifying data operations in a DevOps environment extends the infrastructure as code (IaC) principle to data management, which involves treating database schemas, data transformations, and data pipelines as code. Codifying data operations enables other DevOps capabilities including the use of data management pipelines for data lifecycle management, enforcing quality assurance and governance standards, providing auditability of changes, and the ability to rollback changes when necessary. 

 Store database schemas, along with any related procedures, views, and triggers, in version control systems alongside your application code. This enables the ability to track, review, and test schema changes before deploying them to your production environment. To start managing existing data source schemas as code, database migration and event analysis tools like [AWS DMS Schema Conversion Tool](https://aws.amazon.com/dms/schema-conversion-tool/) and [Amazon EventBridge](https://aws.amazon.com/eventbridge/) can help to infer schemas from existing data sources. 

**Related information:**
+  [Converting database schemas using DMS Schema Conversion](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_SchemaConversion.html) 
+  [Creating an Amazon EventBridge schema](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-schema-create.html) 
+  [Using Amazon RDS Blue/Green Deployments for database updates](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html) 

# [DL.EAC.4] Implement continuous configuration for enhanced application management
[DL.EAC.4] Implement continuous configuration for enhanced application management

 **Category:** RECOMMENDED 

 *Configuration as code* is the practice of managing and tracking configuration changes as code, providing an audit trail and reducing errors from manual changes. [Continuous configuration](https://www.allthingsdistributed.com/2021/08/continuous-configuration-on-aws.html) uses configuration as code to enhance configuration management by allowing configuration changes to be made independently of application code deployments. 

 Configuration should be separated from application code to allow for independent tracking and management. Use tools designed for managing configurations as code, such as [AWS AppConfig](https://aws.amazon.com/systems-manager/features/appconfig/), to manage configuration externally from the application. Create fully automated pipelines that perform continuous integration and continuous delivery (CI/CD) based on changes to the configuration code. Just like with application deployment pipelines, these configuration deployment pipelines should run quality assurance tests, followed by deployment in a non-production environment before deploying to production. 

 It's important to distinguish between static and dynamic configuration types. Static configurations do not change during the software's runtime and are specific to each environment. Dynamic configurations can be adjusted at runtime without downtime. [Feature flags](https://aws.amazon.com/systems-manager/features/appconfig#Feature_flags) are examples of dynamic configurations that can be used to control which features are enabled per environment to decouple release from deployment. Operational configurations, such as log level, throttling thresholds, connection/request limits, alerts, and notifications, can be static or dynamic depending on the use case and need to be managed. Application modes, which toggle the application to run as either *development*, *test*, or *production*, are typically considered to be static configuration that is set at startup and do not change. 

 General use cases for continuous configuration include application integration tuning, feature toggling, allowing access to premium content through allow lists, and addressing operational issues and troubleshooting. To manage your configurations effectively, establish a routine to prevent configuration bloat. While it can seem tempting to externalize as many variables as possible, an excessively complex configuration file can lead to confusion and errors. Carefully evaluate the necessity, frequency of change, and runtime requirements of each value to decide if it should be included as dynamic configuration.  

 For large-scale deployment of configuration as code, a [Dynamic Configuration Pipeline](https://aws-samples.github.io/aws-deployment-pipeline-reference-architecture/dynamic-configuration-pipeline/index.html) is recommended. This allows centralized management of the entire workload configuration and its components across all environments. It ensures that all configurations are version-controlled, adhere to quality assurance and code review processes, and is capable of progressively deploying configuration changes and performing rollbacks as necessary to minimize system disruptions. 

 Continuous configuration is beneficial in DevOps environments, as it improves operational efficiency and scalability. However, not every system requires the complexity associated with continuous configuration. Therefore, each workload should be evaluated depending on architecture choice, team preferences, and service level objective requirements. 

**Related information:**
+  [AWS Cloud Adoption Framework: Operations Perspective - Configuration management](https://docs.aws.amazon.com/whitepapers/latest/aws-caf-operations-perspective/configuration-management.html) 
+  [AWS AppConfig](https://aws.amazon.com/systems-manager/features/appconfig/) 
+ [Continuous configuration](https://www.allthingsdistributed.com/2021/08/continuous-configuration-on-aws.html)

# [DL.EAC.5] Integrate technical and operational documentation into the development lifecycle
[DL.EAC.5] Integrate technical and operational documentation into the development lifecycle

 **Category:** RECOMMENDED 

 Integrating documentation and code involves creating, maintaining, and publishing documentation using the same tools and processes used for application development. With this approach, changes to systems should be immediately reflected in documentation, reducing the risk of discrepancies between system behavior and documentation. By making documentation part of the development lifecycle, it becomes a living document that evolves with the system over time. 

 Documentation should be stored in a versioned source code repository and written in a machine-readable markup language, such as Markdown. The documentation can be made directly accessible through the repository or through knowledge sharing tools capable of rendering the markup language, like Git-based wikis, static site generators, or directly in developers' integrated development environments (IDEs). 

 Code should include clear, insightful comments and commit messages should be structured using a machine-readable specification, such as [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). This information can be used as a source to generate detailed documentation and change logs using tools specific to the programming language and platforms being used. Many of these tools can create API references, class diagrams, or other technical documents from inline comments in your source code, ensuring the documentation is always in line with the most recent changes. Automate this process by adding a stage to the deployment pipeline to generate documentation with every change to a main, releasable branch. 

 This approach is not only limited to documenting code, but also can be used to store operational documentation like incident response procedures, disaster recovery plans, training material, and onboarding processes. While some aspects of these documents still likely require manual effort to create, the benefits of incorporating these documents into the development lifecycle include enforced reviews of changes, ability to write tests to suggest updating documentation when changes are significant or made to important components, and versioning the documents for auditability. 

**Related information:**
+  [AWS Well-Architected Reliability Pillar: REL12-BP01 Use playbooks to investigate failures](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_testing_resiliency_playbook_resiliency.html) 
+  [Write the Docs: Docs as Code](https://www.writethedocs.org/guide/docs-as-code/) 
+  [One AWS team's move to docs as code](https://www.youtube.com/watch?v=Cxuo3udElcE) 
+  [AWS Incident Response Playbook Samples](https://github.com/aws-samples/aws-incident-response-playbooks) 
+  [Using code as documentation to save time and share context](https://github.com/readme/guides/code-as-documentation) 
+  [DocFx](https://dotnet.github.io/docfx/) 
+  [How to build an automated C\$1 code documentation generator using AWS DevOps](https://aws.amazon.com/blogs/modernizing-with-aws/how-to-build-an-automated-c-code-documentation-generator-using-aws-devops/) 

# [DL.EAC.6] Use general-purpose programming languages to generate Infrastructure-as-Code
[DL.EAC.6] Use general-purpose programming languages to generate Infrastructure-as-Code

 **Category:** RECOMMENDED 

 Developing infrastructure as code (IaC) using general-purpose programming languages aligns closely with modern software development practices and DevOps principles. IaC has traditionally been implemented as predefined templates modeled through domain-specific languages using markup languages like JSON or YAML. During deployment, these templates are provided parameters which specify environment-specific details. While parameterized templates are still a best practice for traditional IaC templates, this approach can become difficult to develop, troubleshoot, and manage as infrastructure and environments become more complex. 

 Using general-purpose programming languages changes how we develop, manage, and deploy IaC. It is no longer a collection of parameterized templates, but instead infrastructure is written in common programming languages such as TypeScript, Python, or Java, and can be treated the same as other code throughout the development lifecycle. Instead of providing environment-specific configuration during deployment, tools like [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/v2/guide/best-practices.html#best-practices-apps-stages) generate separate templates for each environment using configurations defined in source code. This provides a more predictable, consistent, and reproducible deployment process. 

 Transitioning to using general-purpose programming languages for IaC can also change how you govern IaC at scale. For example, AWS CDK includes the ability to consume, publish, and version software components called AWS CDK [constructs](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html) through private artifact registries or the open-source [Construct Hub](https://constructs.dev/) registry. 

**Related information:**
+  [Best practices for developing and deploying cloud infrastructure with the AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/best-practices.html) 
+  [CDK for Terraform (CDKtf)](https://www.terraform.io/docs/cdktf/index.html) 
+  [CDK for Kubernetes (CDK8s)](https://cdk8s.io/) 
+  [AWS Solutions Constructs](https://docs.aws.amazon.com/solutions/latest/constructs/welcome.html) 
+  [Artifact Repository - AWS CodeArtifact](https://aws.amazon.com/codeartifact/) 
+  [Infrastructure IS Code with the AWS CDK](https://www.youtube.com/watch?v=Lh-kVC2r2AU) 
+  [Best practices for using the AWS CDK in TypeScript to create IaC projects](https://docs.aws.amazon.com/prescriptive-guidance/latest/best-practices-cdk-typescript-iac/introduction.html) 
+  [Adding the "AWS CDK bootstrap" action in Amazon CodeCatalyst](https://docs.aws.amazon.com/codecatalyst/latest/userguide/cdk-boot-action.html) 

# [DL.EAC.7] Automate compute image generation and distribution
[DL.EAC.7] Automate compute image generation and distribution

 **Category:** OPTIONAL 

 The management of compute images, including containers and machine images, can be optimized and made more reliable through a code-driven approach. Compute images generally include a base image, libraries, environment variables, application code, and configuration files. Similar to other forms of infrastructure as code (IaC), compute images can be codified, stored in version control systems, tested, and distributed as part of the development lifecycle. 

 Establish automated pipelines for building, testing, and distributing compute images. The build stage creates the image based on its code definition, the *test* stage validates the functionality and security compliance of the image, and the *distribution* stage ensures the image is readily available for teams to use in their environments and workloads. Updates to the images should be automated, accounting for software patches, security enhancements, and other modifications. 

 Given the diverse range of applications and infrastructure requirements, especially when using managed cloud-based services, not all organizations or workloads necessitate using dedicated compute images or codifying them. 

**Related information:**
+  [Amazon EC2 Image Builder](https://aws.amazon.com/image-builder/) 
+  [AWS Deployment Pipeline Reference Architecture](https://aws-samples.github.io/aws-deployment-pipeline-reference-architecture) 
+  [What is AWS App2Container?](https://docs.aws.amazon.com/app2container/latest/UserGuide/what-is-a2c.html) 

# Anti-patterns for everything as code
Anti-patterns
+  **Checking in secrets:** Storing sensitive data, such as API keys, passwords, or other secrets, directly in the code base or version control system is a critical security vulnerability. Checking in secrets exposes sensitive credentials to anyone with access to the repository and, if the repository is public, to the world. Instead, use management tools or services to store and retrieve secrets securely. These tools can integrate with deployment pipelines and systems during runtime to provide secrets only when necessary, ensuring they remain confidential and are not inadvertently exposed. 
+  **Manual modifications to infrastructure:** Making manual changes to infrastructure can be time consuming and error prone, leading to inconsistencies that can be difficult to troubleshoot and resolve. Actively prevent users from making manual changes to environments and workloads to ensure consistent and reliable deployments. 
+  **Outdated or incomplete documentation:** Ignoring documentation or treating it as an afterthought can lead to knowledge gaps, misunderstandings about system behavior, and misleading users. As the system changes over time, documentation needs to be continuously updated to align with the current system state. 
+  **Ignoring configuration drift:** Failing to track and manage changes to your system's configuration can result in configuration drift, where the actual configuration state deviates from the desired state. Overtime this can lead to system instability, security vulnerabilities, and operational inefficiencies. Use continuous configuration management practices and automated governance capabilities to keep configurations in a known and secure state. 
+  **Bypassing code review and testing:** Failing to review and test IaC changes, including data, documentation, configuration, and networking components is an anti-pattern that can lead to data inconsistencies, data loss, and system instability. It's important to apply the same quality assurance practices to IaC as you would to application code. 
+  **Inefficient IaC development practices:** Treating IaC differently from application code, especially by not using version control, diminishes developer experience and increases deployment risk. By not versioning IaC files, teams lose the ability to track changes over time, identify when specific changes were made, or correlate infrastructure changes with system behavior. Additionally, storing large, monolithic IaC files makes development and management of IaC more complex, as intertwining components make it challenging to identify specific sections and understand changes being made. Mitigate these challenges by segmenting IaC into modular units consistent with the system's architecture and maintain them within version control systems. Using general-purpose programming languages when developing IaC can further simplify managing IaC like other application code. 
+  **Monolithic network architectures:** Designing a network where different components are tightly coupled leads to reduced flexibility and increased complexity. This pattern can make troubleshooting and scaling particularly challenging, as changes in one component may inadvertently impact others. Instead, create a modular network design expressed through multiple, well-organized IaC files where components are loosely coupled and can be individually managed, maintained, and scaled. 

# Metrics for everything as code
Metrics
+  **Infrastructure code coverage**: The percentage of infrastructure components managed by infrastructure as code (IaC) compared to the total number. High infrastructure code coverage implies improved manageability, reproducibility, and automation capabilities for systems. Calculate by dividing the number of infrastructure components managed as code by the total number of infrastructure components and multiply by 100 to get the percentage. 
+  **Configuration drift rate**: The percentage of infrastructure components drifting from their intended configuration over time. Configuration drift can introduce security vulnerabilities, performance issues, and general system instability. Implement configuration management tools, routinely run drift detection processes, and automate corrective actions to improve this metric. Monitor infrastructure configurations regularly and calculate the drift rate by dividing the number of drifted configurations by the total number of configurations and multiplying by 100 to get the percentage. 
+  **Documentation update frequency**: The average frequency that documentation is updated relative to code or system changes. Stale or out-of-date documentation can lead to operational inefficiencies, onboarding issues, and system misuse. This metric can be improved by defining documentation as code, automating the release of documentation through a delivery pipeline, and prompting developers to update docs as part of the development lifecycle. Track the number of documentation changes over a set time frame and compare it to the number of system changes in that same time frame. 
+  **Time to provision infrastructure**: The time taken to provision a new infrastructure component or environment using IaC. A key advantage of using code to define infrastructure is improved change lead time and deployment frequency through the reduction of inconsistent and manual infrastructure provisioning practices. Use time-stamped logs to measure the time interval between the initiation and completion of infrastructure provisioning tasks. 
+  **Mean time to recover (MTTR)**: The average time taken to restore a system after a failure. Ensure IaC is testable, automate infrastructure provisioning, and maintain configuration consistency across deployments. Monitor downtime incidents and compute the average recovery time over a designated period. 