AWS Organization Policy and Azure Policy

Cloud Journey
8 min readJul 18, 2021

--

Overview

In the past, when we talk about Azure policy, we typically say it’s Azure unique feature, however it does not necessarily mean AWS can not do preventative control to enforce guardrails.

AWS Organizations provide central governance and management across AWS accounts. AWS Organization has two type of policy, SCP and management policy.

you can use SCPs (Service Control Policy) to set permission guardrails with the fine-grained control supported in the AWS Identity and Access Management (IAM) policy language.

We will explore couple of sample policies, compare between Azure and AWS. The goal is to learn AWS feature if you are familiar with Azure and vice versa.

Example Policies

Lock Down Region

AWS SCP sample policy, only allow eu-central-1 and eu-west-1. It provides exemptions for operations in approved global services. This example also shows how to exempt requests made by either of two specified administrator roles.

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAllOutsideEU",
"Effect": "Deny",
"NotAction": [
"a4b:*",
"acm:*",
"aws-marketplace-management:*",
"aws-marketplace:*",
"aws-portal:*",
"budgets:*",
"ce:*",
"chime:*",
"cloudfront:*",
"config:*",
"cur:*",
"directconnect:*",
"ec2:DescribeRegions",
"ec2:DescribeTransitGateways",
"ec2:DescribeVpnGateways",
"fms:*",
"globalaccelerator:*",
"health:*",
"iam:*",
"importexport:*",
"kms:*",
"mobileanalytics:*",
"networkmanager:*",
"organizations:*",
"pricing:*",
"route53:*",
"route53domains:*",
"s3:GetAccountPublic*",
"s3:ListAllMyBuckets",
"s3:PutAccountPublic*",
"shield:*",
"sts:*",
"support:*",
"trustedadvisor:*",
"waf-regional:*",
"waf:*",
"wafv2:*",
"wellarchitected:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": [
"eu-central-1",
"eu-west-1"
]
},
"ArnNotLike": {
"aws:PrincipalARN": [
"arn:aws:iam::*:role/Role1AllowedToBypassThisSCP",
"arn:aws:iam::*:role/Role2AllowedToBypassThisSCP"
]
}
}
}
]
}

Azure allowed location built in policy.

{
"properties": {
"displayName": "Allowed locations",
"policyType": "BuiltIn",
"mode": "Indexed",
"description": "This policy enables you to restrict the locations your organization can specify when deploying resources. Use to enforce your geo-compliance requirements. Excludes resource groups, Microsoft.AzureActiveDirectory/b2cDirectories, and resources that use the 'global' region.",
"metadata": {
"version": "1.0.0",
"category": "General"
},
"parameters": {
"listOfAllowedLocations": {
"type": "Array",
"metadata": {
"description": "The list of locations that can be specified when deploying resources.",
"strongType": "location",
"displayName": "Allowed locations"
}
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "location",
"notIn": "[parameters('listOfAllowedLocations')]"
},
{
"field": "location",
"notEquals": "global"
},
{
"field": "type",
"notEquals": "Microsoft.AzureActiveDirectory/b2cDirectories"
}
]
},
"then": {
"effect": "deny"
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "e56962a6-4747-49cd-b67b-bf8b01975c4c"
}

List Azure available locations.

PS C:\Users\rquan> (Get-AzLocation).Location
eastasia
southeastasia
centralus
eastus
eastus2
westus
northcentralus
southcentralus
northeurope
westeurope
japanwest
japaneast
brazilsouth
australiaeast
australiasoutheast
southindia
centralindia
westindia
canadacentral
canadaeast
uksouth
ukwest
westcentralus
westus2
......

Specific VM Type

With this SCP, any instance launches not using the t2.micro instance type are denied.

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RequireMicroInstanceType",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*:*:instance/*"
],
"Condition": {
"StringNotEquals": {
"ec2:InstanceType": "t2.micro"
}
}
}
]
}

Azure — allow specific SKU virtual machine.

