Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ Inspect the following files for instructions to test PSRule for Azure rules by c
- [deployments/contoso/landing-zones/subscription-1/rg-app-001/dev.bicepparam](deployments/contoso/landing-zones/subscription-1/rg-app-001/dev.bicepparam)
- [deployments/contoso/landing-zones/subscription-1/rg-app-002/deploy.bicep](deployments/contoso/landing-zones/subscription-1/rg-app-002/deploy.bicep)

For examples of how to reference resources that require secrets to be passed in, see:

- [deployments/contoso/landing-zones/subscription-1/rg-vm-001/deploy.bicep](deployments/contoso/landing-zones/subscription-1/rg-vm-001/deploy.bicep)

## Support

This project uses GitHub Issues to track bugs and feature requests.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// Note:
// This Azure Bicep code demonstrates a deployment of a VM that uses a password with two common
// deployment options. 1. Using a password from the pipeline. 2. Using a password from a Key Vault secret.

// ---------------------------------------------------------------
// OPTION 1: A VM deployment using the password from the pipeline.
// ---------------------------------------------------------------

// If your pipeline passes a password in as a parameter to the deployment script, use this option.
// For expansion with PSRule, a dummy value for `adminPassword` is used set in `ps-rule.yaml` with
// the `AZURE_PARAMETER_DEFAULTS` configuration option. This allows PSRule to expand the deployment,
// without exposing your secret in the code or PSRule.

@secure()
@description('Load the admin password from the pipeline.')
param adminPassword string

@description('A VM deployment using a password from the pipeline.')
module vm001 '../../../../../modules/virtual-machine-windows/v1/main.bicep' = {
params: {
name: 'vm-001'
adminPassword: adminPassword
adminUsername: 'vm-admin'
imageSKU: '2022-Datacenter'
size: 'Standard_D4ds_v4'
subnetId: vnet.id
tags: {
env: 'dev'
}
}
}

// ---------------------------------------------------------------------
// OPTION 2: A VM deployment using the password from a Key Vault secret.
// ---------------------------------------------------------------------

// If your VM deployment is able to use a Key Vault secret that is already deployed to Azure, use this option.
// When you reference a Key Vault secret, PSRule will automatically substitute a placeholder for the secret value
// during expansion. So you can use the secret in your deployment without exposing it as a deployment parameter.

// NB: PSRule never actually attempts to retrieve the secret value, so it does not need access to the secret.

@description('An existing Key Vault to use for the VM deployment.')
resource vault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
name: 'kv-001'
}

@description('Load the admin password from a Key Vault secret.')
module vm002 '../../../../../modules/virtual-machine-windows/v1/main.bicep' = {
params: {
name: 'vm-002'
adminPassword: vault.getSecret('vm002-admin-password')
adminUsername: 'vm-admin'
imageSKU: '2022-Datacenter'
size: 'Standard_D4ds_v4'
subnetId: vnet.id
tags: {
env: 'dev'
}
}
}

// ---------------
// Other resources
// ---------------

// An existing virtual network and subnet to connect the VM.
resource vnet 'Microsoft.Network/virtualNetworks/subnets@2023-05-01' existing = {
name: 'vnet-001/subnet-001'
}
71 changes: 71 additions & 0 deletions modules/virtual-machine-windows/v1/.bicep/rbac.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// Configure role assignments for the Virtual Machine

// ----------
// PARAMETERS
// ----------

@sys.description('The display name of the role to assign or the GUID.')
param role string

@sys.description('The GUID of the identity object to assign.')
param principalId string

@sys.description('A description of the assignment.')
param description string = ''

@allowed([
'ServicePrincipal'
'Group'
'User'
'ForeignGroup'
'Device'
])
@sys.description('The principal type to assign.')
param principalType string = 'ServicePrincipal'

@sys.description('The name of the Virtual Machine name.')
param resource string

// ---------
// VARIABLES
// ---------

var roles = {
Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Thoughts: Can we add any documentation which contains these relationships and GUID relevance please.

Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
'User Access Administrator': subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'18d7d88d-d35e-4fb5-a5c3-7773c20a72d9'
)
'Virtual Machine Contributor': subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'9980e02c-c2be-4d73-94e8-173b1dc7cf3c'
)
}
var roleDefinitionId = contains(roles, role)
? roles[role]
: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', role)

// ---------
// RESOURCES
// ---------

resource vm 'Microsoft.Compute/virtualMachines@2023-03-01' existing = {
name: resource
}

@sys.description('Assign permissions to an Azure AD principal.')
resource rbac 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(vm.id, principalId, roleDefinitionId)
scope: vm
properties: {
principalId: principalId
roleDefinitionId: roleDefinitionId
principalType: principalType
description: description
}
}
Loading
Loading