Allow deployments only from Terraform using Azure Policy
Hi Team,
Is it possible to block all deployments and allow it only from Terraform? I tried this but it didn't work.
{
"not": {
"anyOf": [
{
"field": "Microsoft.Authorization/roleAssignments/principalId",
"equals": "[parameters('allowedServicePrincipal')]"
}
]
}
}
Azure Policy
-
Ashok Gandhi Kotnana • 6,040 Reputation points • Microsoft External Staff
2025-03-26T16:33:43.8633333+00:00 Hi @Logan,
There is an alternative way to achieve this requirement.
Grant all users read-only permissions, except for the service principal, which should be assigned Contributor access at the subscription level. This is the simplest way to meet your requirement.
If you prefer to enforce this via Azure Policy, note that there is no default policy available to achieve this. You will need to create a custom policy.
Please let me know if you're facing any challenges
If the answer is helpful, please and "Upvote it"
-
Logan • 0 Reputation points
2025-03-26T16:43:26.45+00:00 Hi @Ashok Gandhi Kotnana , Thanks for the suggestion. We can't have this because there are some cases where we need to do the changes manually. Is there a field which can be verified by Azure policy when it's coming from Terraform or Manual or User deployment?
-
Ashok Gandhi Kotnana • 6,040 Reputation points • Microsoft External Staff
2025-03-26T17:22:13.2933333+00:00 Hi @Logan,
For the policy I cannot confirm as this is a custom policy this has to be tested before confirming with you
To identify who initiated a resource deployment:
Go to any Resource Group and check the Deployments section.
- If the deployment name starts with "Microsoft.", it indicates that the resource was created via the Azure Portal, CLI, or PowerShell if it is terraform it won't show as Microsoft. this is one method to identity, but this is manual task
- To automate this, update your PowerShell script in an Automation Account your script should get both values one if deployment name and resource
Please provide your thoughts.
-
Logan • 0 Reputation points
2025-03-27T08:00:13.4233333+00:00 Hi @Ashok Gandhi Kotnana , Thank you. Actually, I'm looking for guidance on how to identify it using Azure Policy.
Checking if anyone come across this or have any thoughts on this requirement.?
-
Venkat V • 1,645 Reputation points • Microsoft External Staff
2025-03-27T15:17:44.24+00:00 Hi@Logan
The policy will only block or audit Azure resources because Terraform is an Iaac tool and there is no way to permit Terraform deployment from Azure policy.If you have a policy in place to block resources, it will prevent them from being created, whether they are in Terraform or other.
For example, if you made a policy to prevent RG names from beginning with Test, it will prevent if you used any source to create the RG.
Alternatively, you can assign the role only to the principal that you are using for deployment in Terraform. This ensures that only the service principal has access to create resources, and no other user or service principal can do so. This way, you restrict resource creation in Azure.
-
-
-
Venkat V • 1,645 Reputation points • Microsoft External Staff
2025-03-29T03:18:33.3733333+00:00 Hi@Logan
Azure Policy
applies only tomanagement groups
,subscriptions
andresource groups
. It is not possible to assignAzure Policy
to aservice principal
. you can follow the Ms Doc for more information aboutAzure Policy
assignment.Azure Conditional Access policies in Azure AD can be used to block or restrict user access based on conditions such as user group membership, location, or sign-in risk. This allows you to set policies that limit access to resources based on the user's identity or email.
You could implement a custom solution using Azure Automation or Functions to monitor user activities or access patterns and take actions (like blocking users) based on your criteria (like specific email addresses or conditions).
-
-
Logan • 0 Reputation points
2025-04-01T10:05:32.8366667+00:00 Hi Venkat V,
It wasn't very helpful, which is why I did some additional research but still couldn't find a solution. I understand that it's not available and we may need to think outside the box to figure out how we can prevent resource creation or modification, even if the user has permission to do so, but it should be only allowed from the Service Principal.
The reason I don't want to apply RBAC is that if the Terraform pipeline doesn't work, we might have to relax the policy and deploy it manually.
-
SadiqhAhmed-MSFT • 48,716 Reputation points • Microsoft Employee
2025-04-15T12:47:36.0666667+00:00 @Logan My sincere apologies for the delayed response!
From your post I understand that you want to allow deployments only through Terraform using Azure policy. You could leverage identity-based exemptions, which is currently in private preview, to achieve this scenario. With this, you’d be able to apply a policy to prevent resource creation or modification, then create an exemption for that assignment which would allow the Terraform pipeline’s Service Principal ID to bypass the policy. Refer to the document link - https://learn.microsoft.com/en-us/azure/governance/policy/concepts/exemption-structure for details on identity-based exemption private preview.
Let us know if you have any questions!
-
Logan • 0 Reputation points
2025-04-16T16:59:58.8033333+00:00 Hi @SadiqhAhmed-MSFT
Looks like the link provided is incorrect or I can't see the identity-based exemption based references.
-
SadiqhAhmed-MSFT • 48,716 Reputation points • Microsoft Employee
2025-04-21T14:33:59.6666667+00:00 @Logan Sorry for the inconvenience. It is not in the public documentation yet because it is in private preview. The general structure of identity-based exemptions will look like this:
Example:
Assume you want to assign the built-in policy definition Allowed virtual machine size SKUs in your subscription to ensure that only A-family VMs can be deployed to keep cost down. You name the Policy assignment CostMgmt. However, certain engineers in your organization should be able to deploy higher-SKU, more expensive VMs for specific workloads and purposes. They should be able to bypass this policy. So, you create this exemption:Now you’re all set! When a member of deploys a higher-SKU VM such as Standard_D1, they will not be blocked.
Hope this helps!
-
Logan • 0 Reputation points
2025-04-21T14:48:15.19+00:00 Hi SadiqhAhmed-MSFT,
This is exactly what we wanted. Will i be able to test it in our tenant?
-
SadiqhAhmed-MSFT • 48,716 Reputation points • Microsoft Employee
2025-04-21T16:21:17.7166667+00:00 @Logan Yes, you can test it and let us know if you have any questions.
-
Logan • 0 Reputation points
2025-04-21T17:19:47.29+00:00 Hi SadiqhAhmed-MSFT,
I created a policy based on the template given but it is not working with any of the user id's.
Example: 1234-1234 is the my username object id and 3333-3333 is the test account. I tried with both accounts but no luck.
{ "properties": { "policyAssignmentId": "/subscriptions/SubscriptionID/providers/Microsoft.Authorization/policyAssignments/DenyResourceCreation", "policyRule": { "if": { "field": "type", "equals": "Microsoft.Storage/storageAccounts" }, "then": { "effect": "deny" } }, "resourceSelectors": [ { "name": "AllowedUsers", "selectors": [ { "kind": "userPrincipalId", "in": ["1234-1234"] }, { "kind": "userPrincipalId", "notIn": ["1111-1111", "2222-2222","3333-3333"] } ] } ], "exemptionCategory": "Waiver", "displayName": "Deny Resource Creation-v9", "description": "This exemption allows specific users to create resources" } }
-
SadiqhAhmed-MSFT • 48,716 Reputation points • Microsoft Employee
2025-04-22T16:44:03.9+00:00 @Logan The sample you shared attempts to combine the identity-based resource selectors in the policy rule. However, the selectors belong in the exemption object, not in the policy definition.
So, you’ll first need to create the policy definition which blocks storage account creation, then assign it to the desired scope. Once that assignment is in place, then you’ll create an exemption for that assignment which uses selectors to specify allowed/disallowed user/object ID(s).
Also, in your selectors, it is not necessary to use both the “in” and “notIn” restrictions – this one is more restrictive and can be used by itself: "kind": "userPrincipalId", "in": ["1234-1234"]
Let me know if this makes sense.
-
Logan • 0 Reputation points
2025-04-22T17:03:48.1333333+00:00 @SadiqhAhmed-MSFT, I was confused with your multiple screenshots and that's why added everything. If i understood correctly, I'll have to create block all users E.g group1 and create exemption for specific users. But i don't see any exemption for user-based category.
Only below are the exemptions available
-
SadiqhAhmed-MSFT • 48,716 Reputation points • Microsoft Employee
2025-04-23T05:26:17.2866667+00:00 @Logan Yes this [
create block all users E.g group1 and create exemption for specific users
] is the correct understanding. In its current private preview state, identity-based exemptions through resource selectors are not supported in portal. Can you try creating the exemption through an API call? -
Logan • 0 Reputation points
2025-04-23T09:59:08.3+00:00 Hi @SadiqhAhmed-MSFT , Are you sure through API we can exempt because i was referring this article and don't see the relevant exemption
Can you please share the correct article.
-
SadiqhAhmed-MSFT • 48,716 Reputation points • Microsoft Employee
2025-04-24T16:38:54.13+00:00 @Logan This feature is not publicly documented yet because it is in private preview.
Since this capability is just an additional supported property (resourceSelectors) in the exemption JSON payload, all you have to do is adjust the request body for the create API call.
The screenshots I shared in the earlier post shows the JSON schema to use in the request body for the API call to create an identity-based exemption, and you can just use the existing URI (in the public document you linked) to send the create API request.
Sorry for the confusion here! Let me know if you have further questions.
-
Logan • 0 Reputation points
2025-04-25T08:05:40.48+00:00 SadiqhAhmed-MSFT, Will you be able to provide any example?
-
SadiqhAhmed-MSFT • 48,716 Reputation points • Microsoft Employee
2025-04-28T07:22:47.2866667+00:00 @Logan YES – you should be able to create the exemption using an API request URI & request body like this (be sure to first assign the policy, then insert real values for the placeholders shown):
Let me know if this works out for you.
-
Logan • 0 Reputation points
2025-04-29T17:19:39.0633333+00:00 This feature is exactly what I was looking for and it’s working as expected. Could you please let me know when it will be available for general use? Additionally, is there an RSS feed I can subscribe to so I can stay updated on its availability?
Just to give you a heads up, my company has a policy that restricts us from using any feature that is still in preview. So, I’d like to ensure we are compliant with this policy.
Sign in to comment