{
"properties": {
"displayName": "Allowed virtual machine size SKUs",
"policyType": "BuiltIn",
"mode": "Indexed",
"description": "This policy enables you to specify a set of virtual machine size SKUs that your organization can deploy.",
"metadata": {
"version": "1.0.1",
"category": "Compute"
},
"parameters": {
"listOfAllowedSKUs": {
"type": "Array",
"metadata": {
"description": "The list of size SKUs that can be specified for virtual machines.",
"displayName": "Allowed Size SKUs",
"strongType": "VMSKUs"
}
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Compute/virtualMachines"
},
{
"not": {
"field": "Microsoft.Compute/virtualMachines/sku.name",
"in": "[parameters('listOfAllowedSKUs')]"
}
}
]
},
"then": {
"effect": "Deny"
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/cccc23c7-8427-4f53-ad12-b6a63eb452b3",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "cccc23c7-8427-4f53-ad12-b6a63eb452b3"
}

Azure get list of available VMs for a region.

Prevent public S3 access

Here is the example SCP that prevents employees from changing S3 public access setting. The actual deny public access is configured through block public access settings for access point, bucket or account.

{
"Sid": "PreventS3PublicAccess",
"Action": [
"s3:PutAccountPublicAccessBlock"
],
"Resource": "*",
"Effect": "Deny"
}

Azure - built-in policy to disallow anonymous access.

{
"properties": {
"displayName": "[Preview]: Storage account public access should be disallowed",
"policyType": "BuiltIn",
"mode": "Indexed",
"description": "Anonymous public read access to containers and blobs in Azure Storage is a convenient way to share data but might present security risks. To prevent data breaches caused by undesired anonymous access, Microsoft recommends preventing public access to a storage account unless your scenario requires it.",
"metadata": {
"version": "2.0.1-preview",
"category": "Storage",
"preview": true
},
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "The effect determines what happens when the policy rule is evaluated to match"
},
"allowedValues": [
"audit",
"deny",
"disabled"
],
"defaultValue": "audit"
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
},
{
"field": "id",
"notContains": "/resourceGroups/databricks-rg-"
},
{
"not": {
"field": "Microsoft.Storage/storageAccounts/allowBlobPublicAccess",
"equals": "false"
}
}
]
},
"then": {
"effect": "[parameters('effect')]"
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/4fa4b6c0-31ca-4c0d-b10d-24b96f62a751",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "4fa4b6c0-31ca-4c0d-b10d-24b96f62a751"
}

Azure - policy to disallow access from all network.

{
"properties": {
"displayName": "Storage accounts should restrict network access",
"policyType": "BuiltIn",
"mode": "Indexed",
"description": "Network access to storage accounts should be restricted. Configure network rules so only applications from allowed networks can access the storage account. To allow connections from specific internet or on-premises clients, access can be granted to traffic from specific Azure virtual networks or to public internet IP address ranges",
"metadata": {
"version": "1.1.1",
"category": "Storage"
},
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "The effect determines what happens when the policy rule is evaluated to match"
},
"allowedValues": [
"Audit",
"Deny",
"Disabled"
],
"defaultValue": "Audit"
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
},
{
"field": "Microsoft.Storage/storageAccounts/networkAcls.defaultAction",
"notEquals": "Deny"
}
]
},
"then": {
"effect": "[parameters('effect')]"
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/34c877ad-507e-4c82-993e-3452a6e0ad3c",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "34c877ad-507e-4c82-993e-3452a6e0ad3c"
}

ARM parameter values:

"networkAclsBypass": {
"value": "AzureServices"
},
"networkAclsDefaultAction": {
"value": "Allow"
},

Tag Policy

AWS organization tag policy, deny when missing required tag for a specific service.

{
"tags": {
"costcenter": {
"tag_key": {
"@@assign": "CostCenter"
},
"tag_value": {
"@@assign": [
"100",
"200"
]
},
"enforced_for": {
"@@assign": [
"secretsmanager:*"
]
}
}
}
}

