This post is a part of the "SC-500: Implementing End-to-End Security Controls for Cloud and AI Workloads" Exam Prep Hub.
This topic falls under these sections:
Manage identity, access, and governance (20–25%)
--> Implement governance to enforce security and regulatory compliance
--> Implement and configure security controls by using infrastructure as code
Note that there are 10 practice questions (with answers) at the end of each section to help you solidify your knowledge of the material. Also, there are 4 practice tests with 30 questions each available from the hub's main page below the exam topics section.
Overview
Infrastructure as code (IaC) is the practice of defining and deploying infrastructure through machine-readable configuration files rather than manually creating and configuring resources through a portal.
For the SC-500 exam, IaC is important because security controls should be:
- Consistent across environments
- Repeatable and auditable
- Enforced before deployment
- Version-controlled
- Reviewed through an approval process
- Resistant to configuration drift
- Integrated into the software development lifecycle
Common IaC technologies include:
- Azure Resource Manager templates
- Bicep
- Terraform
- Azure CLI and PowerShell scripts used within deployment automation
- CI/CD pipelines such as GitHub Actions or Azure Pipelines
The objective is not simply to automate infrastructure deployment. The objective is to ensure that security and compliance requirements are built into the deployment process.
Why Infrastructure as Code Improves Security
Manual configuration can create inconsistent environments. For example, an administrator might enable encryption on one storage account but forget to enable it on another. A virtual network might be deployed with private access in one environment but with unnecessary public exposure in another.
IaC helps reduce these problems by defining the expected configuration in code.
Major security benefits
| Benefit | Description |
|---|---|
| Consistency | Resources are deployed using the same approved configuration |
| Repeatability | The same secure configuration can be deployed multiple times |
| Version control | Changes can be tracked, reviewed, and reverted |
| Auditability | Organizations can identify who changed deployment code and when |
| Standardization | Security requirements can be applied across subscriptions and environments |
| Early detection | Misconfigurations can be identified before deployment |
| Reduced drift | Deployed resources can be compared with the approved configuration |
| Automation | Security checks can run automatically in CI/CD pipelines |
IaC does not automatically make an environment secure. Poorly written infrastructure code can reproduce insecure configurations at scale. Security must therefore be included in the design, validation, deployment, and monitoring processes.
Security Controls That Can Be Implemented Through IaC
IaC can define many Azure security settings, including:
Identity and access
- Azure role assignments
- Managed identities
- Resource scopes
- Role definitions
- Access policies where supported
- Privileged access configuration
- Group-based access patterns
Governance
- Azure Policy definitions
- Policy assignments
- Policy initiatives
- Resource locks
- Management group hierarchy
- Required tags
- Allowed regions
- Allowed resource types
- Naming standards
Network security
- Virtual networks and subnets
- Network security groups
- Azure Firewall rules
- Private endpoints
- Private DNS zones
- Route tables
- Public network access settings
- Network segmentation
Data protection
- Storage encryption settings
- Storage network restrictions
- Secure transfer requirements
- Key Vault configuration
- Key and secret access
- Azure SQL firewall rules
- Auditing settings
- Microsoft Defender plans
Compute security
- Virtual machine encryption
- Trusted launch settings
- Managed identities
- Just-in-time access configuration
- Diagnostic settings
- Container registry security
- App Service authentication and networking settings
Security Should Be Defined at Multiple Layers
A mature IaC security strategy generally uses several layers.
1. Source-code controls
Security begins in the infrastructure repository.
Examples include:
- Requiring pull requests
- Requiring peer review
- Protecting the main branch
- Scanning for secrets
- Scanning IaC files for insecure configurations
- Preventing direct production changes
- Maintaining approved modules
- Tracking changes through version control
2. Pre-deployment validation
Before infrastructure is deployed, the code should be checked for:
- Syntax errors
- Invalid resource properties
- Insecure defaults
- Excessive permissions
- Public network exposure
- Missing encryption
- Missing diagnostic settings
- Noncompliant locations or resource types
- Unapproved role assignments
Examples of tools and techniques include:
- Bicep validation and linting
- ARM template validation
- Terraform validation and planning
- Static analysis tools
- Policy-as-code checks
- Security scanning in CI/CD pipelines
3. Deployment-time controls
Azure Policy can evaluate resources during deployment and determine whether they comply with organizational requirements.
Depending on the policy effect, Azure Policy can:
- Audit noncompliant resources
- Deny noncompliant deployments
- Modify resource properties
- Deploy supporting configuration
- Append required properties
- Audit or deny public network access
- Require diagnostic settings
- Enforce approved resource locations
A secure deployment pipeline should use preventive controls where practical and auditing controls where immediate denial would disrupt legitimate deployment requirements.
4. Post-deployment monitoring
After deployment, organizations should continue checking for:
- Configuration drift
- Unauthorized changes
- Newly created resources
- Changes to role assignments
- Disabled security controls
- Public exposure
- Missing logs
- Noncompliant resources
Microsoft Defender for Cloud, Azure Policy compliance data, Azure Activity Logs, and Microsoft Sentinel can support this process.
Azure Policy and Infrastructure as Code
Azure Policy is a governance service used to enforce organizational standards and assess resource compliance.
IaC defines the desired infrastructure configuration, while Azure Policy provides an additional governance layer that can evaluate or enforce requirements across deployments.
Example
An organization requires all storage accounts to disable public blob access.
The organization can:
- Define the desired storage configuration in Bicep or Terraform.
- Add a validation check to the deployment pipeline.
- Assign an Azure Policy that audits or denies public blob access.
- Monitor compliance after deployment.
- Remediate existing noncompliant resources.
This layered approach is stronger than relying on IaC alone.
Common Azure Policy effects
| Effect | Purpose |
|---|---|
| Audit | Records noncompliance without blocking deployment |
| Deny | Blocks creation or update of noncompliant resources |
| Modify | Changes or adds resource properties during deployment |
| Append | Adds properties to a resource request |
| DeployIfNotExists | Deploys supporting resources or configuration when missing |
| AuditIfNotExists | Audits resources when a related configuration is missing |
| Disabled | Disables the policy |
A policy assignment can be scoped at a management group, subscription, resource group, or resource level. Policies assigned at a parent scope can affect child resources.
Policy as Code
Policy as code means representing governance and security requirements in a format that can be version-controlled, reviewed, tested, and deployed through automation.
Examples include:
- Azure Policy definitions stored in a repository
- Policy initiatives defined as code
- Terraform configurations for policy assignments
- Bicep modules that deploy policy definitions and assignments
- Automated compliance tests in a pipeline
Benefits of policy as code
- Policies can be reviewed like application code.
- Changes can be approved before deployment.
- Policy definitions can be reused across environments.
- Organizations can maintain consistent governance.
- Policy changes can be rolled back.
- Compliance requirements become visible and traceable.
Example workflow
- A security team creates a policy requiring private endpoints for selected PaaS services.
- The policy is stored in source control.
- A pull request is created.
- Automated checks validate the policy syntax and scope.
- Security and platform teams review the change.
- The policy is deployed through a pipeline.
- Compliance results are monitored.
- Exceptions are documented and approved.
Secure Bicep and ARM Deployments
Bicep is a declarative language used to define Azure resources. Bicep files are compiled into Azure Resource Manager templates.
Security practices for Bicep and ARM templates include:
Avoid hard-coded secrets
Do not place passwords, access keys, connection strings, or tokens directly in templates or parameter files.
Use services such as:
- Azure Key Vault
- Managed identities
- Secure pipeline variables
- Secret references supported by the deployment mechanism
Even when a secret is stored in a parameter file, the file may still be exposed through source control, build logs, or deployment artifacts.
Use secure parameters
Sensitive values should be handled as secure parameters where supported. However, secure parameters do not replace proper secret management.
Prefer managed identities
Managed identities reduce the need to store credentials in application configuration or deployment scripts.
For example, an application can use a managed identity to access Key Vault instead of storing a client secret in the application.
Use modules
Reusable Bicep modules can standardize secure configurations, such as:
- Storage accounts with public access disabled
- Private endpoints
- Diagnostic settings
- Required tags
- Approved network rules
- Managed identities
- Standardized role assignments
Limit role-assignment scope
Role assignments should be deployed at the narrowest scope required.
A deployment should not assign subscription-level Owner access when resource-group-level access is sufficient.
Use explicit resource properties
Security-sensitive settings should be explicitly defined rather than relying on uncertain defaults.
Examples include:
- Disabling public network access
- Requiring secure transfer
- Enabling diagnostic settings
- Enabling encryption
- Restricting network access
- Selecting approved SKUs and regions
Secure Terraform Deployments
Terraform can manage Azure infrastructure through the Azure provider.
Important security practices include:
- Store Terraform code in version control.
- Protect the Terraform state file.
- Use a secure remote backend.
- Restrict access to state files.
- Avoid storing secrets in state whenever possible.
- Use managed identities or workload identities for pipeline authentication.
- Review Terraform plans before applying changes.
- Use policy checks before deployment.
- Separate development and production state.
- Restrict who can execute production applies.
Terraform state security
Terraform state may contain sensitive information about deployed resources and, depending on the configuration, may contain secrets or sensitive values.
Therefore:
- Do not store state in a public location.
- Encrypt state at rest.
- Restrict access using Azure RBAC.
- Enable appropriate storage protections.
- Use locking to prevent conflicting changes.
- Avoid placing state files in source control.
Protecting the IaC code is not enough. The state file and pipeline credentials must also be protected.
Secure CI/CD Pipelines
A deployment pipeline should treat infrastructure code as production code.
Recommended controls
- Require approval for production deployments.
- Use separate deployment identities for different environments.
- Grant the pipeline only the permissions it needs.
- Use workload identity federation where supported.
- Avoid long-lived client secrets.
- Store secrets in an approved secret-management service.
- Scan templates and scripts before deployment.
- Require successful policy checks.
- Log deployment activity.
- Restrict who can modify pipeline definitions.
- Protect deployment branches.
- Use separate stages for validation, testing, approval, and deployment.
Pipeline identity permissions
The pipeline identity should not automatically receive Owner at the subscription level.
For example, if a pipeline only deploys resources in one resource group, its permissions should be limited to that resource group whenever possible.
If the pipeline must create role assignments, that capability should be granted deliberately because role-assignment permissions are highly privileged.
Role Assignments in Infrastructure as Code
A role assignment consists of:
- A security principal
- A role definition
- A scope
The principal may be:
- A user
- A security group
- A service principal
- A managed identity
- Another supported workload identity
When defining role assignments through IaC, consider:
- Whether the assignment is necessary
- Whether the role is too broad
- Whether the scope is too broad
- Whether a group should be used instead of an individual
- Whether the assignment should be temporary
- Whether the principal still exists
- Whether the assignment creates privilege escalation risk
Example of an insecure pattern
A deployment template assigns Owner at the subscription scope to an application service principal.
This creates a significant risk because the service principal may be able to:
- Modify resources
- Delete resources
- Create role assignments
- Grant access to other identities
- Escalate privileges
A safer design would use:
- A narrower built-in role
- A resource-group or resource scope
- A managed identity
- A custom role only if necessary
- Separate deployment and runtime identities
Preventing Excessive Permissions
IaC should be reviewed for permissions that can lead to privilege escalation.
Particular attention should be given to permissions such as:
- Creating or deleting role assignments
- Managing role definitions
- Assigning Owner or User Access Administrator
- Managing policy assignments
- Modifying Key Vault access
- Changing network access controls
- Disabling security monitoring
- Modifying diagnostic settings
- Deleting security resources
A custom role containing broad wildcard permissions may be more dangerous than a carefully selected built-in role.
Custom roles should be used only when built-in roles cannot satisfy the requirement. Their permissions should be narrowly defined and regularly reviewed.
Resource Locks and IaC
Resource locks can help protect critical resources from accidental deletion or modification.
Common lock types include:
- Read-only
- CanNotDelete
However, locks must be considered carefully in IaC workflows.
For example:
- A deployment may fail if it attempts to modify a resource protected by a read-only lock.
- A delete operation may fail because of a CanNotDelete lock.
- The identity managing locks must have appropriate permissions.
- Locks should not be treated as a replacement for RBAC, backups, or change control.
IaC can deploy and manage locks, but the deployment process should account for their effect on future updates.
Managing Exceptions
Security policies sometimes need exceptions for legitimate business requirements.
Exceptions should be:
- Explicitly documented
- Limited in scope
- Time-bound where possible
- Approved by the appropriate authority
- Associated with a business justification
- Monitored for continued necessity
Avoid broad exemptions at the subscription or management-group level when a resource-level exemption would be sufficient.
An exception should not become a permanent way to bypass security controls.
Handling Configuration Drift
Configuration drift occurs when deployed resources no longer match the approved IaC configuration.
Drift can occur when:
- An administrator changes a resource manually
- A script modifies a setting
- A security control is disabled
- A resource is updated outside the pipeline
- A policy assignment changes
- A role assignment is added directly through the portal
Drift-management process
- Detect the difference.
- Determine whether the change was authorized.
- Identify the responsible identity.
- Restore the approved configuration if necessary.
- Update the IaC code if the change is legitimate.
- Review whether additional controls are needed to prevent recurrence.
IaC should be treated as the authoritative definition of the desired state, but organizations should establish clear procedures for handling legitimate emergency changes.
Recommended Secure IaC Workflow
A secure end-to-end workflow can be organized as follows:
Step 1: Define security requirements
Identify requirements for:
- Identity
- Access
- Network exposure
- Encryption
- Logging
- Monitoring
- Compliance
- Data protection
- Resource ownership
Step 2: Create reusable secure modules
Build approved modules for common resource types and configurations.
Step 3: Store code in source control
Use protected repositories and require peer review.
Step 4: Validate the code
Run:
- Syntax validation
- Static analysis
- Secret scanning
- Policy checks
- Security configuration checks
Step 5: Generate and review the deployment plan
Review what the deployment will create, modify, or delete.
Step 6: Apply governance controls
Use Azure Policy and other preventive controls to block noncompliant deployments.
Step 7: Require approval for sensitive environments
Production deployments and privilege changes should require appropriate approval.
Step 8: Deploy using least privilege
Use a dedicated deployment identity with only the required permissions.
Step 9: Monitor compliance
Review policy compliance, activity logs, Defender for Cloud recommendations, and security alerts.
Step 10: Remediate drift
Investigate unauthorized changes and restore the approved configuration.
Common Exam Traps
Trap 1: IaC alone guarantees security
IaC can reproduce insecure settings. Security validation and governance are still required.
Trap 2: Azure Policy and IaC are identical
IaC defines desired infrastructure. Azure Policy evaluates or enforces governance requirements. They complement each other.
Trap 3: A pipeline identity should be Owner
The pipeline should receive only the permissions required for deployment. Owner is often unnecessarily broad.
Trap 4: Secure parameters eliminate secret-management risks
Secrets may still appear in state files, logs, artifacts, or source control. Use a dedicated secret-management solution.
Trap 5: A custom role is automatically safer
A custom role with wildcard permissions can be extremely broad. Least privilege depends on the actual permissions and scope.
Trap 6: Policy audit and policy deny have the same effect
Audit reports noncompliance. Deny blocks the deployment or update.
Trap 7: Resource locks replace RBAC
Locks protect against certain deletion or modification operations but do not determine who can access a resource.
Trap 8: A deployment at subscription scope is always appropriate
The deployment identity and role assignments should be scoped as narrowly as possible.
Trap 9: Terraform state is harmless
State may contain sensitive infrastructure details and secrets. It must be protected.
Trap 10: Manual emergency changes do not matter
Manual changes can create configuration drift and should be investigated, documented, and reconciled with IaC.
Practice Exam Questions
Question 1
A company uses Bicep to deploy storage accounts. Security requires that all storage accounts disable public network access. The company wants noncompliant deployments to be blocked automatically.
What should the company implement?
A. An Azure Activity Log alert
B. An Azure Policy with the Deny effect
C. A resource lock on each storage account
D. A Microsoft Sentinel workbook
Correct answer: B
Explanation: An Azure Policy with the Deny effect can block the creation or update of resources that do not meet the required configuration. Activity Log alerts and Sentinel workbooks provide monitoring, while resource locks do not enforce storage network settings.
Question 2
A Terraform deployment pipeline creates resources in a single resource group. The pipeline currently has Owner access at the subscription scope.
What is the best security improvement?
A. Grant the pipeline Global Administrator
B. Replace Terraform with manual deployments
C. Give the pipeline Contributor access at the subscription scope
D. Reduce the pipeline identity’s permissions and scope to what the deployment requires
Correct answer: D
Explanation: The pipeline should follow least privilege. If it only deploys resources in one resource group, its permissions should be limited to that resource group and should exclude unnecessary role-assignment or administrative permissions.
Question 3
An organization wants security policies to be reviewed, version-controlled, and deployed through a CI/CD pipeline.
Which approach best meets this requirement?
A. Store Azure Policy definitions in source control and deploy them as policy as code
B. Configure all policies manually in the Azure portal
C. Use resource locks instead of policies
D. Review policy compliance only once each year
Correct answer: A
Explanation: Policy as code allows policy definitions and assignments to be version-controlled, peer-reviewed, tested, and deployed consistently through automation.
Question 4
A developer places a database password directly in a Bicep parameter file stored in a private repository.
Why is this still a security concern?
A. The password may be exposed through source control, logs, or deployment artifacts
B. Parameter files cannot contain strings
C. Bicep cannot deploy database resources
D. Azure Policy automatically publishes parameter values
Correct answer: A
Explanation: A private repository does not eliminate the risk of secret exposure. Secrets may appear in source history, build logs, deployment outputs, artifacts, or copied files. Secrets should be stored and retrieved through an approved secret-management solution.
Question 5
A company wants to ensure that every production resource has diagnostic settings configured.
Which Azure Policy effect is most appropriate when the organization wants Azure to deploy the missing configuration automatically?
A. Audit
B. DeployIfNotExists
C. Disabled
D. Deny
Correct answer: B
Explanation: DeployIfNotExists can deploy supporting configuration when the required related resource or setting is missing. Audit only reports noncompliance, while Deny blocks noncompliant deployments.
Question 6
A Terraform state file is stored in a publicly accessible storage container.
What should the security team do first?
A. Delete all Terraform configuration files
B. Grant all administrators access to the container
C. Move the state to a protected backend and restrict access
D. Add a resource lock to the storage account only
Correct answer: C
Explanation: Terraform state can contain sensitive infrastructure information and potentially secret values. It should be stored in a secured backend with encryption, access controls, and appropriate protection against unauthorized access.
Question 7
A Bicep template assigns the Owner role at the subscription scope to a service principal used by an application at runtime.
What is the best remediation?
A. Replace the service principal with a user account
B. Assign the Owner role at the management-group scope
C. Disable Azure RBAC
D. Use a managed identity and grant only the required role at the narrowest scope
Correct answer: D
Explanation: Runtime applications should not normally receive Owner access. A managed identity and a narrowly scoped role reduce credential-management risk and limit the impact of compromise.
Question 8
A policy requiring private endpoints is stored in a repository. A developer submits a change that changes the policy effect from Deny to Audit without approval.
Which control would best prevent this change from being deployed?
A. A protected branch and required pull-request approval
B. A read-only resource lock
C. A storage firewall rule
D. A virtual network peering connection
Correct answer: A
Explanation: Source-control protections and required reviews can prevent unauthorized changes to policy code before it reaches the deployment pipeline. Resource locks and network controls do not govern repository changes.
Question 9
An administrator manually disables encryption on a resource that was originally deployed through IaC.
What is this situation called, and what should the organization do?
A. Privilege activation; permanently assign the administrator Owner
B. Configuration drift; investigate and restore the approved configuration
C. Policy inheritance; remove the management group
D. Deployment compilation; rebuild the Bicep compiler
Correct answer: B
Explanation: Configuration drift occurs when the deployed environment no longer matches the approved IaC configuration. The organization should investigate the change, determine whether it was authorized, and restore or update the desired configuration appropriately.
Question 10
An organization wants to allow a deployment pipeline to create resources and assign a specific role to a managed identity, but it does not want the pipeline to have unrestricted access to all role assignments.
What is the best approach?
A. Grant the pipeline subscription-level Owner access
B. Grant the pipeline Global Administrator
C. Use narrowly scoped role-assignment permissions and conditions where supported
D. Allow the pipeline to modify all custom role definitions
Correct answer: C
Explanation: Role-assignment management is highly privileged. The organization should limit the pipeline’s scope and permissions and use supported conditions to constrain which roles, principals, or actions it can manage.
Final Takeaways
For the SC-500 exam, remember these principles:
- Define security requirements in infrastructure code.
- Validate IaC before deployment.
- Use Azure Policy as an additional governance layer.
- Prefer Deny for requirements that must block noncompliant deployments.
- Use DeployIfNotExists when missing supporting configuration should be deployed automatically.
- Protect secrets, pipeline credentials, and Terraform state.
- Use managed identities and workload identities instead of long-lived secrets.
- Scope deployment permissions narrowly.
- Review role assignments carefully, especially Owner and role-assignment management permissions.
- Use source control, peer review, and protected deployment pipelines.
- Monitor for configuration drift after deployment.
- Treat IaC as a repeatable security-control mechanism, not as a substitute for monitoring and governance.
Go to the SC-500 Exam Prep Hub main page

