Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(azure): scaffold ssh jumper #958

Merged
merged 8 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions .azure/infrastructure/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ param sourceKeyVaultResourceGroup string
@minLength(3)
param sourceKeyVaultName string

@description('SSH secret key for the ssh jumper')
@secure()
@minLength(3)
param sourceKeyVaultSshJumperSshSecretKey string

import { Sku as KeyVaultSku } from '../modules/keyvault/create.bicep'
param keyVaultSku KeyVaultSku

Expand Down Expand Up @@ -59,6 +64,7 @@ var secrets = {
sourceKeyVaultSubscriptionId: sourceKeyVaultSubscriptionId
sourceKeyVaultResourceGroup: sourceKeyVaultResourceGroup
sourceKeyVaultName: sourceKeyVaultName
sourceKeyVaultSshSecretKey: sourceKeyVaultSshJumperSshSecretKey
}

var namePrefix = 'dp-be-${environment}'
Expand Down Expand Up @@ -150,6 +156,21 @@ var srcKeyVault = {
resourceGroupName: secrets.sourceKeyVaultResourceGroup
}

module sshJumper '../modules/ssh-jumper/main.bicep' = {
scope: resourceGroup
name: 'sshJumper'
params: {
namePrefix: namePrefix
location: location
subnetId: vnet.outputs.defaultSubnetId
tags: tags
srcKeyVaultName: secrets.sourceKeyVaultName
srcKeyVaultSubId: secrets.sourceKeyVaultSubscriptionId
srcKeyVaultRGNName: secrets.sourceKeyVaultResourceGroup
srcKeyVaultSshSecretKey: secrets.sourceKeyVaultSshSecretKey
}
}

