Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
e423421
Added first draft for CMK + minor fixes
AlexanderSehr Jun 10, 2022
db8a01d
Merge branch 'main' into users/alsehr/778_cmk
AlexanderSehr Jun 19, 2022
08bace4
Disabled ports for testing
AlexanderSehr Jun 19, 2022
6b0c30b
Disabled test file & pester
AlexanderSehr Jun 19, 2022
7ea48fc
URL & port tests
AlexanderSehr Jun 19, 2022
b64a63d
Undid changes
AlexanderSehr Jun 19, 2022
672185f
Updated docs
AlexanderSehr Jun 19, 2022
7edcef2
Updated wiki
AlexanderSehr Jun 19, 2022
25ad60c
Updated wiki
AlexanderSehr Jun 19, 2022
cc1f776
Update to latest
AlexanderSehr Jun 19, 2022
d6de3df
Removed redundant param
AlexanderSehr Jun 20, 2022
d527f87
Merged latest main
AlexanderSehr Jun 23, 2022
98cd5d0
Minor change in prep
AlexanderSehr Jun 27, 2022
50e409a
Updated versioning
AlexanderSehr Jun 27, 2022
f7a1a0c
Updated versioning
AlexanderSehr Jun 27, 2022
b244c17
Update to latest
AlexanderSehr Jun 27, 2022
cb129b0
Update to latest
AlexanderSehr Jun 27, 2022
1b6acc1
Cleanup
AlexanderSehr Jun 27, 2022
89c478c
Update to latest
AlexanderSehr Jun 27, 2022
13e3a38
Update to latest
AlexanderSehr Jun 27, 2022
b6e85c3
Merged latest main
AlexanderSehr Dec 2, 2022
e10655e
Update to latest
AlexanderSehr Dec 2, 2022
66822f2
Merge branch 'main' into users/alsehr/778_cmk
AlexanderSehr Dec 21, 2022
bc65357
cleanup
AlexanderSehr Dec 21, 2022
ff0f10e
Latest somehow working
AlexanderSehr Dec 21, 2022
6ff9871
Updated docs
AlexanderSehr Dec 21, 2022
7b18342
Update to latest
AlexanderSehr Dec 21, 2022
4fe8e52
Merged with latest main
AlexanderSehr Dec 23, 2022
41fd8aa
Push updated API Specs file
Dec 23, 2022
ffb7c03
Small fixes
AlexanderSehr Dec 23, 2022
26b5a97
Merge branch 'main' into users/alsehr/778_cmk
AlexanderSehr Dec 23, 2022
7ec486b
Push updated API Specs file
Dec 23, 2022
ebd7701
Update to latest
AlexanderSehr Dec 23, 2022
3b8f916
Update to latest
AlexanderSehr Dec 23, 2022
cd104fb
Push updated API Specs file
Dec 23, 2022
5838142
Update docs/wiki/Getting started - Scenario 2 Onboard module library …
AlexanderSehr Jan 3, 2023
ebbe749
Update modules/Microsoft.ContainerInstance/containerGroups/.test/encr…
AlexanderSehr Jan 3, 2023
6f06117
Update to latest
AlexanderSehr Jan 3, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,15 @@ Finally, the elements described above must further be configured in the followin

