Skip to content

Commit 17be4ed

Browse files
feat(bootstrap): add bootstrap Bicep and Terraform make targets for mbsgw
This commit adds a Makefile target to bootstrap the infrastructure setup for the `mbsgw` project using both Bicep and Terraform. It includes environment-specific variables, resource group initialisation modules, and scripts to facilitate the deployment process. Refs: DTOSS-12260
1 parent dd977b3 commit 17be4ed

14 files changed

Lines changed: 729 additions & 0 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
include scripts/shared.mk
2+
include scripts/terraform/terraform.mk
23

34
.DEFAULT_GOAL := help
45

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
ENV_CONFIG=dev
2+
ENVIRONMENT=dev
3+
AZURE_SUBSCRIPTION="Breast Screening - Manage Breast Screening - Dev"
4+
HUB_SUBSCRIPTION="Digital Screening DToS - DevOps"
5+
HUB=dev
6+
TERRAFORM_MODULES_REF=main
7+
ENABLE_SOFT_DELETE=false
8+
ADO_MANAGEMENT_POOL=private-pool-dev-uks
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
ENV_CONFIG=preprod
2+
ENVIRONMENT=preprod
3+
AZURE_SUBSCRIPTION="Breast Screening - Manage Breast Screening - Preprod"
4+
HUB_SUBSCRIPTION="Digital Screening DToS - Core Services Prod Hub"
5+
HUB=prod
6+
TERRAFORM_MODULES_REF=main
7+
ENABLE_SOFT_DELETE=false
8+
ADO_MANAGEMENT_POOL=private-pool-prod-uks
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
ENV_CONFIG=prod
2+
ENVIRONMENT=prod
3+
AZURE_SUBSCRIPTION="Breast Screening - Manage Breast Screening - Prod"
4+
HUB_SUBSCRIPTION="Digital Screening DToS - Core Services Prod Hub"
5+
HUB=prod
6+
TERRAFORM_MODULES_REF=main
7+
ENABLE_SOFT_DELETE=false
8+
ADO_MANAGEMENT_POOL=private-pool-prod-uks
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
ENV_CONFIG=review
2+
ENVIRONMENT=review
3+
AZURE_SUBSCRIPTION="Breast Screening - Manage Breast Screening - Dev"
4+
HUB_SUBSCRIPTION="Digital Screening DToS - DevOps"
5+
HUB=dev
6+
TERRAFORM_MODULES_REF=main
7+
ENABLE_SOFT_DELETE=false
8+
ADO_MANAGEMENT_POOL=private-pool-dev-uks
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
targetScope='subscription'
2+
3+
@minLength(1)
4+
param miPrincipalId string
5+
@minLength(1)
6+
param miName string
7+
@minLength(1)
8+
param userGroupPrincipalID string
9+
@minLength(1)
10+
param userGroupName string
11+
12+
// See: https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles
13+
var roleID = {
14+
contributor: 'b24988ac-6180-42a0-ab88-20f7382dd24c'
15+
kvSecretsUser: '4633458b-17de-408a-b874-0445c86b69e6'
16+
kvSecretsOfficer: 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7'
17+
rbacAdmin: 'f58310d9-a9f6-439a-9e8d-f62e7b41a168'
18+
storageBlobDataContributor: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe'
19+
storageQueueDataContributor: '974c5e8b-45b9-4653-ba55-5f855dd0fb88'
20+
AzureConnectedMachineOnboarding: 'b64e21ea-ac4e-4cdf-9dc9-5b892992bee7'
21+
}
22+
23+
// Define role assignments for managed identity
24+
var miRoleAssignments = [
25+
{
26+
roleName: 'contributor'
27+
roleId: roleID.contributor
28+
description: 'Contributor access to subscription'
29+
}
30+
{
31+
roleName: 'kvSecretsUser'
32+
roleId: roleID.kvSecretsUser
33+
description: 'kvSecretsUser access to subscription'
34+
}
35+
{
36+
roleName: 'rbacAdmin'
37+
roleId: roleID.rbacAdmin
38+
description: 'Role Based Access Control Administrator access to subscription. Can assign Storage Blob Data Contributor, Storage Queue Data Contributor, and Azure Connected Machine Onboarding roles.'
39+
// Optional properties - only rbacAdmin has a condition
40+
condition: '((!(ActionMatches{\'Microsoft.Authorization/roleAssignments/write\'})) OR (@Request[Microsoft.Authorization/roleAssignments:RoleDefinitionId] ForAnyOfAnyValues:GuidEquals {${roleID.storageBlobDataContributor}, ${roleID.storageQueueDataContributor}, ${roleID.AzureConnectedMachineOnboarding}})) AND ((!(ActionMatches{\'Microsoft.Authorization/roleAssignments/delete\'})) OR (@Resource[Microsoft.Authorization/roleAssignments:RoleDefinitionId] ForAnyOfAnyValues:GuidEquals {${roleID.storageBlobDataContributor}, ${roleID.storageQueueDataContributor}, ${roleID.AzureConnectedMachineOnboarding}}))'
41+
conditionVersion: '2.0'
42+
}
43+
]
44+
45+
// Define role assignments for Entra ID group
46+
var groupRoleAssignments = [
47+
{
48+
roleName: 'contributor'
49+
roleId: roleID.contributor
50+
description: 'Contributor access to subscription'
51+
}
52+
{
53+
roleName: 'kvSecretsOfficer'
54+
roleId: roleID.kvSecretsOfficer
55+
description: 'kvSecretsOfficer access to subscription'
56+
}
57+
{
58+
roleName: 'rbacAdmin'
59+
roleId: roleID.rbacAdmin
60+
description: 'Role Based Access Control Administrator access to subscription. Can assign Storage Blob Data Contributor, Storage Queue Data Contributor, and Azure Connected Machine Onboarding roles.'
61+
// Optional properties - only rbacAdmin has a condition
62+
condition: '((!(ActionMatches{\'Microsoft.Authorization/roleAssignments/write\'})) OR (@Request[Microsoft.Authorization/roleAssignments:RoleDefinitionId] ForAnyOfAnyValues:GuidEquals {${roleID.storageBlobDataContributor}, ${roleID.storageQueueDataContributor}, ${roleID.AzureConnectedMachineOnboarding}})) AND ((!(ActionMatches{\'Microsoft.Authorization/roleAssignments/delete\'})) OR (@Resource[Microsoft.Authorization/roleAssignments:RoleDefinitionId] ForAnyOfAnyValues:GuidEquals {${roleID.storageBlobDataContributor}, ${roleID.storageQueueDataContributor}, ${roleID.AzureConnectedMachineOnboarding}}))'
63+
conditionVersion: '2.0'
64+
}
65+
]
66+
67+
// This creates one resource for each item in the miRoleAssignments array
68+
resource miRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for role in miRoleAssignments: {
69+
// guid() ensures unique names for each assignment
70+
name: guid(subscription().subscriptionId, miPrincipalId, role.roleName)
71+
properties: {
72+
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', role.roleId)
73+
principalId: miPrincipalId
74+
principalType: 'ServicePrincipal'
75+
description: '${miName} ${role.description}'
76+
// Conditionally include the 'condition' property only if it exists in the role object
77+
condition: role.?condition
78+
conditionVersion: role.?conditionVersion
79+
}
80+
}]
81+
82+
83+
// This creates one resource for each item in the groupRoleAssignments array
84+
resource groupRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for role in groupRoleAssignments: {
85+
name: guid(subscription().subscriptionId, userGroupPrincipalID, role.roleName)
86+
properties: {
87+
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', role.roleId)
88+
principalId: userGroupPrincipalID
89+
principalType: 'Group'
90+
description: '${userGroupName} ${role.description}'
91+
condition: role.?condition
92+
conditionVersion: role.?conditionVersion
93+
}
94+
}]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
param resourceServiceType string
2+
3+
var dnsZoneName = {
4+
storage: 'privatelink.blob.${environment().suffixes.storage}'
5+
// Cannot read vault URL from environment() because of https://github.com/Azure/bicep/issues/9839
6+
keyVault: 'privatelink.vaultcore.azure.net'
7+
}
8+
9+
// Retrieve the private DNS zone for storage accounts
10+
resource privateDNSZone 'Microsoft.Network/privateDnsZones@2024-06-01' existing = {
11+
name: dnsZoneName[resourceServiceType]
12+
}
13+
14+
output privateDNSZoneID string = privateDNSZone.id
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
2+
param enableSoftDelete bool
3+
param keyVaultName string
4+
param miPrincipalId string
5+
param miName string
6+
param region string
7+
param userGroupPrincipalID string
8+
param userGroupName string
9+
10+
// See: https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles
11+
var roleID = {
12+
kvSecretsUser: '4633458b-17de-408a-b874-0445c86b69e6'
13+
kvSecretsOfficer: 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7'
14+
}
15+
16+
// Define role assignments for managed identity (read-only)
17+
var miRoleAssignments = [
18+
{
19+
roleName: 'kvSecretsUser'
20+
roleId: roleID.kvSecretsUser
21+
description: 'kvSecretsUser access to resource group'
22+
}
23+
]
24+
25+
// Define role assignments for Entra ID group (full management)
26+
var groupRoleAssignments = [
27+
{
28+
roleName: 'kvSecretsOfficer'
29+
roleId: roleID.kvSecretsOfficer
30+
description: 'kvSecretsOfficer access to resource group'
31+
}
32+
]
33+
34+
resource keyVault 'Microsoft.KeyVault/vaults@2024-11-01' = {
35+
name: keyVaultName
36+
location: region
37+
properties: {
38+
tenantId: subscription().tenantId
39+
sku: {
40+
name: 'standard'
41+
family: 'A'
42+
}
43+
enableRbacAuthorization: true
44+
enabledForDeployment: true
45+
enabledForTemplateDeployment: true
46+
enabledForDiskEncryption: true
47+
enableSoftDelete: enableSoftDelete
48+
publicNetworkAccess: 'disabled'
49+
}
50+
}
51+
52+
// Managed identity RBAC assignments using loop
53+
resource miRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for role in miRoleAssignments: {
54+
name: guid(subscription().subscriptionId, miPrincipalId, role.roleName)
55+
properties: {
56+
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', role.roleId)
57+
principalId: miPrincipalId
58+
principalType: 'ServicePrincipal'
59+
description: '${miName} ${role.description}'
60+
}
61+
}]
62+
63+
// Entra ID Group RBAC assignments using loop
64+
resource groupRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for role in groupRoleAssignments: {
65+
name: guid(subscription().subscriptionId, userGroupPrincipalID, role.roleName)
66+
properties: {
67+
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', role.roleId)
68+
principalId: userGroupPrincipalID
69+
principalType: 'Group'
70+
description: '${userGroupName} ${role.description}'
71+
}
72+
}]
73+
74+
// Output the key vault ID so it can be used to create the private endpoint
75+
output keyVaultID string = keyVault.id

0 commit comments

Comments
 (0)