module postgresql '../modules/postgreSql/create.bicep' = {
scope: resourceGroup
name: 'postgresql'
Expand Down
1 change: 1 addition & 0 deletions .azure/infrastructure/production.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ param dialogportenPgAdminPassword = readEnvironmentVariable('PG_ADMIN_PASSWORD')
param sourceKeyVaultSubscriptionId = readEnvironmentVariable('SOURCE_KEY_VAULT_SUBSCRIPTION_ID')
param sourceKeyVaultResourceGroup = readEnvironmentVariable('SOURCE_KEY_VAULT_RESOURCE_GROUP')
param sourceKeyVaultName = readEnvironmentVariable('SOURCE_KEY_VAULT_NAME')
param sourceKeyVaultSshJumperSshSecretKey = readEnvironmentVariable('SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY')

// SKUs
param keyVaultSku = {
Expand Down
1 change: 1 addition & 0 deletions .azure/infrastructure/soak.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ param dialogportenPgAdminPassword = readEnvironmentVariable('PG_ADMIN_PASSWORD')
param sourceKeyVaultSubscriptionId = readEnvironmentVariable('SOURCE_KEY_VAULT_SUBSCRIPTION_ID')
param sourceKeyVaultResourceGroup = readEnvironmentVariable('SOURCE_KEY_VAULT_RESOURCE_GROUP')
param sourceKeyVaultName = readEnvironmentVariable('SOURCE_KEY_VAULT_NAME')
param sourceKeyVaultSshJumperSshSecretKey = readEnvironmentVariable('SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY')

// SKUs
param keyVaultSku = {
Expand Down
1 change: 1 addition & 0 deletions .azure/infrastructure/staging.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ param dialogportenPgAdminPassword = readEnvironmentVariable('PG_ADMIN_PASSWORD')
param sourceKeyVaultSubscriptionId = readEnvironmentVariable('SOURCE_KEY_VAULT_SUBSCRIPTION_ID')
param sourceKeyVaultResourceGroup = readEnvironmentVariable('SOURCE_KEY_VAULT_RESOURCE_GROUP')
param sourceKeyVaultName = readEnvironmentVariable('SOURCE_KEY_VAULT_NAME')
param sourceKeyVaultSshJumperSshSecretKey = readEnvironmentVariable('SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY')

// SKUs
param keyVaultSku = {
Expand Down
1 change: 1 addition & 0 deletions .azure/infrastructure/test.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ param dialogportenPgAdminPassword = readEnvironmentVariable('PG_ADMIN_PASSWORD')
param sourceKeyVaultSubscriptionId = readEnvironmentVariable('SOURCE_KEY_VAULT_SUBSCRIPTION_ID')
param sourceKeyVaultResourceGroup = readEnvironmentVariable('SOURCE_KEY_VAULT_RESOURCE_GROUP')
param sourceKeyVaultName = readEnvironmentVariable('SOURCE_KEY_VAULT_NAME')
param sourceKeyVaultSshJumperSshSecretKey = readEnvironmentVariable('SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY')

// SKUs
param keyVaultSku = {
Expand Down
146 changes: 146 additions & 0 deletions .azure/modules/ssh-jumper/main.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
@description('The name prefix to be used for the resource')
param namePrefix string

@description('The location to deploy the resource to')
param location string

@description('The subnet to deploy the network interface to')
param subnetId string

@description('Tags to be applied to the resource')
param tags object

@description('The name of the source Key Vault')
param srcKeyVaultName string

@description('The subscription ID of the source Key Vault')
param srcKeyVaultSubId string

@description('The resource group name of the source Key Vault')
param srcKeyVaultRGNName string

@description('The SSH secret key to be used to get the ssh key for the virtual machine')
@secure()
param srcKeyVaultSshSecretKey string

var name = '${namePrefix}-ssh-jumper'

resource srcKeyVaultResource 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
name: srcKeyVaultName
scope: resourceGroup(srcKeyVaultSubId, srcKeyVaultRGNName)
}

resource publicIp 'Microsoft.Network/publicIPAddresses@2023-11-01' = {
name: '${name}-ip'
location: location
sku: {
name: 'Standard'
tier: 'Regional'
}
zones: [
'1'
]
properties: {
publicIPAddressVersion: 'IPv4'
publicIPAllocationMethod: 'Static'
idleTimeoutInMinutes: 4
ipTags: []
}
tags: tags
}

resource networkInterface 'Microsoft.Network/networkInterfaces@2023-11-01' = {
name: name
location: location
properties: {
ipConfigurations: [
{
name: '${name}-ipconfig'
type: 'Microsoft.Network/networkInterfaces/ipConfigurations'
properties: {
privateIPAddress: '10.0.0.5'
privateIPAllocationMethod: 'Dynamic'
publicIPAddress: {
id: publicIp.id
properties: {
deleteOption: 'Delete'
}
}
subnet: {
id: subnetId
}
primary: true
privateIPAddressVersion: 'IPv4'
}
}
]
dnsSettings: {
dnsServers: []
}
enableAcceleratedNetworking: false
enableIPForwarding: false
disableTcpStateTracking: false
nicType: 'Standard'
auxiliaryMode: 'None'
auxiliarySku: 'None'
}
}

module virtualMachine '../../modules/virtualMachine/main.bicep' = {
name: name
params: {
name: name
sshKeyData: srcKeyVaultResource.getSecret(srcKeyVaultSshSecretKey)
location: location
tags: tags
hardwareProfile: {
vmSize: 'Standard_B1s'
}
additionalCapabilities: {
hibernationEnabled: false
}
storageProfile: {
imageReference: {
publisher: 'canonical'
offer: '0001-com-ubuntu-server-focal'
sku: '20_04-lts-gen2'
version: 'latest'
}
osDisk: {
osType: 'Linux'
name: '${name}-osdisk'
createOption: 'FromImage'
caching: 'ReadWrite'
managedDisk: {
storageAccountType: 'Premium_LRS'
}
deleteOption: 'Delete'
diskSizeGB: 30
}
dataDisks: []
diskControllerType: 'SCSI'
}
securityProfile: {
uefiSettings: {
secureBootEnabled: true
vTpmEnabled: true
}
securityType: 'TrustedLaunch'
}
networkProfile: {
networkInterfaces: [
{
id: networkInterface.id
properties: {
deleteOption: 'Delete'
}
}
]
}
diagnosticsProfile: {
bootDiagnostics: {
enabled: true
}
}
}
}
132 changes: 132 additions & 0 deletions .azure/modules/virtualMachine/main.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
param name string
param location string
param tags object

type HardwareProfile = {
vmSize: string
}
@description('Specifies the hardware profile for the virtual machine')
param hardwareProfile HardwareProfile

type AdditionalCapabilities = {
hibernationEnabled: bool
}
@description('Specifies the additional capabilities for the virtual machine')
param additionalCapabilities AdditionalCapabilities

type SecurityProfile = {
uefiSettings: {
secureBootEnabled: bool
vTpmEnabled: bool
}
securityType: string
}
@description('Specifies the security profile for the virtual machine')
param securityProfile SecurityProfile

type NetworkInterface = {
id: string
properties: {
deleteOption: string
}
}
type NetworkProfile = {
networkInterfaces: NetworkInterface[]
}
@description('Specifies the network profile for the virtual machine')
param networkProfile NetworkProfile

type DiagnosticsProfile = {
bootDiagnostics: {
enabled: bool
}
}
@description('Specifies the diagnostics profile for the virtual machine')
param diagnosticsProfile DiagnosticsProfile

type StorageProfile = {
imageReference: {
publisher: string
offer: string
sku: string
version: string
}
osDisk: {
osType: string
name: string
createOption: string
caching: string
managedDisk: {
storageAccountType: string
}
deleteOption: string
diskSizeGB: int
}
dataDisks: array
diskControllerType: string
}
@description('Specifies the storage profile for the virtual machine')
param storageProfile StorageProfile

@description('Specifies the SSH key data for the virtual machine')
@secure()
param sshKeyData string

resource virtualMachine 'Microsoft.Compute/virtualMachines@2024-03-01' = {
name: name
location: location
zones: [
'1'
]
properties: {
hardwareProfile: hardwareProfile
additionalCapabilities: additionalCapabilities
storageProfile: storageProfile
osProfile: {
computerName: name
adminUsername: name
linuxConfiguration: {
disablePasswordAuthentication: true
ssh: {
publicKeys: [
{
path: '/home/${name}/.ssh/authorized_keys'
keyData: sshKeyData
}
]
}
provisionVMAgent: true
patchSettings: {
patchMode: 'AutomaticByPlatform'
automaticByPlatformSettings: {
rebootSetting: 'IfRequired'
bypassPlatformSafetyChecksOnUserSchedule: false
}
assessmentMode: 'ImageDefault'
}
}
secrets: []
allowExtensionOperations: true
requireGuestProvisionSignal: true
}
securityProfile: securityProfile
networkProfile: networkProfile
diagnosticsProfile: diagnosticsProfile
}
identity: {
type: 'SystemAssigned'
}
tags: tags
}

resource aadLoginExtension 'Microsoft.Compute/virtualMachines/extensions@2023-03-01' = {
parent: virtualMachine
name: 'AADSSHLoginForLinux'
location: location
properties: {
publisher: 'Microsoft.Azure.ActiveDirectory'
type: 'AADSSHLoginForLinux'
typeHandlerVersion: '1.0'
autoUpgradeMinorVersion: true
}
}
3 changes: 3 additions & 0 deletions .github/workflows/action-deploy-infra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ on:
required: true
AZURE_SOURCE_KEY_VAULT_RESOURCE_GROUP:
required: true
AZURE_SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY:
required: true

inputs:
region:
Expand Down Expand Up @@ -98,6 +100,7 @@ jobs:
SOURCE_KEY_VAULT_SUBSCRIPTION_ID: ${{ secrets.AZURE_SOURCE_KEY_VAULT_SUBSCRIPTION_ID }}
SOURCE_KEY_VAULT_RESOURCE_GROUP: ${{ secrets.AZURE_SOURCE_KEY_VAULT_RESOURCE_GROUP }}
SOURCE_KEY_VAULT_NAME: ${{ secrets.AZURE_SOURCE_KEY_VAULT_NAME }}
SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY: ${{ secrets.AZURE_SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY }}
with:
scope: subscription
template: ./.azure/infrastructure/main.bicep
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci-cd-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ jobs:
AZURE_SOURCE_KEY_VAULT_NAME: ${{ secrets.AZURE_SOURCE_KEY_VAULT_NAME }}
AZURE_SOURCE_KEY_VAULT_SUBSCRIPTION_ID: ${{ secrets.AZURE_SOURCE_KEY_VAULT_SUBSCRIPTION_ID }}
AZURE_SOURCE_KEY_VAULT_RESOURCE_GROUP: ${{ secrets.AZURE_SOURCE_KEY_VAULT_RESOURCE_GROUP }}
AZURE_SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY: ${{ secrets.AZURE_SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY }}
with:
environment: test
region: norwayeast
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci-cd-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
AZURE_SOURCE_KEY_VAULT_NAME: ${{ secrets.AZURE_SOURCE_KEY_VAULT_NAME }}
AZURE_SOURCE_KEY_VAULT_SUBSCRIPTION_ID: ${{ secrets.AZURE_SOURCE_KEY_VAULT_SUBSCRIPTION_ID }}
AZURE_SOURCE_KEY_VAULT_RESOURCE_GROUP: ${{ secrets.AZURE_SOURCE_KEY_VAULT_RESOURCE_GROUP }}
AZURE_SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY: ${{ secrets.AZURE_SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY }}
with:
environment: test
region: norwayeast
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci-cd-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ jobs:
AZURE_SOURCE_KEY_VAULT_NAME: ${{ secrets.AZURE_SOURCE_KEY_VAULT_NAME }}
AZURE_SOURCE_KEY_VAULT_SUBSCRIPTION_ID: ${{ secrets.AZURE_SOURCE_KEY_VAULT_SUBSCRIPTION_ID }}
AZURE_SOURCE_KEY_VAULT_RESOURCE_GROUP: ${{ secrets.AZURE_SOURCE_KEY_VAULT_RESOURCE_GROUP }}
AZURE_SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY: ${{ secrets.AZURE_SOURCE_KEY_VAULT_SSH_JUMPER_SSH_SECRET_KEY }}
with:
environment: staging
region: norwayeast
Expand Down
Loading
Loading