| File | Parameter | Notes |
| - | - | - |
| `modules\Microsoft.Web\sites\.test\common\deploy.bicep` | `appSettingsKeyValuePairs.EASYAUTH_SECRET` | Key Vault secret URI without version (e.g., 'https://Test-KeyVault.vault.azure.net/secrets/aBcDeFghIjK69Ln') |
| `modules\Microsoft.Web\sites\.test\common\deploy.bicep` | `authSettingV2Configuration.identityProviders.azureActiveDirectory.registration.clientId` | App ID from the Azure Active Directory App (e.g., '11111111-1111-1111-1111-11111111111') |
| `modules\Microsoft.Web\sites\.test\common\deploy.bicep` | `authSettingV2Configuration.identityProviders.azureActiveDirectory.validation.allowedAudiences` | API endpoint from the Azure Active Directory app (e.g., 'api://11111111-1111-1111-1111-11111111111') |
| `modules/Microsoft.Web/sites/.test/common/deploy.bicep` | `appSettingsKeyValuePairs.EASYAUTH_SECRET` | Key Vault secret URI without version (e.g., 'https://Test-KeyVault.vault.azure.net/secrets/aBcDeFghIjK69Ln') |
| `modules/Microsoft.Web/sites/.test/common/deploy.bicep` | `authSettingV2Configuration.identityProviders.azureActiveDirectory.registration.clientId` | App ID from the Azure Active Directory App (e.g., '11111111-1111-1111-1111-11111111111') |
| `modules/Microsoft.Web/sites/.test/common/deploy.bicep` | `authSettingV2Configuration.identityProviders.azureActiveDirectory.validation.allowedAudiences` | API endpoint from the Azure Active Directory app (e.g., 'api://11111111-1111-1111-1111-11111111111') |

### Microsoft.ContainerInstance/containerGroup

To successfully run the Customer-Managed-Keys encryption test `encr/deploy.test.bicep` of the Container Instance module, you first need to register a Service Principal instance of the `Azure Container Instance Service` Azure application in your test Tenant. This can be achieved, for example, by running the command `New-AzADServicePrincipal -ApplicationId '6bb8e274-af5d-4df2-98a3-4fd78b4cafd9'`. For further information, please refer to the official [docs](https://learn.microsoft.com/en-us/azure/container-instances/container-instances-encrypt-data#create-service-principal-for-aci).

Once the Service Principal is created, please update the `properties/principalId` of the `keyPermissions` deployment in the dependencies file `modules/Microsoft.ContainerInstance/containerGroups/.test/encr/dependencies.bicep` with its object ID. You can fetch the object ID using the command `(Get-AzADServicePrincipal -DisplayName 'Azure Container Instance Service').Id`.

# 5. (Optional) Convert library to ARM

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
@description('Required. The name of the managed identity to create.')
param managedIdentityName string

@description('Optional. The location to deploy resources to.')
param location string = resourceGroup().location

@description('Required. The name of the Key Vault to create.')
@minLength(3)
@maxLength(24)
param keyVaultName string

resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
name: managedIdentityName
location: location
}

resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = {
name: keyVaultName
location: location
properties: {
sku: {
family: 'A'
name: 'standard'
}
tenantId: tenant().tenantId
enablePurgeProtection: true // Required by batch account
softDeleteRetentionInDays: 7
enabledForTemplateDeployment: true
enabledForDiskEncryption: true
enabledForDeployment: true
enableRbacAuthorization: true
accessPolicies: []
}

resource key 'keys@2022-07-01' = {
name: 'keyEncryptionKey'
properties: {
kty: 'RSA'
}
}
}

// Ref: https://learn.microsoft.com/en-us/azure/container-instances/container-instances-encrypt-data#create-service-principal-for-aci
resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid('msi-${keyVault::key.id}-${location}-Azure Container Instance Service-Key Vault Crypto User')
scope: keyVault
properties: {
principalId: '8b659b68-1eb9-4ea5-ab00-a6a182520436' // Replace with your tenant 'Azure Container Instance Service' Service Principal Object Id
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6') // Key Vault Crypto Service Encryption User. Allows Keys: get, list, wrap key, unwrap key
principalType: 'ServicePrincipal'
}
}

@description('The resource ID of the created managed identity.')
output managedIdentityResourceId string = managedIdentity.id

@description('The resource ID of the created Key Vault.')
output keyVaultResourceId string = keyVault.id

@description('The name of the Key Vault Encryption Key.')
output keyVaultEncryptionKeyName string = keyVault::key.name
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
targetScope = 'subscription'

