Infrastructure as code is an increasingly popular way to codify and automate system configurations and installations.
Systematizing the many parameters necessary to instantiate a cloud computing environment is critical to manage thousands of virtual resources across multiple providers and regions. IaC translates configuration policies into a readable format IT admins easily edit, audit and reproduce. Policy as code (PaC) is the application of this principle to security, software development and IT operations rules and processes.
Policy as code documents rules, controls and best practices, and automates enforcement and implementation through software known as a policy engine. A policy engine, like a software compiler, translates structured code into implementations, whether for network security configuration or Kubernetes cluster parameters. Much like IaC systems and software compilers, PaC engines check automatically for logical inconsistencies, syntax errors and missing dependencies to minimize or -- ideally -- eliminate errors in policy enforcement and implementation. PaC's roots go back 30 years to Donald Knuth's concept of literate programming, which combined software code and documentation into a single file. Literate programming is a further generalization of policy as code because it combines narrative descriptions and logical, structured algorithms. Knuth wrote, "Programming is best regarded as the process of creating works of literature, which are meant to be read." In essence: Code is a language, and the premise of a language is to be understood by humans -- therefore, code should also be human-readable.
PaC combines these same ideals, namely:
- A policy narrative translates into a portable, readable document format, such as HTML or PDF.
- A structured policy description compiles into system and network parameters, cloud service configurations and deployment instructions.
Portable is the operative word because, like a software compiler, PaC instructions enable a policy compiler to implement policies on many different types of hardware and environments. The policy should be literate and understandable by those tasked to implement, update and audit it.
When using Knuth's paradigm mentioned above, there is a strong binding between the controls, the rules -- which represent the human-readable intent -- and the code.
Policy-as-code benefits, best practices
PaC is gaining adherents for the same reasons that drive the adoption of IaC:
- Remove ambiguity. It expresses potentially unclear policies as unambiguous, deterministic code.
- Provide developer guardrails and code testability. This reduces the chance of costly, dangerous errors via sandboxed development environments.
- Encourage consistency and accountability via version control systems. This enables incremental bug fixes and code reuse, which facilitate policy consistency.
- Improve development efficiency. It uses a library of policy templates that apply to new applications and infrastructure environments.
- Reduce implementation errors and deployment time. PaC provides machine-readable policy instructions that can be applied programmatically. PaC systems can also integrate with CI/CD toolchains to include policy enforcement in the development pipeline.
- Minimize chances for policy drift. PaC enables deployed systems to be audited automatically for policy compliance and to correct any detected gaps quickly by applying the correct policy programmatically.
The following best practices maximize the benefits of policy as code and improve policy consistency, coverage, security and accuracy.
- Use a version control system (VCS) like GitHub or BitBucket to maintain a single source for policies across platforms and applications. A VCS also enables code reuse by creating modular policies tailored to situations that can be aggregated into a comprehensive policy regime.
- Test policies on an isolated test or development environment before deploying them to production systems. With a test sandbox, admins can also check minor policy changes against the entire policy stack to ensure code additions don't break existing rules or leave holes in coverage.
- Use role-based access controls that integrate with existing identity and access management systems to tie policies with centrally-managed user, group and service account definitions.
- Integrate the policy VCS with existing CI/CD development pipelines and approval automation software to ensure software compliance with security and tighten the feedback loop between policy developers and reviewers.
- Adopt the Literate Programming philosophy to make policy definitions self-documenting. This means using a single source file compiled into HTML or PDF documentation and the PaC's actual code contents, usually a scriptable language like Node.js, Go, Python or a domain specific language (DSL).
PaC defines and enforces security policies, such as firewall rules; application, resource or data access controls; data encryption rules; and code provenance restrictions. It links to infrastructure-as-code systems to apply policies for infrastructure deployment, such as restrictions on container cluster and workload placement. PaC is also used for network security configurations and temporal restrictions on application or resource use.
But policy as code is still a relatively new idea, with few software tools available that target cloud environments. These include:
- HashiCorp Sentinel. A framework for policy codification with a DSL and workflow for code development and testing. It supports rules using conditional logic with granular controls. IT professionals construct rules from logical and conditional expressions. Sentinel supports changing a policy's pass/fail criteria via multiple enforcement levels and integrates with other HashiCorp infrastructure management tools, such as Consul, Nomad, Terraform and Vault.
- Pulumi CrossGuard. A PaC engine that works with its other cloud management tools for AWS, Azure, Google Cloud and Kubernetes. Polices are described in Node.js, Go, Python, Open Policy Agent (OPA) or .NET. Policy sets -- also called policy packs -- are assigned to a particular environment, like AWS, or to a policy group that applies to multiple situations. Policies are enforced centrally by the Pulumi console.
- Open Policy Agent. An open source policy engine that uses a declarative DSL, such as Rego, to express policies. OPA decouples services, such as Kubernetes or a cloud resource, from policy enforcement and, as illustrated below, returns policy decisions in response to service requests. For example, infrastructure-as-code software might query the policy engine before it creates a new compute instance to determine which regions are acceptable for deployment, given parameters about the instance type, target application and storage or network dependencies.