What are Attestations in Azure Policy?

With regular policies in Azure you may be familiar with some common concepts such as effect
, enforcement mode
, resources being compliant
or non-compliant
and so on and so forth.
It can be a policy that states Public network access should be disabled
and if the resource has its public endpoint enabled then the policy is non-compliant
and vice versa if it is disabled and only using private link then it is compliant
. Not super difficult to wrap ones head around. These policies usually have an effect such as Deny
to prohibit the creation of resources that do not match the criteria of the policy. You also have DeployIfNotExists
which you can use together with a managed identity to remediate resources to ensure they follow suit. And you may have even seen and used policies with the Modify
effect which can update your resources, also using a managed identity.
You have Audit
which will just report on the resource and informing you if it is compliant or not but will not actually deny any changes made to existing or new resources that are effected by the policy. There are more, you can find all of them HERE
And then we have the manual
effect policy which I recently learned about. These manual
effect policies are actually quite interesting, usually found in regulatory compliance initiatives such as NIST, PCI DSS and ISO. Their default compliance state is Unknown
instead of compliant
or non-compliant
. It can be controls that could be called Complete security training for the team
This means that you could potentially use these controls like this:
1. Every team needs to complete some basic training in Security, Azure & Terraform
2. They complete this training and supply evidence of this in some way. We create a policy attestation
resource that can look something like this:
"properties": {
"policyAssignmentId": "/subscriptions/{subscriptionID}/providers/microsoft.authorization/policyassignments/{assignmentID}",
"policyDefinitionReferenceId": "{definitionReferenceID}",
"complianceState": "Compliant",
"expiresOn": "2023-07-14T00:00:00Z",
"owner": "{AADObjectID}",
"comments": "This subscription has passed a security audit. See attached details for evidence",
"evidence": [
{
"description": "The results of the security audit.",
"sourceUri": "https://gist.github.com/contoso/9573e238762c60166c090ae16b814011"
},
{
"description": "Description of the attached evidence document.",
"sourceUri": "https://contoso.blob.core.windows.net/contoso-container/contoso_file.docx"
},
],
"assessmentDate": "2022-11-14T00:00:00Z",
"metadata": {
"departmentId": "{departmentID}"
}
}
The policy becomes compliant
instead of Unknown
, sort of like a super complex to-do list.
They can expire so you can make the attestation only valid for 1 year for example, then it expires and training has to be refreshed.
This is maybe way too complicated in the real world but that is at least what I think Microsoft is trying to achieve with these manual
effect policies. Have you used them?
More about attestations
Attestations in Azure are resources that are not listed anywhere. You can only administer them though the ARM API, AZ CLI or Azure Powershell. This however makes it possible for us to declare them in code in order to keep track of them.
We will complete the following objectives:
- Assign a
manual
effect policy with Terraform - We will self-attest to the policy that it should be marked completed or
compliant
- We will create the
attestation
resource in Terraform
We have covered Azure Policy extensively on this blog but incase you want a visual representation of what we will create and how Azure Policy works then see this image:

First we need to create our base Terraform code, this will contain:
- The Terraform block and provider version
- Provider blocks and configuration (AzureRM & AzAPI)
- A policy definition & policy assignment resource
terraform {
required_providers {
azapi = {
source = "Azure/azapi"
version = "2.2.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "4.18.0"
}
azuread = {
source = "hashicorp/azuread"
version = "3.1.0"
}
}
}
provider "azapi" {}
provider "azurerm" {
features {}
subscription_id = var.azure_subscription_id
}
data "azurerm_subscription" "current" {}
resource "azurerm_policy_definition" "this" {
name = "Azure-Attestation-Custom"
policy_type = "Custom"
mode = "All"
display_name = "Everyone needs to prove their love for Azure before this can be attested to"
description = "What the title says..."
parameters = jsonencode({
effect = {
type = "String"
value = "Manual"
}
})
policy_rule = jsonencode({
if = {
field = "type",
equals = "Microsoft.Resources/subscriptions"
},
then = {
effect = "[parameters('effect')]"
}
})
}
resource "azurerm_subscription_policy_assignment" "this" {
name = azurerm_policy_definition.this.name
subscription_id = data.azurerm_subscription.current.id
policy_definition_id = azurerm_policy_definition.this.id
display_name = azurerm_policy_definition.this.display_name
description = azurerm_policy_definition.this.description
parameters = jsonencode({
effect = {
value = "Manual"
}
})
}
I also create a variables.tf
variable "azure_subscription_id" {
type = string
default = "Your-Subscription-ID"
description = "Azure Subscription ID"
}
variable "environment" {
type = string
description = "Environment"
}
variable "location" {
type = string
description = "Location"
}
variable "location_short" {
type = string
description = "Location Short"
}
And a dev.tfvars
file:
environment = "dev"
location = "swedencentral"
location_short = "se"
I will deploy running the following commands
terraform init
terraform apply -var-file variables/dev.tfvars -auto-approve
Normally you would run terraform plan
as well to preview the changes, I felt confident here ;)

Review the attestation
So after a while we will have our new policy with its Unknown
compliant state as such:

So lets assume that the team here, called the ChatGPT
team, needs to prove their love for Azure, which they have. They sent us this message:
From ChatGPT:
Dearest Microsoft Azure,
From the moment I spun up my first virtual machine, you captivated my heart with your endless cloud capabilities and effortless scalability. You make my dreams of boundless innovation come true, always ready to expand and adapt at my slightest request. My love for your clean interfaces and resilient architecture grows every time I deploy a new service. Thank you for consistently lifting my ideas into the cloud and reminding me there’s no limit to what we can create together.
It brings a tear to my eye, everytime...
Creating the attestation
So let us create the attestation. Since we can use the ARM API, Powershell or CLI we have the option to use the azapi
provider in Terraform.
resource "azapi_resource" "this" {
type = "Microsoft.PolicyInsights/attestations@2024-10-01"
name = "ChatGPT-Loves-Azure"
parent_id = "/subscriptions/${var.azure_subscription_id}"
body = {
properties = {
assessmentDate = "2025-12-09T00:00:00Z"
comments = "The ChatGPT team has proven their love for Azure"
complianceState = "Compliant" # Or Non-Compliant
evidence = [
{
description = "The love letter submitted by the ChatGPT team"
sourceUri = "The URI location of the evidence, could be a blob storage URL"
}
]
expiresOn = "2026-12-09T00:00:00Z" # A year later from the assessmentDate property
owner = data.azuread_client_config.this.object_id
policyAssignmentId = azurerm_subscription_policy_assignment.this.id
}
}
}


terraform apply -var-file variables/dev.tfvars -auto-approve
We can verify that the attestation resource exists by querying with az cli

And finally, if we head to the policy compliance section of the Azure portal we should no longer see the Unknown
policy compliance state

Conclusion
Today we again reviewed the structure of Azure Policies. We also created a policy assignment with Terraform with the manual
effect. We created an attestation that will be valid for one year and in that time we can be sure that the ChatGPT team will love Azure!
Hope you enjoyed todays post.
References


About me
