Skip to content

Commit

Permalink
feat: Added user defined type for Key Vault Access Policies (#622)
Browse files Browse the repository at this point in the history
## Description

This pull request introduces the type `accessPoliciesType` so the author
experience is enhanced when using this parameter to set access policies.
I have added the `accessPoliciesType` to `key-vault/vault/main.bicep`
and `key-vault/vault/access-policy`.

Besides the addition of the type I have removed
`formattedAccessPolicies` because the user-defined type has taken over
the task to enforce required properties. This makes it simpler for the
user to read and use the key vault main.bicep.

I have tested the modules by deploying to my Azure environment:

1. **With** access policies configured in bicepparam:

```bicepparam
using './main.bicep'

param name = 'br-kv-john-test-no-ap'
param enableRbacAuthorization = false
param accessPolicies = [
  {
    objectId: '<object-id-here>'
    permissions: {
      certificates: [
        'all'
      ]
      keys: [
        'all'
      ]
      secrets: [
        'all'
      ]
      storage: [
        'all'
      ]
    }
    tenantId: '<tenant-id-here>'
  }
]
```

**Succesful deployment**
<img width="1772" alt="image"
src="https://github.com/Azure/bicep-registry-modules/assets/3514513/ec7d782c-3310-42b7-bb77-f99dac993d90">

2. **Without** access policies configured in bicepparam to showcase it
is optional:

```bicepparam
using './main.bicep'

param name = 'br-kv-john-test-no-ap'
```

**Succesful deployment**
<img width="1447" alt="image"
src="https://github.com/Azure/bicep-registry-modules/assets/3514513/d1a605e2-bf8d-4d2a-9da6-aa532be71ce1">

## Updating an existing module

- [ ] I have run `brm validate` locally to verify the module files.
- [x] I have run deployment tests locally to ensure the module is
deployable.
- [x] I have read the [Updating an existing
module](https://github.com/Azure/bicep-registry-modules/blob/main/CONTRIBUTING.md#updating-an-existing-module)
section in the contributing guide and updated the `version.json` file
properly:
- [ ] The PR contains backwards compatible bug fixes, and I have NOT
bumped the MAJOR or MINOR version in `version.json`.
- [x] The PR contains backwards compatible feature updates, and I have
bumped the MINOR version in `version.json`.
- [ ] The PR contains breaking changes, and I have bumped the MAJOR
version in `version.json`.
- [ ] I have updated the examples in README with the latest module
version number.
  • Loading branch information
johnlokerse authored Nov 16, 2023
1 parent 68f7e41 commit 0e61a5c
Show file tree
Hide file tree
Showing 10 changed files with 640 additions and 45 deletions.
9 changes: 4 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,19 +310,18 @@ The `brm validate` command mentioned in the above step does not deploy the `test

Once the module files are validated locally, you can commit your changes and open a pull request. You must link the new module proposal in the pull request description if you are trying to add a new module. Adding or updating multiple modules is not supported and will cause a failure in the pull request validation CI, so please only add or change one module at a time.

## Prefix the PR TItle based on the type of change.
## Prefix the pull request title based on the type of change

The modules in the repository follow Semantic Versioning.
A GitHub action checks that PRs include a prefix. This acts as a stepping stone to automating the version incrementing, this action requires each PR have a semantic prefix.
The modules in the repository follow Semantic Versioning. A GitHub action checks that pull requests include a prefix. This acts as a stepping stone to automating the version incrementing, this GitHub action requires each pull request to have a semantic prefix.

Example PR Tiles:
Example pull request titles:

- Creating a new module: `feat(new): Storage Account Module`
- Add a bug fix to existing module: `fix: Storage Account does not properly format output`
- Add a feature to existing module `feat: Add input parameter to deploy storage into vnet`
- Add a breaking change to a module due to refactoring: `refactor!: Use custom types in storage account`

More details can be found [here] about each prefix(https://www.conventionalcommits.org/en/v1.0.0/).
More details on prefixes can be found [here](https://www.conventionalcommits.org/en/v1.0.0/).

Recommend prefixes include:

Expand Down
73 changes: 73 additions & 0 deletions avm/res/key-vault/vault/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,79 @@ All access policies to create.
- Required: No
- Type: array


| Name | Required | Type | Description |
| :-- | :-- | :--| :-- |
| [`applicationId`](#parameter-accesspoliciesapplicationid) | No | string | Optional. Application ID of the client making request on behalf of a principal. |
| [`objectId`](#parameter-accesspoliciesobjectid) | Yes | string | Required. The object ID of a user, service principal or security group in the tenant for the vault. |
| [`permissions`](#parameter-accesspoliciespermissions) | Yes | object | |
| [`tenantId`](#parameter-accesspoliciestenantid) | No | string | Optional. The tenant ID that is used for authenticating requests to the key vault. |

### Parameter: `accessPolicies.applicationId`

Optional. Application ID of the client making request on behalf of a principal.

- Required: No
- Type: string

### Parameter: `accessPolicies.objectId`

Required. The object ID of a user, service principal or security group in the tenant for the vault.

- Required: Yes
- Type: string

### Parameter: `accessPolicies.permissions`
- Required: Yes
- Type: object

| Name | Required | Type | Description |
| :-- | :-- | :--| :-- |
| [`certificates`](#parameter-accesspoliciespermissionscertificates) | No | array | Optional. Permissions to certificates. |
| [`keys`](#parameter-accesspoliciespermissionskeys) | No | array | Optional. Permissions to keys. |
| [`secrets`](#parameter-accesspoliciespermissionssecrets) | No | array | Optional. Permissions to secrets. |
| [`storage`](#parameter-accesspoliciespermissionsstorage) | No | array | Optional. Permissions to storage accounts. |

### Parameter: `accessPolicies.permissions.certificates`

Optional. Permissions to certificates.

- Required: No
- Type: array
- Allowed: `[all, backup, create, delete, deleteissuers, get, getissuers, import, list, listissuers, managecontacts, manageissuers, purge, recover, restore, setissuers, update]`

### Parameter: `accessPolicies.permissions.keys`

Optional. Permissions to keys.

- Required: No
- Type: array
- Allowed: `[all, backup, create, decrypt, delete, encrypt, get, getrotationpolicy, import, list, purge, recover, release, restore, rotate, setrotationpolicy, sign, unwrapKey, update, verify, wrapKey]`

### Parameter: `accessPolicies.permissions.secrets`

Optional. Permissions to secrets.

- Required: No
- Type: array
- Allowed: `[all, backup, delete, get, list, purge, recover, restore, set]`

### Parameter: `accessPolicies.permissions.storage`

Optional. Permissions to storage accounts.

- Required: No
- Type: array
- Allowed: `[all, backup, delete, deletesas, get, getsas, list, listsas, purge, recover, regeneratekey, restore, set, setsas, update]`


### Parameter: `accessPolicies.tenantId`

Optional. The tenant ID that is used for authenticating requests to the key vault.

- Required: No
- Type: string

### Parameter: `createMode`

The vault's create mode to indicate whether the vault need to be recovered or not. - recover or default.
Expand Down
73 changes: 73 additions & 0 deletions avm/res/key-vault/vault/access-policy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,79 @@ An array of 0 to 16 identities that have access to the key vault. All identities
- Required: No
- Type: array


| Name | Required | Type | Description |
| :-- | :-- | :--| :-- |
| [`applicationId`](#parameter-accesspoliciesapplicationid) | No | string | Optional. Application ID of the client making request on behalf of a principal. |
| [`objectId`](#parameter-accesspoliciesobjectid) | Yes | string | Required. The object ID of a user, service principal or security group in the tenant for the vault. |
| [`permissions`](#parameter-accesspoliciespermissions) | Yes | object | |
| [`tenantId`](#parameter-accesspoliciestenantid) | No | string | Optional. The tenant ID that is used for authenticating requests to the key vault. |

### Parameter: `accessPolicies.applicationId`

Optional. Application ID of the client making request on behalf of a principal.

- Required: No
- Type: string

### Parameter: `accessPolicies.objectId`

Required. The object ID of a user, service principal or security group in the tenant for the vault.

- Required: Yes
- Type: string

### Parameter: `accessPolicies.permissions`
- Required: Yes
- Type: object

| Name | Required | Type | Description |
| :-- | :-- | :--| :-- |
| [`certificates`](#parameter-accesspoliciespermissionscertificates) | No | array | Optional. Permissions to certificates. |
| [`keys`](#parameter-accesspoliciespermissionskeys) | No | array | Optional. Permissions to keys. |
| [`secrets`](#parameter-accesspoliciespermissionssecrets) | No | array | Optional. Permissions to secrets. |
| [`storage`](#parameter-accesspoliciespermissionsstorage) | No | array | Optional. Permissions to storage accounts. |

### Parameter: `accessPolicies.permissions.certificates`

Optional. Permissions to certificates.

- Required: No
- Type: array
- Allowed: `[all, backup, create, delete, deleteissuers, get, getissuers, import, list, listissuers, managecontacts, manageissuers, purge, recover, restore, setissuers, update]`

### Parameter: `accessPolicies.permissions.keys`

Optional. Permissions to keys.

- Required: No
- Type: array
- Allowed: `[all, backup, create, decrypt, delete, encrypt, get, getrotationpolicy, import, list, purge, recover, release, restore, rotate, setrotationpolicy, sign, unwrapKey, update, verify, wrapKey]`

### Parameter: `accessPolicies.permissions.secrets`

Optional. Permissions to secrets.

- Required: No
- Type: array
- Allowed: `[all, backup, delete, get, list, purge, recover, restore, set]`

### Parameter: `accessPolicies.permissions.storage`

Optional. Permissions to storage accounts.

- Required: No
- Type: array
- Allowed: `[all, backup, delete, deletesas, get, getsas, list, listsas, purge, recover, regeneratekey, restore, set, setsas, update]`


### Parameter: `accessPolicies.tenantId`

Optional. The tenant ID that is used for authenticating requests to the key vault.

- Required: No
- Type: string

### Parameter: `keyVaultName`

The name of the parent key vault. Required if the template is used in a standalone deployment.
Expand Down
36 changes: 32 additions & 4 deletions avm/res/key-vault/vault/access-policy/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ metadata owner = 'Azure/module-maintainers'
param keyVaultName string

@description('Optional. An array of 0 to 16 identities that have access to the key vault. All identities in the array must use the same tenant ID as the key vault\'s tenant ID.')
param accessPolicies array?
param accessPolicies accessPoliciesType

var formattedAccessPolicies = [for accessPolicy in (accessPolicies ?? []): {
applicationId: contains(accessPolicy, 'applicationId') ? accessPolicy.applicationId : ''
objectId: contains(accessPolicy, 'objectId') ? accessPolicy.objectId : ''
applicationId: accessPolicy.?applicationId ?? ''
objectId: accessPolicy.objectId
permissions: accessPolicy.permissions
tenantId: contains(accessPolicy, 'tenantId') ? accessPolicy.tenantId : tenant().tenantId
tenantId: accessPolicy.?tenantId ?? tenant().tenantId
}]

resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
Expand All @@ -35,3 +35,31 @@ output name string = policies.name

@description('The resource ID of the access policies assignment.')
output resourceId string = policies.id

// ================ //
// Definitions //
// ================ //
type accessPoliciesType = {
@description('Optional. The tenant ID that is used for authenticating requests to the key vault.')
tenantId: string?

@description('Required. The object ID of a user, service principal or security group in the tenant for the vault.')
objectId: string

@description('Optional. Application ID of the client making request on behalf of a principal.')
applicationId: string?

permissions: {
@description('Optional. Permissions to keys.')
keys: ('all' | 'backup' | 'create' | 'decrypt' | 'delete' | 'encrypt' | 'get' | 'getrotationpolicy' | 'import' | 'list' | 'purge' | 'recover' | 'release' | 'restore' | 'rotate' | 'setrotationpolicy' | 'sign' | 'unwrapKey' | 'update' | 'verify' | 'wrapKey')[]?

@description('Optional. Permissions to secrets.')
secrets: ('all' | 'backup' | 'delete' | 'get' | 'list' | 'purge' | 'recover' | 'restore' | 'set')[]?

@description('Optional. Permissions to certificates.')
certificates: ('all' | 'backup' | 'create' | 'delete' | 'deleteissuers' | 'get' | 'getissuers' | 'import' | 'list' | 'listissuers' | 'managecontacts' | 'manageissuers' | 'purge' | 'recover' | 'restore' | 'setissuers' | 'update')[]?

@description('Optional. Permissions to storage accounts.')
storage: ('all' | 'backup' | 'delete' | 'deletesas' | 'get' | 'getsas' | 'list' | 'listsas' | 'purge' | 'recover' | 'regeneratekey' | 'restore' | 'set' | 'setsas' | 'update')[]?
}
}[]?
Loading

0 comments on commit 0e61a5c

Please sign in to comment.