This is a terraform module for creating an azure key vault resource
module "key_vault" {
source = "git@github.com:hmcts/cnp-module-key-vault?ref=master"
name = "rhubarb-fe-${var.env}" // Max 24 characters
product = var.product
env = var.env
object_id = var.jenkins_AAD_objectId
resource_group_name = azurerm_resource_group.rg.name
product_group_name = "Your AAD group" # e.g. MI Data Platform, or dcd_cmc
common_tags = var.common_tags
}
The module creates the following permissions:
- Jenkins access to Keyvault
- Managed Identity ($product)-$env-mi
- Product team/developers access
All developers have access to read non production secrets if they are a member of the DTS CFT Developers
Azure AD group
Reading of production secrets is discouraged, in general you should overwrite the secret rather than trying to read it.
If you really really need that secret then ask the Platform Operations team to get it for you.
Reading a secret via Azure CLI:
$ az keyvault secret show --vault-name $VAULT --name $SECRET
The product group for the key vault have permissions to update / write / list / delete secrets in all environments
This should be your teams AD group, it's controlled by the product_group_object_id
variable
You should always write secrets via the command line, as you normally don't have read access on the production vault, but you can still write the secrets via CLI.
$ az keyvault secret set --vault-name $VAULT_NAME --name "${SECRET_NAME}" --value "${SECRET_VALUE}"
More docs can be found here: https://docs.microsoft.com/en-us/cli/azure/keyvault/secret?view=azure-cli-latest
Note: Historically this module couldn't look up groups by display name, that is now available in product_group_name
The product group object id is the Azure AD group object_id of users who should be allowed to write secrets into the vault (note they can't read the secrets after writing).
Useful commands for finding your group object id:
List all reform groups:
$ az ad group list --query "[?contains(displayName, 'dcd_')].{DisplayName: displayName, id: id}" -o table
Retrieve by name if you know the display name:
$ az ad group list --query "[?displayName=='dcd_devops'].{DisplayName: displayName, id: id}" -o table
Allow the jenkins subnet id e.g [data.azurerm_subnet.jenkins_subnet.id] and others Allow the listed set of IPs
# Set by the Jenkins pipeline
variable "mgmt_subscription_id" {}
provider "azurerm" {
alias = "mgmt"
subscription_id = var.mgmt_subscription_id
features {}
}
# for SDS
data "azurerm_subnet" "jenkins_subnet" {
provider = azurerm.mgmt
name = "iaas"
virtual_network_name = var.env == "sbox" ? "ss-ptlsbox-vnet" : "ss-ptl-vnet"
resource_group_name = var.env == "sbox" ? "ss-ptlsbox-network-rg" : "ss-ptl-network-rg"
}
# for CFT
data "azurerm_subnet" "jenkins_subnet" {
provider = azurerm.mgmt
name = "iaas"
virtual_network_name = "cft-ptl-vnet"
resource_group_name = "cft-ptl-network-rg"
}
module "key_vault" {
source = "git@github.com:hmcts/cnp-module-key-vault?ref=master"
#...
network_acls_allowed_subnet_ids = [data.azurerm_subnet.jenkins_subnet.id]
network_acls_allowed_ip_ranges = ["IPs"]
network_acls_default_action = "Deny" # Allow by default
}
If your application is running in kubernetes it will retrieve the secrets with a managed identity.
Teams can use single Manage Identity for all the key vaults owned by a team.
In order to allow the managed identity access you need to either :
Add an additional variable to the module (create_managed_identity
) which will create a managed identity and creates necessary access policy.
module "this" {
source = "git@github.com:hmcts/cnp-module-key-vault?ref=master"
#...
create_managed_identity = true
}
Object Id and Client id are available in terraform output.
Add the managed_identity_object_ids
variable to the module with an existing managed identity.
data "azurerm_user_assigned_identity" "cmc-identity" {
name = "${var.product}-${var.env}-mi"
resource_group_name = "managed-identities-${var.env}-rg"
}
module "key_vault" {
source = "git@github.com:hmcts/cnp-module-key-vault?ref=master"
#...
managed_identity_object_ids = [data.azurerm_user_assigned_identity.cmc-identity.principal_id]
}
You may need to join the readers group for the subscription in order to see the manged identity
It can be retrieved with:
$ az identity show --name <identity-name>-sandbox-mi -g managed-identities-<env>-rg --subscription <Subscription> --query principalId -o tsv
i.e. for sandbox
$ az identity show --name cnp-sandbox-mi -g managed-identities-sbox-rg --subscription DCD-CFT-Sandbox --query principalId -o tsv
To enable private endpoints:
locals {
private_endpoint_rg_name = var.businessArea == "sds" ? "ss-${var.env}-network-rg" : "${var.businessArea}-${var.env}-network-rg"
private_endpoint_vnet_name = var.businessArea == "sds" ? "ss-${var.env}-vnet" : "${var.businessArea}-${var.env}-vnet"
}
# CFT only, on SDS remove this provider
provider "azurerm" {
alias = "private_endpoints"
subscription_id = var.aks_subscription_id
features {}
skip_provider_registration = true
}
data "azurerm_subnet" "private_endpoints" {
# CFT only you will need to provide an extra provider, uncomment the below line, on SDS remove this line and the next
# azurerm.private_endpoints
resource_group_name = local.private_endpoint_rg_name
virtual_network_name = local.private_endpoint_vnet_name
name = "private-endpoints"
}
module "this" {
source = "git@github.com:hmcts/cnp-module-key-vault?ref=master"
name = "rhubarb-fe-${var.env}" // Max 24 characters
product = var.product
env = var.env
object_id = var.jenkins_AAD_objectId
resource_group_name = azurerm_resource_group.rg.name
product_group_name = "Your AAD group" # e.g. MI Data Platform, or dcd_cmc
private_endpoint_subnet_id = data.azurerm_subnet.endpoint_subnet.id
common_tags = var.common_tags
}
variables.tf:
variable "businessArea" {
default = "" # sds or cft, fill this in
}