AWS organization SCP for resource tagging, prevents IAM users and roles in the affected accounts from creating certain resource types if the request doesn’t include the specified tags.

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyCreateSecretWithNoProjectTag",
"Effect": "Deny",
"Action": "secretsmanager:CreateSecret",
"Resource": "*",
"Condition": {
"Null": {
"aws:RequestTag/Project": "true"
}
}
},
{
"Sid": "DenyRunInstanceWithNoProjectTag",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*:*:volume/*"
],
"Condition": {
"Null": {
"aws:RequestTag/Project": "true"
}
}
},
{
"Sid": "DenyCreateSecretWithNoCostCenterTag",
"Effect": "Deny",
"Action": "secretsmanager:CreateSecret",
"Resource": "*",
"Condition": {
"Null": {
"aws:RequestTag/CostCenter": "true"
}
}
},
{
"Sid": "DenyRunInstanceWithNoCostCenterTag",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*:*:volume/*"
],
"Condition": {
"Null": {
"aws:RequestTag/CostCenter": "true"
}
}
}
]
}

Azure — policy to deny when missing required tag.

{
"properties": {
"displayName": "Require a tag on resources",
"policyType": "BuiltIn",
"mode": "Indexed",
"description": "Enforces existence of a tag. Does not apply to resource groups.",
"metadata": {
"version": "1.0.1",
"category": "Tags"
},
"parameters": {
"tagName": {
"type": "String",
"metadata": {
"displayName": "Tag Name",
"description": "Name of the tag, such as 'environment'"
}
}
},
"policyRule": {
"if": {
"field": "[concat('tags[', parameters('tagName'), ']')]",
"exists": "false"
},
"then": {
"effect": "deny"
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/871b6d14-10aa-478d-b590-94f262ecfa99",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "871b6d14-10aa-478d-b590-94f262ecfa99"
}

Allow Certain Services

AWS SCP policy:

{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"dynamodb:*","rds:*","ec2:*","s3:*","elasticmapreduce:*",
"glacier:*","elasticloadbalancing:*", "cloudwatch:*",
"importexport:*", "cloudformation:*", "redshift:*",
"iam:*", "health:*", "config:*", "snowball:*",
"trustedadvisor:*", "kms:*", "apigateway:*",
"autoscaling:*", "directconnect:*",
"execute-api:*", "sts:*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}

Azure built-in policy under general category.

{
"properties": {
"displayName": "Not allowed resource types",
"policyType": "BuiltIn",
"mode": "All",
"description": "Restrict which resource types can be deployed in your environment. Limiting resource types can reduce the complexity and attack surface of your environment while also helping to manage costs. Compliance results are only shown for non-compliant resources.",
"metadata": {
"version": "2.0.0",
"category": "General"
},
"parameters": {
"listOfResourceTypesNotAllowed": {
"type": "Array",
"metadata": {
"description": "The list of resource types that cannot be deployed.",
"displayName": "Not allowed resource types",
"strongType": "resourceTypes"
}
},
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "Enable or disable the execution of the policy"
},
"allowedValues": [
"Audit",
"Deny",
"Disabled"
],
"defaultValue": "Deny"
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"in": "[parameters('listOfResourceTypesNotAllowed')]"
},
{
"value": "[field('type')]",
"exists": true
}
]
},
"then": {
"effect": "[parameters('effect')]"
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/6c112d4e-5bc7-47ae-a041-ea2d9dccd749",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "6c112d4e-5bc7-47ae-a041-ea2d9dccd749"
}

Conclusion

Azure policy aims to enforce organizational standards and to asses compliance at scale. It’s NOT coupled with Azure RBAC or access control, Azure Policy evaluates resources in Azure by comparing the properties of those resources to business rules.

Azure policy uses consistent policy syntax to enforce guardrails across all resources.

Azure policy support multiple effects to respond a non-compliant resource. It can do preventative control via deny effect, it can do detective control via audit effect, it can remediate via append, modify and deploy effects.

  • Deny the resource change (Deny)
  • Log the change to the resource (Audit, AuditIfNotExists)
  • Alter the resource before the change (Append, Modify)
  • Deploy related compliant resources (DeployIfNotExists)

References

Overview of Azure Policy — Azure Policy | Microsoft Docs

Managing AWS Organizations policies — AWS Organizations (amazon.com)

How to use service control policies to set permission guardrails across accounts in your AWS Organization | AWS Security Blog (amazon.com)

How to Use Service Control Policies in AWS Organizations to Enforce Healthcare Compliance in Your AWS Account | AWS Security Blog (amazon.com)

Understand how effects work — Azure Policy | Microsoft Docs

Configuring block public access settings for your account — Amazon Simple Storage Service

Managing Amazon S3 access with VPC endpoints and S3 Access Points | AWS Storage Blog

New — Use Tag Policies to Manage Tags Across Multiple AWS Accounts | AWS News Blog (amazon.com)

Resource providers and resource types — Azure Resource Manager | Microsoft Docs

https://docs.microsoft.com/en-us/azure/governance/policy/how-to/author-policies-for-arrays#pass-values-to-a-parameter-array-during-assignment

--

--

Cloud Journey

All blogs are strictly personal and do not reflect the views of my employer. https://github.com/Ronnie-personal