Skip to content

Commit

Permalink
[Modules] New Microsoft.Compute/sshPublicKey (#2673)
Browse files Browse the repository at this point in the history
* add sshPublicKey Module

* Update modules/Microsoft.Compute/sshPublicKeys/readme.md

Co-authored-by: Alexander Sehr <ASehr@hotmail.de>

* Update modules/Microsoft.Compute/sshPublicKeys/deploy.bicep

Co-authored-by: Alexander Sehr <ASehr@hotmail.de>

* Update modules/Microsoft.Compute/sshPublicKeys/.test/common/dependencies.bicep

Co-authored-by: Alexander Sehr <ASehr@hotmail.de>

* Update modules/Microsoft.Compute/sshPublicKeys/.test/common/deploy.test.bicep

Co-authored-by: Alexander Sehr <ASehr@hotmail.de>

* Update modules/Microsoft.Compute/sshPublicKeys/.test/min/deploy.test.bicep

Co-authored-by: Alexander Sehr <ASehr@hotmail.de>

* Update modules/Microsoft.Compute/sshPublicKeys/readme.md

Co-authored-by: Alexander Sehr <ASehr@hotmail.de>

* Update modules/Microsoft.Compute/sshPublicKeys/deploy.bicep

Co-authored-by: Alexander Sehr <ASehr@hotmail.de>

* Update modules/Microsoft.Compute/sshPublicKeys/deploy.bicep

Co-authored-by: Alexander Sehr <ASehr@hotmail.de>

* resolved comments

* updated readme and nested role assignments

* added !

---------

Co-authored-by: Shawn Meyer <shawn.meyer@microsoft.com>
Co-authored-by: Alexander Sehr <ASehr@hotmail.de>
  • Loading branch information
3 people authored Apr 18, 2023
1 parent 9a6383b commit ce13120
Show file tree
Hide file tree
Showing 9 changed files with 799 additions and 0 deletions.
50 changes: 50 additions & 0 deletions .azuredevops/modulePipelines/ms.compute.sshpublickeys.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: 'Compute - SshPublicKeys'

parameters:
- name: staticValidation
displayName: Execute static validation
type: boolean
default: true
- name: deploymentValidation
displayName: Execute deployment validation
type: boolean
default: true
- name: removeDeployment
displayName: Remove deployed module
type: boolean
default: true
- name: prerelease
displayName: Publish prerelease module
type: boolean
default: false

pr: none

trigger:
batch: true
branches:
include:
- main
paths:
include:
- '/.azuredevops/modulePipelines/ms.compute.sshpublickeys.yml'
- '/.azuredevops/pipelineTemplates/*.yml'
- '/modules/Microsoft.Compute/sshPublicKeys/*'
- '/utilities/pipelines/*'
exclude:
- '/utilities/pipelines/deploymentRemoval/*'
- '/**/*.md'

variables:
- template: '../../settings.yml'
- group: 'PLATFORM_VARIABLES'
- name: modulePath
value: '/modules/Microsoft.Compute/sshPublicKeys'

stages:
- template: /.azuredevops/pipelineTemplates/stages.module.yml
parameters:
staticValidation: '${{ parameters.staticValidation }}'
deploymentValidation: '${{ parameters.deploymentValidation }}'
removeDeployment: '${{ parameters.removeDeployment }}'
prerelease: '${{ parameters.prerelease }}'
165 changes: 165 additions & 0 deletions .github/workflows/ms.compute.sshpublickeys.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
name: 'Compute: SshPublicKeys'

on:
workflow_dispatch:
inputs:
staticValidation:
type: boolean
description: 'Execute static validation'
required: false
default: true
deploymentValidation:
type: boolean
description: 'Execute deployment validation'
required: false
default: true
removeDeployment:
type: boolean
description: 'Remove deployed module'
required: false
default: true
prerelease:
type: boolean
description: 'Publish prerelease module'
required: false
default: false
push:
branches:
- main
paths:
- '.github/actions/templates/**'
- '.github/workflows/ms.compute.sshpublickeys.yml'
- 'modules/Microsoft.Compute/sshPublicKeys/**'
- 'utilities/pipelines/**'
- '!utilities/pipelines/deploymentRemoval/**'
- '!*/**/readme.md'

env:
variablesPath: 'settings.yml'
modulePath: 'modules/Microsoft.Compute/sshPublicKeys'
workflowPath: '.github/workflows/ms.compute.sshPublicKeys.yml'
AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}
ARM_SUBSCRIPTION_ID: '${{ secrets.ARM_SUBSCRIPTION_ID }}'
ARM_MGMTGROUP_ID: '${{ secrets.ARM_MGMTGROUP_ID }}'
ARM_TENANT_ID: '${{ secrets.ARM_TENANT_ID }}'
TOKEN_NAMEPREFIX: '${{ secrets.TOKEN_NAMEPREFIX }}'