// ========== //
// Parameters //
// ========== //
@description('Optional. The name of the resource group to deploy for testing purposes.')
@maxLength(90)
param resourceGroupName string = 'ms.containerinstance.containergroups-${serviceShort}-rg'

@description('Optional. The location to deploy resources to.')
param location string = deployment().location

@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.')
param serviceShort string = 'cicgecr'

@description('Generated. Used as a basis for unique resource names.')
param baseTime string = utcNow('u')

@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).')
param enableDefaultTelemetry bool = true

// =========== //
// Deployments //
// =========== //

// General resources
// =================
resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
name: resourceGroupName
location: location
}

module resourceGroupResources 'dependencies.bicep' = {
scope: resourceGroup
name: '${uniqueString(deployment().name, location)}-paramNested'
params: {
managedIdentityName: 'dep-<<namePrefix>>-msi-${serviceShort}'
// Adding base time to make the name unique as purge protection must be enabled (but may not be longer than 24 characters total)
keyVaultName: 'dep-<<namePrefix>>-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}'
}
}

// ============== //
// Test Execution //
// ============== //

module testDeployment '../../deploy.bicep' = {
scope: resourceGroup
name: '${uniqueString(deployment().name)}-test-${serviceShort}'
params: {
enableDefaultTelemetry: enableDefaultTelemetry
name: '<<namePrefix>>${serviceShort}001'
lock: 'CanNotDelete'
containers: [
{
name: '<<namePrefix>>-az-aci-x-001'
properties: {
command: []
environmentVariables: []
image: 'mcr.microsoft.com/azuredocs/aci-helloworld'
ports: [
{
port: '80'
protocol: 'Tcp'
}
{
port: '443'
protocol: 'Tcp'
}
]
resources: {
requests: {
cpu: 2
memoryInGB: 2
}
}
}
}
{
name: '<<namePrefix>>-az-aci-x-002'
properties: {
command: []
environmentVariables: []
image: 'mcr.microsoft.com/azuredocs/aci-helloworld'
ports: [
{
port: '8080'
protocol: 'Tcp'
}
]
resources: {
requests: {
cpu: 2
memoryInGB: 2
}
}
}
}
]
ipAddressPorts: [
{
protocol: 'Tcp'
port: 80
}
{
protocol: 'Tcp'
port: 443
}
]
systemAssignedIdentity: true
userAssignedIdentities: {
'${resourceGroupResources.outputs.managedIdentityResourceId}': {}
}
cMKKeyName: resourceGroupResources.outputs.keyVaultEncryptionKeyName
cMKKeyVaultResourceId: resourceGroupResources.outputs.keyVaultResourceId
}
}
113 changes: 56 additions & 57 deletions modules/Microsoft.ContainerInstance/containerGroups/deploy.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,6 @@ param autoGeneratedDomainNameLabelScope string = 'TenantReuse'
@description('Optional. The Dns name label for the resource.')
param dnsNameLabel string = ''

@allowed([
'Standard'
'Dedicated'
])
@description('Optional. Specify the Sku.')
param sku string = 'Standard'

@description('Optional. If Non-Microsoft-managed encryption should be used, specify the key vaults base URL.')
param encryptionVaultBaseUrl string = ''

@description('Optional. If Non-Microsoft-managed encryption should be used, specify the key name.')
param encrytionKeyName string = ''

@description('Optional. If Non-Microsoft-managed encryption should be used, specify the key version.')
param encryptionKeyVersion string = ''

@description('Optional. List of dns servers used by the containers for lookups.')
param dnsNameServers array = []

Expand Down Expand Up @@ -95,53 +79,29 @@ param tags object = {}
@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).')
param enableDefaultTelemetry bool = true

@description('Optional. The container group SKU.')
@allowed([
'Dedicated'
'Standard'
])
param sku string = 'Standard'

@description('Optional. The resource ID of a key vault to reference a customer managed key for encryption from.')
param cMKKeyVaultResourceId string = ''

@description('Optional. The name of the customer managed key to use for encryption.')
param cMKKeyName string = ''

