How to Use Azure Policy to Ensure Compliance and Developer Freedom
This blog post was co-written with Paul McCrady, Principal Consultant at Contino.
Cloud computing is often seen as the nirvana to developers in large enterprises–a chance to break the shackles of old and embark on a new journey towards true freedom and autonomy.
Yet, developers moving from “born in the cloud companies” or less regulated sectors to the modern enterprise are often faced with a stark reality–one where the cloud platform they know and love is restricted to the use of "pre-approved" templates or modules using tightly controlled pipelines. And where securing the cloud is approached using artifacts created by a central team, mandating governed configurations and offering Terraform modules or ARM templates with little flexibility to change.
In a desire to standardise these offerings across multiple clouds, a lowest common denominator approach typically evolves, to the detriment of the value afforded by these platforms when used as intended. This approach limits the ability of developers to evaluate new technologies and prevents them from changing their workflow to enable rapid creation of business value. All of which ultimately results in frustration amongst developers and difficulty on the part of the business in retaining cloud-native talent.
So how can highly-regulated enterprises ensure that their dev teams can operate both securely and with the freedom they need?
What Is Azure Policy?
Azure Policy is part of the Azure Governance Platform that helps your organisation's engineering teams standardise their operational and deployment practices and enforce how cloud resources are configured within an environment.
You can use Azure Policy specifically to:
- Apply compliance/security policies to existing resources
- Automate compliance/security policies for new resources
- Assess compliance at scale
- Get a single-pane-of-glass view of your compliance posture across all resources
Some common use cases of Azure Policy include:
- Forcing a tagging strategy on resources to aid billing enquiries
- Only allowing resources to be deployed to specific regions for regulatory compliance
- Limiting the SKU types of Virtual Machines to help with reducing compute costs
But what are the main features of Azure Policy that work to ensure developer freedom on top of compliance?
How Azure Policy Offers Freedom and Control
1. Provides a mechanism of auditing nuanced configurations of Azure resources
From a cloud provider point of view, built-in native tools are often overlooked in the quest for cloud agnosticism. Azure Policy provides a mechanism for Auditing nuanced configurations of Azure resources. Such as enforcing AAD onboarding for AKS or the presence of standardised tags.
These configurations can provide valuable insight on a continuous basis for reporting and/or auditing purposes. Authored as Json files, this provides teams with a productive and consistent approach to writing policy in a language familiar to modern developers.
Policy can be authored within the Azure portal itself (and exported to GitHub if desired), or within an IDE/text editor of choice. This flexible approach to authoring and software versioning provides developers with freedom of choice in tooling and control through popular release management software.
2. Blocks resource configurations that are non-compliant
Azure Policy has a flexible structure that lets you switch how a policy effect is applied. The same policy that audited resources for non-compliance can be switched to Deny. This ensures validation of requests hitting the Azure Resource Management API meet the desired configuration, regardless of a developer’s provisioning tool choice–be it the Azure Portal, ARM Templates, Terraform, Powershell or Pulumi.
Deny assignments are a great way of introducing guard rails, paving the way towards developer freedom and blocking creation/configuration of resources not meeting a desired state, regardless of the tool choice.
This level of policy control provides the assurance needed but it can also leave developers with a difficult feedback loop. Despite their new found freedom, a need to configure standard settings such as logging or core security controls could be met with a loop of policy rejections if these controls aren't clearly documented.
How can we reduce the effort for our developers, removing the need for them to apply the standard configuration, whilst still ensuring that controls are met with as little friction as possible in their daily workflow?
3. Supports the ability to “Deploy If Not Exists” (DINE Policy Affect)
In addition to being able to “Audit” or “Deny” certain configurations, Azure Policy supports the ability to "Deploy If Not Exists" (often referred to as a DINE policy) using ARM templates as part of the policy definition.
When you apply this type of policy, policies configured to modify resources will automatically augment new resources on creation, but they will not change the state of the infrastructure deployed prior to the policy being enforced–that is unless you explicitly ask it to remediate for you.
This ensures that existing resources aren't changed without human interaction, but can still leverage the benefits of the pre-codified desired state controls.
Existing resources that fail to meet the desired state are flagged as non-compliant, with the ability to run remediation tasks to bring them into line when appropriate. Using the same controls, Azure can then remediate existing resources with minimal interaction, using an appropriately scoped, least-privileged identity.
This is an important point to note as often development teams will expect a DINE policy to automatically remediate existing resources. It does not. DINE policy scan results can be a useful education tool in helping developers write compliance level code from the outset.
4. Gives developers the freedom to use their tool of choice
Developers can be given the freedom to use their tools of choice, writing infrastructure configuration using a domain-specific language (ARM/HCL), a scripting language (Powershell), or a programming language (C#, Typescript, Go). They can do this safe in the knowledge that, regardless of the requested configuration, Azure can augment the incoming request to ensure that the desired controlled configurations are applied transparently to the user.
As an example, this allows compliance teams to implement core logging requirements such as sending audit logs to a named Log Analytics workspace. A policy can automatically apply these settings to resources when created and more importantly, enforce and report on the continued compliance state of resources regardless of the deployment tool of choice.
This simplifies the developer workflow, as their infrastructure configuration needs to only focus on specifics based on their use case–such as size/scale, with the core controls performed by the platform transparently.
These features in Azure Policy can massively bridge the gap between security/compliance teams and platform users, supporting freedom with the assurance that your organisation’s security posture can't be compromised.