concurrency:
group: ${{ github.workflow }}

jobs:
###########################
# Initialize pipeline #
###########################
job_initialize_pipeline:
runs-on: ubuntu-20.04
name: 'Initialize pipeline'
steps:
- name: 'Checkout'
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: 'Set input parameters to output variables'
id: get-workflow-param
uses: ./.github/actions/templates/getWorkflowInput
with:
workflowPath: '${{ env.workflowPath}}'
- name: 'Get parameter file paths'
id: get-module-test-file-paths
uses: ./.github/actions/templates/getModuleTestFiles
with:
modulePath: '${{ env.modulePath }}'
outputs:
workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }}
moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }}

#########################
# Static validation #
#########################
job_module_static_validation:
runs-on: ubuntu-20.04
name: 'Static validation'
if: (fromJson(needs.job_initialize_pipeline.outputs.workflowInput)).staticValidation == 'true'
needs:
- job_initialize_pipeline
steps:
- name: 'Checkout'
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set environment variables
uses: ./.github/actions/templates/setEnvironmentVariables
with:
variablesPath: ${{ env.variablesPath }}
- name: 'Run tests'
uses: ./.github/actions/templates/validateModulePester
with:
modulePath: '${{ env.modulePath }}'
moduleTestFilePath: '${{ env.moduleTestFilePath }}'

#############################
# Deployment validation #
#############################
job_module_deploy_validation:
runs-on: ubuntu-20.04
name: 'Deploying'
if: |
!cancelled() &&
(fromJson(needs.job_initialize_pipeline.outputs.workflowInput)).deploymentValidation == 'true' &&
needs.job_module_static_validation.result != 'failure'
needs:
- job_initialize_pipeline
- job_module_static_validation
strategy:
fail-fast: false
matrix:
moduleTestFilePaths: ${{ fromJson(needs.job_initialize_pipeline.outputs.moduleTestFilePaths) }}
steps:
- name: 'Checkout'
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set environment variables
uses: ./.github/actions/templates/setEnvironmentVariables
with:
variablesPath: ${{ env.variablesPath }}
- name: 'Using test file [${{ matrix.moduleTestFilePaths }}]'
uses: ./.github/actions/templates/validateModuleDeployment
with:
templateFilePath: '${{ env.modulePath }}/${{ matrix.moduleTestFilePaths }}'
location: '${{ env.location }}'
subscriptionId: '${{ secrets.ARM_SUBSCRIPTION_ID }}'
managementGroupId: '${{ secrets.ARM_MGMTGROUP_ID }}'
removeDeployment: '${{ (fromJson(needs.job_initialize_pipeline.outputs.workflowInput)).removeDeployment }}'

##################
# Publishing #
##################
job_publish_module:
name: 'Publishing'
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' || github.event.inputs.prerelease == 'true'
runs-on: ubuntu-20.04
needs:
- job_module_deploy_validation
steps:
- name: 'Checkout'
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set environment variables
uses: ./.github/actions/templates/setEnvironmentVariables
with:
variablesPath: ${{ env.variablesPath }}
- name: 'Publishing'
uses: ./.github/actions/templates/publishModule
with:
templateFilePath: '${{ env.modulePath }}/deploy.bicep'
templateSpecsRGName: '${{ env.templateSpecsRGName }}'
templateSpecsRGLocation: '${{ env.templateSpecsRGLocation }}'
templateSpecsDescription: '${{ env.templateSpecsDescription }}'
templateSpecsDoPublish: '${{ env.templateSpecsDoPublish }}'
bicepRegistryName: '${{ env.bicepRegistryName }}'
bicepRegistryRGName: '${{ env.bicepRegistryRGName }}'
bicepRegistryRgLocation: '${{ env.bicepRegistryRgLocation }}'
bicepRegistryDoPublish: '${{ env.bicepRegistryDoPublish }}'
publishLatest: '${{ env.publishLatest }}'
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
@sys.description('Required. The IDs of the principals to assign the role to.')
param principalIds array