@description('Optional. The version of the customer managed key to reference for encryption. If not provided, the latest key version is used.')
param cMKKeyVersion string = ''

var identityType = systemAssignedIdentity ? (!empty(userAssignedIdentities) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(userAssignedIdentities) ? 'UserAssigned' : 'None')

var identity = identityType != 'None' ? {
type: identityType
userAssignedIdentities: !empty(userAssignedIdentities) ? userAssignedIdentities : null
} : null

var dnsConfig = !empty(dnsNameServers) ? {
nameServers: dnsNameServers
searchDomains: dnsSearchDomains
} : null

var encryptionProperties = !empty(encryptionVaultBaseUrl) ? {
vaultBaseUrl: encryptionVaultBaseUrl
keyName: encrytionKeyName
keyVersion: encryptionKeyVersion
} : null

var subnetIds = !empty(subnetId) ? [
{
id: subnetId
}
] : null

var generatedDomainNameLabelScope = !empty(dnsNameServers) ? autoGeneratedDomainNameLabelScope : null

var basicContainerProperties = {
containers: containers
dnsConfig: dnsConfig
encryptionProperties: encryptionProperties
imageRegistryCredentials: imageRegistryCredentials
initContainers: initContainers
restartPolicy: restartPolicy
osType: osType
ipAddress: {
type: ipAddressType
autoGeneratedDomainNameLabelScope: generatedDomainNameLabelScope
dnsNameLabel: dnsNameLabel
ports: ipAddressPorts
}
sku: sku
subnetIds: subnetIds
volumes: volumes
}

var containerProperties = !empty(dnsNameServers) ? union(basicContainerProperties, { dnsConfig: dnsConfig }) : basicContainerProperties

resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) {
name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}'
properties: {
Expand All @@ -154,12 +114,51 @@ resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (ena
}
}

resource cmkKeyVault 'Microsoft.KeyVault/vaults@2021-06-01-preview' existing = if (!empty(cMKKeyVaultResourceId)) {
name: last(split(cMKKeyVaultResourceId, '/'))
scope: resourceGroup(split(cMKKeyVaultResourceId, '/')[2], split(cMKKeyVaultResourceId, '/')[4])
}

resource cMKKeyVaultKey 'Microsoft.KeyVault/vaults/keys@2021-10-01' existing = if (!empty(cMKKeyVaultResourceId) && !empty(cMKKeyName)) {
name: '${last(split(cMKKeyVaultResourceId, '/'))}/${cMKKeyName}'
scope: resourceGroup(split(cMKKeyVaultResourceId, '/')[2], split(cMKKeyVaultResourceId, '/')[4])
}

resource containergroup 'Microsoft.ContainerInstance/containerGroups@2021-10-01' = {
name: name
location: location
identity: identity
tags: tags
properties: containerProperties
properties: union({
containers: containers
encryptionProperties: !empty(cMKKeyName) ? {
keyName: cMKKeyName
keyVersion: !empty(cMKKeyVersion) ? cMKKeyVersion : last(split(cMKKeyVaultKey.properties.keyUriWithVersion, '/'))
vaultBaseUrl: cmkKeyVault.properties.vaultUri
} : null
imageRegistryCredentials: imageRegistryCredentials
initContainers: initContainers
restartPolicy: restartPolicy
osType: osType
ipAddress: {
type: ipAddressType
autoGeneratedDomainNameLabelScope: !empty(dnsNameServers) ? autoGeneratedDomainNameLabelScope : null
dnsNameLabel: dnsNameLabel
ports: ipAddressPorts
}
sku: sku
subnetIds: !empty(subnetId) ? [
{
id: subnetId
}
] : null
volumes: volumes
}, !empty(dnsNameServers) ? {
dnsConfig: {
nameServers: dnsNameServers
searchDomains: dnsSearchDomains
}
} : {})
}

resource containergroup_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock)) {
Expand Down
Loading