@sys.description('Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead.')
param roleDefinitionIdOrName string

@sys.description('Required. The resource ID of the resource to apply the role assignment to.')
param resourceId string

@sys.description('Optional. The principal type of the assigned principal ID.')
@allowed([
'ServicePrincipal'
'Group'
'User'
'ForeignGroup'
'Device'
''
])
param principalType string = ''

@sys.description('Optional. The description of the role assignment.')
param description string = ''

@sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".')
param condition string = ''

@sys.description('Optional. Version of the condition.')
@allowed([
'2.0'
])
param conditionVersion string = '2.0'

@sys.description('Optional. Id of the delegated managed identity resource.')
param delegatedManagedIdentityResourceId string = ''

var builtInRoleNames = {
'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')
'Avere Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')
'Azure Center for SAP solutions administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')
'Azure Center for SAP solutions reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')
'Azure Center for SAP solutions service role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')
'Azure Kubernetes Service Policy Add-on Deployment': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')
'Compute Gallery Sharing Admin': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1ef6a3be-d0ac-425d-8c01-acb62866290b')
Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
'Data Operator for Managed Disks': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '959f8984-c045-4866-89c7-12bf9737be2e')
'Desktop Virtualization Power On Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '489581de-a3bd-480d-9518-53dea7416b33')
'Desktop Virtualization Power On Off Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '40c5ff49-9181-41f8-ae61-143b0e78555e')
'Desktop Virtualization Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')
'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')
'Disk Backup Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24')
'Disk Pool Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '60fc6e62-5479-42d4-8bf4-67625fcc2840')
'Disk Restore Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b50d9833-a0cb-478e-945f-707fcc997c13')
'Disk Snapshot Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7efff54f-a5b4-42b5-a1c5-5411624893ce')
'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
'Reservation Purchaser': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689')
'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')
'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')
'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')
'Virtual Machine Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')
'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')
'Virtual Machine User Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')
'VM Scanner Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd24ecba3-c1f4-40fa-a7bb-4588a071e8fd')
'Windows Admin Center Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')
}

resource sshKey 'Microsoft.Compute/sshPublicKeys@2022-11-01' existing = {
name: last(split(resourceId, '/'))!
}

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in principalIds: {
name: guid(resourceId, principalId, roleDefinitionIdOrName)
properties: {
description: description
roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
principalId: principalId
principalType: !empty(principalType) ? any(principalType) : null
condition: !empty(condition) ? condition : null
conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null
delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) ? delegatedManagedIdentityResourceId : null
}
scope: sshKey
}]
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
@description('Optional. The location to deploy resources to.')
param location string = resourceGroup().location

@description('Optional. Name of the Deployment Script that creates the SSH Public Key.')
param generateSshPubKeyScriptName string

@description('Required. The name of the Managed Identity to create.')
param managedIdentityName string

@description('Required. Name of the temporary SSH Public Key to create for test.')
param sshKeyName string

@description('Optional. Do not provide a value. Used to force the deployment script to rerun on every redeployment.')
param utcValue string = utcNow()

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

// required for the deployment script to create a new temporary ssh public key object
resource msi_ContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, 'ManagedIdentityContributor', '<<namePrefix>>')
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor
principalId: managedIdentity.properties.principalId
principalType: 'ServicePrincipal'
}
}

resource createPubKeyScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
name: generateSshPubKeyScriptName
location: location
kind: 'AzurePowerShell'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${managedIdentity.id}': {}
}
}
properties: {
azPowerShellVersion: '8.0'
retentionInterval: 'P1D'
arguments: '-ResourceGroupName ${resourceGroup().name} -SSHKeyName ${sshKeyName}'
scriptContent: loadTextContent('../../../../.shared/.scripts/New-SSHKey.ps1')
cleanupPreference: 'OnExpiration'
forceUpdateTag: utcValue
}
dependsOn: [
msi_ContributorRoleAssignment
]
}

@description('The public key to be added to the SSH Public Key resource.')
output publicKey string = createPubKeyScript.properties.outputs.pubKey

@description('The resource ID of the managed Identity')
output managedIdentityId string = managedIdentity.id

@description('The principal ID of the created Managed Identity.')
output managedIdentityPrincipalId string = managedIdentity.properties.principalId
Loading

0 comments on commit ce13120

Please sign in to comment.