diff --git a/activedirectory/CreateADTrust-Manual-Steps b/activedirectory/CreateADTrust-Manual-Steps new file mode 100644 index 0000000000..e88fcf454a --- /dev/null +++ b/activedirectory/CreateADTrust-Manual-Steps @@ -0,0 +1,9 @@ +Safe Haven Management Domain Controller + - Create DNS Conditional Forwarder in DNS referencing DSG DNS server + - Create Two-Way External Forest trust between Safe Haven Domain Controller and DSG domain controller. + +DSG Domain Controller + - Create DNS Conditional Forwarder in DNS referencing Safe Haven Management DNS server + - Create Two-Way External Forest trust between SG domain controller and Safe Haven Domain Controller. + +Verify that trust is in place and working. diff --git a/activedirectory/Create_NSG_Subnet_Identity.ps1 b/activedirectory/Create_NSG_Subnet_Identity.ps1 new file mode 100644 index 0000000000..318fe5fb6f --- /dev/null +++ b/activedirectory/Create_NSG_Subnet_Identity.ps1 @@ -0,0 +1,251 @@ +#Resources +$resourceGroupName = "RG_DSG_VNET" +$location = "UKWest" +$region = "ukwest" +$nsgName = "NSG_MGMT_SUBNET_IDENTITY" + +#Select subscription +write-Host -ForegroundColor Cyan "Select the correct subscription..." +$subscription = ( + Get-AzureRmSubscription | + Sort-Object -Property Name | + Select-Object -Property Name,Id | + Out-GridView -OutputMode Single -Title 'Select an subscription' +).name + +Select-AzureRmSubscription -SubscriptionName $subscription +write-Host -ForegroundColor Green "Ok, lets go!" + +Read-Host -Prompt "Check that the subscription has been selected above, press any key to continue or Ctrl+C to abort" + +# Create Network Security Group +$nsg = New-AzureRmNetworkSecurityGroup -Name "$nsgName" -ResourceGroupName $resourceGroupName -Location $location + +$nsg = Get-AzureRmNetworkSecurityGroup -Name "$nsgName" -ResourceGroupName $resourceGroupName + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "RPC_endpoint_mapper" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol * ` + -Direction Inbound ` + -Priority 200 ` + -SourceAddressPrefix "10.250.248.0/24" ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 135 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "LDAP" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol TCP ` + -Direction Inbound ` + -Priority 201 ` + -SourceAddressPrefix "10.250.248.0/24","10.250.250.0/24" ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 389 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "LDAP_Ping" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol UDP ` + -Direction Inbound ` + -Priority 202 ` + -SourceAddressPrefix "10.250.248.0/24","10.250.250.0/24" ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 389 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "LDAP_over_SSL" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol TCP ` + -Direction Inbound ` + -Priority 203 ` + -SourceAddressPrefix "10.250.248.0/24" ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 636 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "Global_catalog_LDAP" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol TCP ` + -Direction Inbound ` + -Priority 204 ` + -SourceAddressPrefix "10.250.248.0/24" ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 3268 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "Global_catalog_LDAP_over_SSL" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol TCP ` + -Direction Inbound ` + -Priority 205 ` + -SourceAddressPrefix "10.250.248.0/24" ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 3269 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "DNS" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol * ` + -Direction Inbound ` + -Priority 206 ` + -SourceAddressPrefix "10.250.248.0/24" ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 53 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "Kerberos" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol * ` + -Direction Inbound ` + -Priority 207 ` + -SourceAddressPrefix "10.250.248.0/24" ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 88 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "SMB_over_IP_Microsoft-DS" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol * ` + -Direction Inbound ` + -Priority 208 ` + -SourceAddressPrefix "10.250.248.0/24" ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 445 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "NetBIOS_name_service" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol * ` + -Direction Inbound ` + -Priority 209 ` + -SourceAddressPrefix VirtualNetwork ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 137 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "NetBIOS_datagram_service" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol UDP ` + -Direction Inbound ` + -Priority 210 ` + -SourceAddressPrefix VirtualNetwork ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 138 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "NetBIOS_session_service" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol TCP ` + -Direction Inbound ` + -Priority 211 ` + -SourceAddressPrefix VirtualNetwork ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 139 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "NetBIOS_session_service" ` + -Description "Active Directory Rule" ` + -Access Allow ` + -Protocol TCP ` + -Direction Inbound ` + -Priority 211 ` + -SourceAddressPrefix VirtualNetwork ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 139 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "Kerberos_Password_Change" ` + -Description "Kerberos Password Change" ` + -Access Allow ` + -Protocol * ` + -Direction Inbound ` + -Priority 213 ` + -SourceAddressPrefix VirtualNetwork ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 464 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "RADIUS_Authenitcation_RDS_to_NPS" ` + -Description "Allows RDS servers to connection to NPS server for MFA" ` + -Access Allow ` + -Protocol UDP ` + -Direction Inbound ` + -Priority 300 ` + -SourceAddressPrefix "10.250.249.250" ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange "1812","1813" +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "Remote_Desktop_Connection" ` + -Description "Allows RDP connection to servers from P2S VPN" ` + -Access Allow ` + -Protocol TCP ` + -Direction Inbound ` + -Priority 400 ` + -SourceAddressPrefix "172.16.201.0/24" ` + -SourcePortRange * ` + -DestinationAddressPrefix VirtualNetwork ` + -DestinationPortRange 3389 +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg + + + + + + + +Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg ` + -Name "Deny_All" ` + -Description "Block non-AD traffic" ` + -Access Deny ` + -Protocol * ` + -Direction Inbound ` + -Priority 3000 ` + -SourceAddressPrefix * ` + -SourcePortRange * ` + -DestinationAddressPrefix * ` + -DestinationPortRange * +Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg diff --git a/activedirectory/Create_SafeHavenManagment_DCs.ps1 b/activedirectory/Create_SafeHavenManagment_DCs.ps1 new file mode 100644 index 0000000000..592c330d64 --- /dev/null +++ b/activedirectory/Create_SafeHavenManagment_DCs.ps1 @@ -0,0 +1,228 @@ +#VM Settings +$publisher = "MicrosoftWindowsServer" +$offer = "WindowsServer" +$sku = "2019-Datacenter" +$vmsize = "Standard_D2s_v3" +$version = "latest" + +#SHMDC1 +$dc1osdiskSize = '128' +$dc1osdiskname = "SHMDC1_OS_Disk" +$dc1name = "SHMDC1" +$dc1nicname = "SHMDC1_NIC1" +$dc1ipaddress = "10.251.0.250" + +#SHMDC2 +$dc2osdiskSize = '128' +$dc2osdiskname = "SHMDC2_OS_Disk" +$dc2name = "SHMDC2" +$dc2nicname = "SHMDC2_NIC1" +$dc2ipaddress = "10.251.0.249" + +#Diagnostics settings +$storagediagname = ('bbazdcdiag'+(Get-Random)) +$storagediagsku = "Standard_LRS" + +#Storage Type +$diskaccountType = "Premium_LRS" + + +#Resources +$resourceGroupName = "RG_SHM_VM_DC" +$location = "UK South" +$availabilityset = "AVSET_SHM_VM_DC" + +#Select subscription +write-Host -ForegroundColor Cyan "Select the correct subscription..." +$subscription = ( + Get-AzureRmSubscription | + Sort-Object -Property Name | + Select-Object -Property Name,Id | + Out-GridView -OutputMode Single -Title 'Select an subscription' +).name + +Select-AzureRmSubscription -SubscriptionName $subscription +write-Host -ForegroundColor Green "Ok, got it!" + +Read-Host -Prompt "Check that the subscription has been selected above, press enter key to continue or Ctrl+C to abort" + +#Network +$vnetrg = "RG_SHM_VNet" +$subnetName = "Subnet-Identity" + +#Select VNet +write-Host -ForegroundColor Cyan "Select the correct VNET..." +$vnetname = ( + Get-AzureRmVirtualNetwork -ResourceGroupName $vnetrg | + Sort-Object -Property Name | + Select-Object -Property Name,Id | + Out-GridView -OutputMode Single -Title 'Select the correct VNet' +).name +write-Host -ForegroundColor Green "Ok, got it!" + +# Enter credentials for new VM +write-Host -ForegroundColor Green "Enter credentials to be used for VMs local administrator account" +$cred = Get-Credential + +# Create Resource Group for DC +write-Host -ForegroundColor Cyan "Creating Resource Group..." +New-AzureRmResourceGroup -Name $resourceGroupName -Location $location +write-Host -ForegroundColor Green "Resource Group Created" + +# Connect to existing VNET +write-Host -ForegroundColor Cyan "Getting virtual network..." +$vnet = Get-AzureRmVirtualNetwork -Name $vnetname -ResourceGroupName $vnetrg +write-Host -ForegroundColor Green "Got it!" + +# Select the subnet +write-Host -ForegroundColor Cyan "Getting subnet..." +$SubnetID = (Get-AzureRmVirtualNetworkSubnetConfig -Name $subnetname -VirtualNetwork $vnet).Id +write-Host -ForegroundColor Green "Got it!" + +# Create new NICs in VNET +write-Host -ForegroundColor Cyan "Creating DC1 network interface..." +$dc1nic = New-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName ` + -Name $dc1nicname ` + -SubnetID $subnetID ` + -Location $location ` + -PrivateIpAddress $dc1ipaddress +write-Host -ForegroundColor Green "Network interface created" + +write-Host -ForegroundColor Cyan "Creating DC2 network interface..." +$dc2nic = New-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName ` + -Name $dc2nicname ` + -SubnetID $subnetID ` + -Location $location ` + -PrivateIpAddress $dc2ipaddress +write-Host -ForegroundColor Green "Network interface created" + +#Create managed data disks + +#Create 20Gb disks for AD DBs +write-Host -ForegroundColor Cyan "Creating managed disk for DC1..." +$dc1datadisk1config = New-AzureRmDiskConfig -Location $location ` + -DiskSizeGB 20 ` + -AccountType $diskaccountType ` + -OsType Windows ` + -CreateOption Empty + +$dc1datadisk1 = New-AzureRmDisk -ResourceGroupName $resourceGroupName ` + -DiskName ($dc1name+"_Data_Disk1") ` + -Disk $dc1datadisk1config +write-Host -ForegroundColor Green "Managed disk for DC1 created" + +write-Host -ForegroundColor Cyan "Creating managed disk for DC2..." +$dc2datadisk1config = New-AzureRmDiskConfig -Location $location ` + -DiskSizeGB 20 ` + -AccountType $diskaccountType ` + -OsType Windows ` + -CreateOption Empty + +$dc2datadisk1 = New-AzureRmDisk -ResourceGroupName $resourceGroupName ` + -DiskName ($dc2name+"_Data_Disk1") ` + -Disk $dc2datadisk1config +write-Host -ForegroundColor Green "Managed disk for DC2 created" + +#Create availibility set +write-Host -ForegroundColor Cyan "Creating availability set..." +$avset = New-AzureRmAvailabilitySet -Location $location ` + -Name $availabilityset ` + -ResourceGroupName $resourceGroupName ` + -Sku aligned ` + -PlatformFaultDomainCount 2 ` + -PlatformUpdateDomainCount 2 +write-Host -ForegroundColor Green "Availibility set created" + +#Create Storage Account for boot diagnostics +write-Host -ForegroundColor Cyan "Creating diagnostic storage account..." +$storagediag = New-AzureRmStorageAccount -Location $location -Name $storagediagname -ResourceGroupName $resourcegroupname -SkuName $storagediagsku +write-Host -ForegroundColor Green "Diagnostic storage created" + +#Create Domain Controllers +write-Host -ForegroundColor Cyan Creating $dc1name ... + +$dc1vmConfig = New-AzureRmVMConfig -VMName $dc1name ` + -VMSize $vmsize ` + -AvailabilitySetId $avset.id + +$dc1vmConfig = Set-AzureRmVMOSDisk -VM $dc1vmConfig ` + -Name $dc1osdiskname ` + -DiskSizeInGB $dc1osdiskSize ` + -StorageAccountType $diskaccountType ` + -CreateOption fromImage ` + -Windows | + + Set-AzureRmVMOperatingSystem -Windows ` + -ComputerName $dc1name ` + -Credential $cred ` + -ProvisionVMAgent ` + -EnableAutoUpdate | + + Set-AzureRmVMSourceImage -PublisherName $publisher ` + -Offer $offer ` + -Skus $sku ` + -Version $version | + + + Add-AzureRmVMDataDisk -Name $dc1datadisk1.Name ` + -CreateOption Attach ` + -ManagedDiskId $dc1datadisk1.id ` + -Lun 0 | + + Add-AzureRmVMNetworkInterface -Id $dc1nic.Id -Primary | + + Set-AzureRmVMBootDiagnostics -Enable ` + -ResourceGroupName $resourcegroupname ` + -StorageAccountName $storagediag.StorageAccountName + + New-AzureRmVM -ResourceGroupName $resourceGroupName ` + -Location $location ` + -LicenseType "Windows_Server" ` + -VM $dc1vmConfig + +write-Host -ForegroundColor Green $dc1name Complete + +# Create second DC +write-Host -ForegroundColor Cyan Creating $dc2name ... + +$dc2vmConfig = New-AzureRmVMConfig -VMName $dc2name ` + -VMSize $vmsize ` + -AvailabilitySetId $avset.id + + +$dc2vmConfig = Set-AzureRmVMOSDisk -VM $dc2vmConfig ` + -Name $dc2osdiskname ` + -DiskSizeInGB $dc2osdiskSize ` + -StorageAccountType $diskaccountType ` + -CreateOption fromImage ` + -Windows | + + Set-AzureRmVMOperatingSystem -Windows ` + -ComputerName $dc2name ` + -Credential $cred ` + -ProvisionVMAgent ` + -EnableAutoUpdate | + + Set-AzureRmVMSourceImage -PublisherName $publisher ` + -Offer $offer ` + -Skus $sku ` + -Version $version | + + + Add-AzureRmVMDataDisk -Name $dc2datadisk1.Name ` + -CreateOption Attach ` + -ManagedDiskId $dc2datadisk1.id ` + -Lun 0 | + + Add-AzureRmVMNetworkInterface -Id $dc2nic.Id -Primary | + + Set-AzureRmVMBootDiagnostics -Enable ` + -ResourceGroupName $resourcegroupname ` + -StorageAccountName $storagediag.StorageAccountName + + New-AzureRmVM -ResourceGroupName $resourceGroupName ` + -Location $location ` + -LicenseType "Windows_Server" ` + -VM $dc2vmConfig + +write-Host -ForegroundColor Green $dc2name Complete diff --git a/activedirectory/Testing Environment Design.jpg b/activedirectory/Testing Environment Design.jpg new file mode 100644 index 0000000000..0750154044 Binary files /dev/null and b/activedirectory/Testing Environment Design.jpg differ diff --git a/new_dsg_environment/Linux-authentication/Updates to LDAP providers b/new_dsg_environment/Linux-authentication/Updates to LDAP providers new file mode 100644 index 0000000000..ddc39c0f7b --- /dev/null +++ b/new_dsg_environment/Linux-authentication/Updates to LDAP providers @@ -0,0 +1,62 @@ +Data Science VM + + - Remove from current Kerberos realm + - sudo realm leave -U atiadmin dsgroupX.co.uk + + - Edit /etc/ldap.conf + - Update LDAP server to .turingsafehaven.ac.uk:389 + - Update root bn to new LDAP service account on Safe Haven Management AD + + - Edit /etc/ldap.secret + - Update LDAP bind user password + + - Edit /etc/krb5.conf and update as follows: + + DefaultDomain=TURINGSAFEHAVEN.AC.UK + + [realms] + TURINGSAFEHAVEN.AC.UK = { + kdc = .TURINGSAFEHAVEN.AC.UK + kdc = .TURINGSAFEHAVEN.AC.UK + admin_server = .TURINGSAFEHAVEN.AC.UK + default_domain = TURINGSAFEHAVEN.AC.UK + } + + [domain_realm] + .turingsafehaven.ac.uk = TURINGSAFEHAVEN.AC.UK + turingsafehaven.ac.uk = TURINGSAFEHAVEN.AC.UK + + - Join Kerberos realm + - sudo realm join -U atiadmin turingsafehaven.ac.uk + + - Edit /etc/jupyterhub/juypterhub-ldapauthenticator + - Update following items: + - c.LDAPAuthenticator.server_address + - c.LDAPAuthenticator.bind_dn_template + - c.LDAPAuthenticator.lookup_dn_search_user + - c.LDAPAuthenticator.lookup_dn_search_password + - c.LDAPAuthenticator.user_search_base + +GITLAB Server + + - Edit /etc/gitlab/gitlab.rb + - Update the following items under the LDAP settings section + - label + - host + - bind_dn + - password + - base + - user_filter + + - Add turingsafehaven.ac.uk to the "Restricted domains for sign-up" section within the GitLab settings panel. + + +HACKMD Server + + - Edit docker-compose.yml + - Update the following items: + - HMD_LDAP_PROVIDERNAME + - HMD_LDAP_URL + - HMD_LDAP_BINDDN + - HMD_LDAP_SEARCHBASE + diff --git a/new_dsg_environment/azure-vms/DSG2018/README-parallel-deploy-using-azure-vms.md b/new_dsg_environment/azure-vms/DSG2018/README-parallel-deploy-using-azure-vms.md new file mode 100644 index 0000000000..61a8f11788 --- /dev/null +++ b/new_dsg_environment/azure-vms/DSG2018/README-parallel-deploy-using-azure-vms.md @@ -0,0 +1,40 @@ + + +## Make a new deployment VM +### Create a new Azure VM +- Log into the Azure portal +- Click on the VM icon in the left hand sidebar +- Click on the "+" icon in the pane header to add a VM +- Base on Ubuntu 18.04 LTS +- Create in the "Safe Haven Management Testing" subscription +- Create in the "VM-Deployment-Pool" Resource Group +- Use region "West Europe" +- Name the VM `SH-DEPLOYMENT-0X`(replacing `0X` a zero padded number one greater than largest one currentyl used by an existing deployment VM) +- Set the username to "atiadmin" +- Set the password from the `deployment-vm-admin-password` secret in `dsg-management-test` KeyVault in "Safe Haven Management Testing" subscription +- Open port 22 in the network settings at the bottom of the initial "Basic" configuration tab +- Select "Review + deploy" +- Deploy the VM + +### Install the latest Azure CLI +- Connect to the VM using `ssh atiadmin@sh-deployment-0X.westeurope.cloudapp.azure.com` (replacing `0X` with the zero padded number of the deployment VM you want to use and using the password from the `deployment-vm-admin-password` secret in `dsg-management-test` KeyVault in "Safe Haven Management Testing" subscription) +- Install pip via `sudo apt install python-pip -y` +- Install the Azure CLI via `pip2 install azure-cli` (system python is 2.7) +- You may need to logout of the SSH session and log in again to get `pip2` working. +- Test you can run the Azure CLI with `az`. This should print an extensive help screen. +- You may need to logout of the SSH session and log in again to get the `az` command to work +- Generate a new SSH key to authorise to read from the Safe Haven repo on Github via `ssh-keygen -t rsa -b 4096` +- Print the **public** part of the keypair to the console using `cat ~/.ssh/id_rsa.pub` +- Add this as a deploy key from the configuration tab of the safe haven repo on Github (**do not** check the "Allow write access" box - these VMs only need read access) +- Clone the safe haven repo via `git clone git@github.com:alan-turing-institute/data-safe-haven.git`. This will automatically authenticate using the VM's `id_rsa` SSH key you just created and added to the safe haven repo as a deploy key. + + +## Use a deployment VM to deploy to the Safe Haven +The VM(s) you want to use may be stopped to save money, so you may need to start the VM(s) you want to use from the Azure Portal +- Connect to the VM using `ssh atiadmin@sh-deployment-0X.westeurope.cloudapp.azure.com` (replacing `0X` with the zero padded number of the deployment VM you want to use and using the password from the `deployment-vm-admin-password` and using the password from the `deployment-vm-admin-password` secret in `dsg-management-test` KeyVault in "Safe Haven Management Testing" subscription) +- Navigate to the folder in the safe haven repo with the deployment scripts using `cd data-safe-haven/new_dsg_environment/azure-vms/` +- Checkout the deployment branch for the December 2018 Data Study Groups using `git checkout DSG-DEC2018` +- Ensure you have the latest changes locally using `git pull` +- Ensure you are authenticated in the Azure CLI using `az login` +- Deploy a new VM into a DSG environment using the `deploy_dsg_dec18.sh` script + diff --git a/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-1.yaml b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-1.yaml new file mode 100644 index 0000000000..7d2e7ed547 --- /dev/null +++ b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-1.yaml @@ -0,0 +1,215 @@ +#cloud-config +package_upgrade: false + +write_files: + - path: "/startwm.sh" + content: | + #!/bin/sh + if [ -r /etc/default/locale ]; then + . /etc/default/locale + export LANG LANGUAGE + fi + # Start xfce4 + startxfce4 + - path: "/ldap.conf" + content: | + # The distinguished name of the search base. + base LDAP_BASE_DN + + # Another way to specify your LDAP server is to provide an + uri ldap://AD_DC_NAME_LOWER.DOMAIN_LOWER:389 + + # The LDAP version to use (defaults to 3 + # if supported by client library) + ldap_version 3 + + # The distinguished name to bind to the server with + # if the effective user ID is root. Password is + # stored in /etc/ldap.secret (mode 600) + rootbinddn LDAP_BIND_DN + + # Do not hash the password at all; presume + # the directory server will do it, if + # necessary. This is the default. + pam_password md5 + - path: "/krb5.conf" + content: | + [libdefaults] + default_realm = DOMAIN_UPPER + + # The following krb5.conf variables are only for MIT Kerberos. + krb4_config = /etc/krb.conf + krb4_realms = /etc/krb.realms + kdc_timesync = 1 + ccache_type = 4 + forwardable = true + proxiable = true + + # The following libdefaults parameters are only for Heimdal Kerberos. + v4_instance_resolve = false + v4_name_convert = { + host = { + rcmd = host + ftp = ftp + } + plain = { + something = something-else + } + } + fcc-mit-ticketflags = true + + [realms] + DOMAIN_UPPER = { + kdc = AD_DC_NAME_UPPER.DOMAIN_UPPER:88 + admin_server = AD_DC_NAME_UPPER.DOMAIN_UPPER + default_domain = DOMAIN_UPPER + } + + [domain_realm] + .DOMAIN_LOWER = DOMAIN_UPPER + DOMAIN_LOWER = DOMAIN_UPPER + + [login] + krb4_convert = true + krb4_get_tickets = false + - path: "/active_directory_step01_pre" + content: | + #!/bin/sh + # Set up Active Directory + # ----------------------- + echo "Setting up Active Directory..." + # Ensure that sssd is running + echo "Ensuring that sssd is running" + systemctl status sssd.service + # Add information to hosts file + echo "Setting hostname" + echo "MACHINENAME" > /etc/hostname + cat /etc/hostname + echo "Adding MACHINENAME [$(hostname -I)] to /etc/hosts" + HOST_INFORMATION="$(hostname -I) MACHINENAME MACHINENAME.DOMAIN_LOWER" + sed -i "/127.0.0.1/ a $HOST_INFORMATION" /etc/hosts + cat /etc/hosts + # Set timezone + echo "Setting timezone" + timedatectl set-timezone Europe/London + # Create a default sssd.conf file + echo "Creating sssd config" + cp /usr/share/doc/sssd-common/examples/sssd-example.conf /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Edit LDAP config + echo "Creating LDAP config" + mv /ldap.conf /etc/ldap.conf + cat /etc/ldap.conf + # Store LDAP secret + echo "Storing LDAP secret" + echo "LDAP_SECRET_PLAINTEXT" > /etc/ldap.secret + chmod 0600 /etc/ldap.secret + # Edit Kerberos config + echo "Updating Kerberos config" + mv /krb5.conf /etc/krb5.conf + cat /etc/krb5.conf + - path: "/active_directory_step02_realm_join" + content: | + # Join the VM to the domain + echo "Joining VM to the domain" + cat /etc/ldap.secret | realm join --verbose -U LDAP_USER DOMAIN_LOWER --install=/ + - path: "/active_directory_step03_update_sssd" + content: | + # Check the sssd.conf file + echo "Updating sssd settings" + sed -i -E 's/(use_fully_qualified_names = ).*/\1False/' /etc/sssd/sssd.conf + sed -i -E 's|(fallback_homedir = ).*|\1/home/%u|' /etc/sssd/sssd.conf + sed -i -E 's/(access_provider = ).*/\1simple/' /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Restart the sssd daemon + echo "Restarting sssd" + systemctl restart sssd + - path: "/active_directory_step04_update_pam" + content: | + # Edit the pam session configuration file + echo "Updating PAM configuration" + PAM_INFORMATION="session required|pam_mkhomedir.so|skel=/etc/skel/|umask=0022" + sed "/pam_unix/ a $PAM_INFORMATION" /etc/pam.d/common-session | tr "|" "\t" > common-session + mv common-session /etc/pam.d/common-session + cat /etc/pam.d/common-session + +runcmd: + # ========================================== + # *** BEGINNING OF DSG-SPECIFIC COMMANDS *** + # Use explicit paths as cloud-init runs in /bin/sh not /bin/bash + # Upgrade pip in anticipation of using it to install some packages + - echo "Upgrading pip" + - /anaconda/envs/py27/bin/pip install --upgrade pip + - /anaconda/envs/py36/bin/pip install --upgrade pip + - /anaconda/envs/py35/bin/pip install --upgrade pip + # Install python packages: (list below) + - echo "Installing additional python packages" + - echo "*** Working on py27 environment... ***" + - export PYTHONALLPACKAGES="basemap bokeh fbprophet gensim geopandas keras matplotlib networkx numpy pandas pandas-profiling pyLDAvis pymc3 scikit-learn seaborn tsfresh" + - export PYTHON27PACKAGES="tensorflow" + - export PYTHON35PACKAGES="gpflow pygpu tensorflow-gpu" + - export PYTHON36PACKAGES="gpflow pygpu tensorflow-gpu" + # Remove packages that cause conflicts with desired packages + - echo "*** Working on py27 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON27PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py27 $PYTHONPACKAGES + # - echo "*** Working on py35 environment... ***" + # - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON35PACKAGES" + # - /anaconda/bin/conda install -y --verbose --name py35 $PYTHONPACKAGES + - echo "*** Working on py36 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON36PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py36 $PYTHONPACKAGES + # Install R packages: + - echo "Installing additional R packages" + - Rscript -e "install.packages(c('anomalize', 'caTools', 'gdata', 'gplots', 'gtools', 'here', 'KernSmooth', 'plsgenomics', 'prophet', 'janitor', 'tableone', 'wavethresh'))" + # *** END OF DSG-SPECIFIC COMMANDS *** + # ========================================== + # Create shared data folder and grant all users access + - sudo mkdir /data + - sudo chmod go+rw /data + # Make sure that sssd is running + - echo "Restart sssd service" + - service sssd restart + # Give anaconda directory to plugdev group (which all new users are a part of) and set group permissions equal to user + - echo "Change ownership of /anaconda/" + - chgrp -R plugdev /anaconda/ + - chmod -R g=u /anaconda/ + - chmod -R go-w /anaconda/ + # Set py36 as default environment when launching a new shell + - echo "Add py36 conda environment setup to global bashrc" + - echo "source activate py36" >> /etc/bash.bashrc + # Disable light-locker which can cause irritating error messages + - echo "Disable screen lock" + - echo "Hidden=true" >> /etc/xdg/autostart/light-locker.desktop + # Set default session to xfce4 + - echo "Set default session to xfce4" + - mv /startwm.sh /etc/xrdp/startwm.sh + - chmod 0755 /etc/xrdp/startwm.sh + - echo xfce4-session > ~USERNAME/.xsession + # Set default terminal for xfce + - echo "Set default xfce terminal" + - sed -i -E 's/(TerminalEmulator=).*/\1xfce4-terminal/' /etc/xdg/xfce4/helpers.rc + # Ensure that user owns their home directory + - echo "Ensure that user owns their home directory" + - chown -R USERNAME ~USERNAME + # Restart xrdp to reflect changes made above + - echo "Restart xrdp" + - service xrdp restart + # Add execute permission to the Active Directory set up scripts + - sudo chmod +x /active_directory_step01_pre + - sudo chmod +x /active_directory_step02_realm_join + - sudo chmod +x /active_directory_step03_update_sssd + - sudo chmod +x /active_directory_step04_update_pam + # Run the Active Directory set up scripts + - sudo /active_directory_step01_pre + - sudo /active_directory_step02_realm_join + - sudo /active_directory_step03_update_sssd + - sudo /active_directory_step04_update_pam + # Remove the Active Directory set up scripts (as these contain secrets and are world readable + - sudo rm /active_directory_step01_pre + - sudo rm /active_directory_step02_realm_join + - sudo rm /active_directory_step03_update_sssd + - sudo rm /active_directory_step04_update_pam + # Shutdown so that we can tell when the job has finished by polling the VM state + - shutdown -P now + diff --git a/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-2.yaml b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-2.yaml new file mode 100644 index 0000000000..7d2e7ed547 --- /dev/null +++ b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-2.yaml @@ -0,0 +1,215 @@ +#cloud-config +package_upgrade: false + +write_files: + - path: "/startwm.sh" + content: | + #!/bin/sh + if [ -r /etc/default/locale ]; then + . /etc/default/locale + export LANG LANGUAGE + fi + # Start xfce4 + startxfce4 + - path: "/ldap.conf" + content: | + # The distinguished name of the search base. + base LDAP_BASE_DN + + # Another way to specify your LDAP server is to provide an + uri ldap://AD_DC_NAME_LOWER.DOMAIN_LOWER:389 + + # The LDAP version to use (defaults to 3 + # if supported by client library) + ldap_version 3 + + # The distinguished name to bind to the server with + # if the effective user ID is root. Password is + # stored in /etc/ldap.secret (mode 600) + rootbinddn LDAP_BIND_DN + + # Do not hash the password at all; presume + # the directory server will do it, if + # necessary. This is the default. + pam_password md5 + - path: "/krb5.conf" + content: | + [libdefaults] + default_realm = DOMAIN_UPPER + + # The following krb5.conf variables are only for MIT Kerberos. + krb4_config = /etc/krb.conf + krb4_realms = /etc/krb.realms + kdc_timesync = 1 + ccache_type = 4 + forwardable = true + proxiable = true + + # The following libdefaults parameters are only for Heimdal Kerberos. + v4_instance_resolve = false + v4_name_convert = { + host = { + rcmd = host + ftp = ftp + } + plain = { + something = something-else + } + } + fcc-mit-ticketflags = true + + [realms] + DOMAIN_UPPER = { + kdc = AD_DC_NAME_UPPER.DOMAIN_UPPER:88 + admin_server = AD_DC_NAME_UPPER.DOMAIN_UPPER + default_domain = DOMAIN_UPPER + } + + [domain_realm] + .DOMAIN_LOWER = DOMAIN_UPPER + DOMAIN_LOWER = DOMAIN_UPPER + + [login] + krb4_convert = true + krb4_get_tickets = false + - path: "/active_directory_step01_pre" + content: | + #!/bin/sh + # Set up Active Directory + # ----------------------- + echo "Setting up Active Directory..." + # Ensure that sssd is running + echo "Ensuring that sssd is running" + systemctl status sssd.service + # Add information to hosts file + echo "Setting hostname" + echo "MACHINENAME" > /etc/hostname + cat /etc/hostname + echo "Adding MACHINENAME [$(hostname -I)] to /etc/hosts" + HOST_INFORMATION="$(hostname -I) MACHINENAME MACHINENAME.DOMAIN_LOWER" + sed -i "/127.0.0.1/ a $HOST_INFORMATION" /etc/hosts + cat /etc/hosts + # Set timezone + echo "Setting timezone" + timedatectl set-timezone Europe/London + # Create a default sssd.conf file + echo "Creating sssd config" + cp /usr/share/doc/sssd-common/examples/sssd-example.conf /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Edit LDAP config + echo "Creating LDAP config" + mv /ldap.conf /etc/ldap.conf + cat /etc/ldap.conf + # Store LDAP secret + echo "Storing LDAP secret" + echo "LDAP_SECRET_PLAINTEXT" > /etc/ldap.secret + chmod 0600 /etc/ldap.secret + # Edit Kerberos config + echo "Updating Kerberos config" + mv /krb5.conf /etc/krb5.conf + cat /etc/krb5.conf + - path: "/active_directory_step02_realm_join" + content: | + # Join the VM to the domain + echo "Joining VM to the domain" + cat /etc/ldap.secret | realm join --verbose -U LDAP_USER DOMAIN_LOWER --install=/ + - path: "/active_directory_step03_update_sssd" + content: | + # Check the sssd.conf file + echo "Updating sssd settings" + sed -i -E 's/(use_fully_qualified_names = ).*/\1False/' /etc/sssd/sssd.conf + sed -i -E 's|(fallback_homedir = ).*|\1/home/%u|' /etc/sssd/sssd.conf + sed -i -E 's/(access_provider = ).*/\1simple/' /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Restart the sssd daemon + echo "Restarting sssd" + systemctl restart sssd + - path: "/active_directory_step04_update_pam" + content: | + # Edit the pam session configuration file + echo "Updating PAM configuration" + PAM_INFORMATION="session required|pam_mkhomedir.so|skel=/etc/skel/|umask=0022" + sed "/pam_unix/ a $PAM_INFORMATION" /etc/pam.d/common-session | tr "|" "\t" > common-session + mv common-session /etc/pam.d/common-session + cat /etc/pam.d/common-session + +runcmd: + # ========================================== + # *** BEGINNING OF DSG-SPECIFIC COMMANDS *** + # Use explicit paths as cloud-init runs in /bin/sh not /bin/bash + # Upgrade pip in anticipation of using it to install some packages + - echo "Upgrading pip" + - /anaconda/envs/py27/bin/pip install --upgrade pip + - /anaconda/envs/py36/bin/pip install --upgrade pip + - /anaconda/envs/py35/bin/pip install --upgrade pip + # Install python packages: (list below) + - echo "Installing additional python packages" + - echo "*** Working on py27 environment... ***" + - export PYTHONALLPACKAGES="basemap bokeh fbprophet gensim geopandas keras matplotlib networkx numpy pandas pandas-profiling pyLDAvis pymc3 scikit-learn seaborn tsfresh" + - export PYTHON27PACKAGES="tensorflow" + - export PYTHON35PACKAGES="gpflow pygpu tensorflow-gpu" + - export PYTHON36PACKAGES="gpflow pygpu tensorflow-gpu" + # Remove packages that cause conflicts with desired packages + - echo "*** Working on py27 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON27PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py27 $PYTHONPACKAGES + # - echo "*** Working on py35 environment... ***" + # - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON35PACKAGES" + # - /anaconda/bin/conda install -y --verbose --name py35 $PYTHONPACKAGES + - echo "*** Working on py36 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON36PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py36 $PYTHONPACKAGES + # Install R packages: + - echo "Installing additional R packages" + - Rscript -e "install.packages(c('anomalize', 'caTools', 'gdata', 'gplots', 'gtools', 'here', 'KernSmooth', 'plsgenomics', 'prophet', 'janitor', 'tableone', 'wavethresh'))" + # *** END OF DSG-SPECIFIC COMMANDS *** + # ========================================== + # Create shared data folder and grant all users access + - sudo mkdir /data + - sudo chmod go+rw /data + # Make sure that sssd is running + - echo "Restart sssd service" + - service sssd restart + # Give anaconda directory to plugdev group (which all new users are a part of) and set group permissions equal to user + - echo "Change ownership of /anaconda/" + - chgrp -R plugdev /anaconda/ + - chmod -R g=u /anaconda/ + - chmod -R go-w /anaconda/ + # Set py36 as default environment when launching a new shell + - echo "Add py36 conda environment setup to global bashrc" + - echo "source activate py36" >> /etc/bash.bashrc + # Disable light-locker which can cause irritating error messages + - echo "Disable screen lock" + - echo "Hidden=true" >> /etc/xdg/autostart/light-locker.desktop + # Set default session to xfce4 + - echo "Set default session to xfce4" + - mv /startwm.sh /etc/xrdp/startwm.sh + - chmod 0755 /etc/xrdp/startwm.sh + - echo xfce4-session > ~USERNAME/.xsession + # Set default terminal for xfce + - echo "Set default xfce terminal" + - sed -i -E 's/(TerminalEmulator=).*/\1xfce4-terminal/' /etc/xdg/xfce4/helpers.rc + # Ensure that user owns their home directory + - echo "Ensure that user owns their home directory" + - chown -R USERNAME ~USERNAME + # Restart xrdp to reflect changes made above + - echo "Restart xrdp" + - service xrdp restart + # Add execute permission to the Active Directory set up scripts + - sudo chmod +x /active_directory_step01_pre + - sudo chmod +x /active_directory_step02_realm_join + - sudo chmod +x /active_directory_step03_update_sssd + - sudo chmod +x /active_directory_step04_update_pam + # Run the Active Directory set up scripts + - sudo /active_directory_step01_pre + - sudo /active_directory_step02_realm_join + - sudo /active_directory_step03_update_sssd + - sudo /active_directory_step04_update_pam + # Remove the Active Directory set up scripts (as these contain secrets and are world readable + - sudo rm /active_directory_step01_pre + - sudo rm /active_directory_step02_realm_join + - sudo rm /active_directory_step03_update_sssd + - sudo rm /active_directory_step04_update_pam + # Shutdown so that we can tell when the job has finished by polling the VM state + - shutdown -P now + diff --git a/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-3.yaml b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-3.yaml new file mode 100644 index 0000000000..7d2e7ed547 --- /dev/null +++ b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-3.yaml @@ -0,0 +1,215 @@ +#cloud-config +package_upgrade: false + +write_files: + - path: "/startwm.sh" + content: | + #!/bin/sh + if [ -r /etc/default/locale ]; then + . /etc/default/locale + export LANG LANGUAGE + fi + # Start xfce4 + startxfce4 + - path: "/ldap.conf" + content: | + # The distinguished name of the search base. + base LDAP_BASE_DN + + # Another way to specify your LDAP server is to provide an + uri ldap://AD_DC_NAME_LOWER.DOMAIN_LOWER:389 + + # The LDAP version to use (defaults to 3 + # if supported by client library) + ldap_version 3 + + # The distinguished name to bind to the server with + # if the effective user ID is root. Password is + # stored in /etc/ldap.secret (mode 600) + rootbinddn LDAP_BIND_DN + + # Do not hash the password at all; presume + # the directory server will do it, if + # necessary. This is the default. + pam_password md5 + - path: "/krb5.conf" + content: | + [libdefaults] + default_realm = DOMAIN_UPPER + + # The following krb5.conf variables are only for MIT Kerberos. + krb4_config = /etc/krb.conf + krb4_realms = /etc/krb.realms + kdc_timesync = 1 + ccache_type = 4 + forwardable = true + proxiable = true + + # The following libdefaults parameters are only for Heimdal Kerberos. + v4_instance_resolve = false + v4_name_convert = { + host = { + rcmd = host + ftp = ftp + } + plain = { + something = something-else + } + } + fcc-mit-ticketflags = true + + [realms] + DOMAIN_UPPER = { + kdc = AD_DC_NAME_UPPER.DOMAIN_UPPER:88 + admin_server = AD_DC_NAME_UPPER.DOMAIN_UPPER + default_domain = DOMAIN_UPPER + } + + [domain_realm] + .DOMAIN_LOWER = DOMAIN_UPPER + DOMAIN_LOWER = DOMAIN_UPPER + + [login] + krb4_convert = true + krb4_get_tickets = false + - path: "/active_directory_step01_pre" + content: | + #!/bin/sh + # Set up Active Directory + # ----------------------- + echo "Setting up Active Directory..." + # Ensure that sssd is running + echo "Ensuring that sssd is running" + systemctl status sssd.service + # Add information to hosts file + echo "Setting hostname" + echo "MACHINENAME" > /etc/hostname + cat /etc/hostname + echo "Adding MACHINENAME [$(hostname -I)] to /etc/hosts" + HOST_INFORMATION="$(hostname -I) MACHINENAME MACHINENAME.DOMAIN_LOWER" + sed -i "/127.0.0.1/ a $HOST_INFORMATION" /etc/hosts + cat /etc/hosts + # Set timezone + echo "Setting timezone" + timedatectl set-timezone Europe/London + # Create a default sssd.conf file + echo "Creating sssd config" + cp /usr/share/doc/sssd-common/examples/sssd-example.conf /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Edit LDAP config + echo "Creating LDAP config" + mv /ldap.conf /etc/ldap.conf + cat /etc/ldap.conf + # Store LDAP secret + echo "Storing LDAP secret" + echo "LDAP_SECRET_PLAINTEXT" > /etc/ldap.secret + chmod 0600 /etc/ldap.secret + # Edit Kerberos config + echo "Updating Kerberos config" + mv /krb5.conf /etc/krb5.conf + cat /etc/krb5.conf + - path: "/active_directory_step02_realm_join" + content: | + # Join the VM to the domain + echo "Joining VM to the domain" + cat /etc/ldap.secret | realm join --verbose -U LDAP_USER DOMAIN_LOWER --install=/ + - path: "/active_directory_step03_update_sssd" + content: | + # Check the sssd.conf file + echo "Updating sssd settings" + sed -i -E 's/(use_fully_qualified_names = ).*/\1False/' /etc/sssd/sssd.conf + sed -i -E 's|(fallback_homedir = ).*|\1/home/%u|' /etc/sssd/sssd.conf + sed -i -E 's/(access_provider = ).*/\1simple/' /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Restart the sssd daemon + echo "Restarting sssd" + systemctl restart sssd + - path: "/active_directory_step04_update_pam" + content: | + # Edit the pam session configuration file + echo "Updating PAM configuration" + PAM_INFORMATION="session required|pam_mkhomedir.so|skel=/etc/skel/|umask=0022" + sed "/pam_unix/ a $PAM_INFORMATION" /etc/pam.d/common-session | tr "|" "\t" > common-session + mv common-session /etc/pam.d/common-session + cat /etc/pam.d/common-session + +runcmd: + # ========================================== + # *** BEGINNING OF DSG-SPECIFIC COMMANDS *** + # Use explicit paths as cloud-init runs in /bin/sh not /bin/bash + # Upgrade pip in anticipation of using it to install some packages + - echo "Upgrading pip" + - /anaconda/envs/py27/bin/pip install --upgrade pip + - /anaconda/envs/py36/bin/pip install --upgrade pip + - /anaconda/envs/py35/bin/pip install --upgrade pip + # Install python packages: (list below) + - echo "Installing additional python packages" + - echo "*** Working on py27 environment... ***" + - export PYTHONALLPACKAGES="basemap bokeh fbprophet gensim geopandas keras matplotlib networkx numpy pandas pandas-profiling pyLDAvis pymc3 scikit-learn seaborn tsfresh" + - export PYTHON27PACKAGES="tensorflow" + - export PYTHON35PACKAGES="gpflow pygpu tensorflow-gpu" + - export PYTHON36PACKAGES="gpflow pygpu tensorflow-gpu" + # Remove packages that cause conflicts with desired packages + - echo "*** Working on py27 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON27PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py27 $PYTHONPACKAGES + # - echo "*** Working on py35 environment... ***" + # - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON35PACKAGES" + # - /anaconda/bin/conda install -y --verbose --name py35 $PYTHONPACKAGES + - echo "*** Working on py36 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON36PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py36 $PYTHONPACKAGES + # Install R packages: + - echo "Installing additional R packages" + - Rscript -e "install.packages(c('anomalize', 'caTools', 'gdata', 'gplots', 'gtools', 'here', 'KernSmooth', 'plsgenomics', 'prophet', 'janitor', 'tableone', 'wavethresh'))" + # *** END OF DSG-SPECIFIC COMMANDS *** + # ========================================== + # Create shared data folder and grant all users access + - sudo mkdir /data + - sudo chmod go+rw /data + # Make sure that sssd is running + - echo "Restart sssd service" + - service sssd restart + # Give anaconda directory to plugdev group (which all new users are a part of) and set group permissions equal to user + - echo "Change ownership of /anaconda/" + - chgrp -R plugdev /anaconda/ + - chmod -R g=u /anaconda/ + - chmod -R go-w /anaconda/ + # Set py36 as default environment when launching a new shell + - echo "Add py36 conda environment setup to global bashrc" + - echo "source activate py36" >> /etc/bash.bashrc + # Disable light-locker which can cause irritating error messages + - echo "Disable screen lock" + - echo "Hidden=true" >> /etc/xdg/autostart/light-locker.desktop + # Set default session to xfce4 + - echo "Set default session to xfce4" + - mv /startwm.sh /etc/xrdp/startwm.sh + - chmod 0755 /etc/xrdp/startwm.sh + - echo xfce4-session > ~USERNAME/.xsession + # Set default terminal for xfce + - echo "Set default xfce terminal" + - sed -i -E 's/(TerminalEmulator=).*/\1xfce4-terminal/' /etc/xdg/xfce4/helpers.rc + # Ensure that user owns their home directory + - echo "Ensure that user owns their home directory" + - chown -R USERNAME ~USERNAME + # Restart xrdp to reflect changes made above + - echo "Restart xrdp" + - service xrdp restart + # Add execute permission to the Active Directory set up scripts + - sudo chmod +x /active_directory_step01_pre + - sudo chmod +x /active_directory_step02_realm_join + - sudo chmod +x /active_directory_step03_update_sssd + - sudo chmod +x /active_directory_step04_update_pam + # Run the Active Directory set up scripts + - sudo /active_directory_step01_pre + - sudo /active_directory_step02_realm_join + - sudo /active_directory_step03_update_sssd + - sudo /active_directory_step04_update_pam + # Remove the Active Directory set up scripts (as these contain secrets and are world readable + - sudo rm /active_directory_step01_pre + - sudo rm /active_directory_step02_realm_join + - sudo rm /active_directory_step03_update_sssd + - sudo rm /active_directory_step04_update_pam + # Shutdown so that we can tell when the job has finished by polling the VM state + - shutdown -P now + diff --git a/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-4.yaml b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-4.yaml new file mode 100644 index 0000000000..8a124b6636 --- /dev/null +++ b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-4.yaml @@ -0,0 +1,217 @@ +#cloud-config +package_upgrade: false + +write_files: + - path: "/startwm.sh" + content: | + #!/bin/sh + if [ -r /etc/default/locale ]; then + . /etc/default/locale + export LANG LANGUAGE + fi + # Start xfce4 + startxfce4 + - path: "/ldap.conf" + content: | + # The distinguished name of the search base. + base LDAP_BASE_DN + + # Another way to specify your LDAP server is to provide an + uri ldap://AD_DC_NAME_LOWER.DOMAIN_LOWER:389 + + # The LDAP version to use (defaults to 3 + # if supported by client library) + ldap_version 3 + + # The distinguished name to bind to the server with + # if the effective user ID is root. Password is + # stored in /etc/ldap.secret (mode 600) + rootbinddn LDAP_BIND_DN + + # Do not hash the password at all; presume + # the directory server will do it, if + # necessary. This is the default. + pam_password md5 + - path: "/krb5.conf" + content: | + [libdefaults] + default_realm = DOMAIN_UPPER + + # The following krb5.conf variables are only for MIT Kerberos. + krb4_config = /etc/krb.conf + krb4_realms = /etc/krb.realms + kdc_timesync = 1 + ccache_type = 4 + forwardable = true + proxiable = true + + # The following libdefaults parameters are only for Heimdal Kerberos. + v4_instance_resolve = false + v4_name_convert = { + host = { + rcmd = host + ftp = ftp + } + plain = { + something = something-else + } + } + fcc-mit-ticketflags = true + + [realms] + DOMAIN_UPPER = { + kdc = AD_DC_NAME_UPPER.DOMAIN_UPPER:88 + admin_server = AD_DC_NAME_UPPER.DOMAIN_UPPER + default_domain = DOMAIN_UPPER + } + + [domain_realm] + .DOMAIN_LOWER = DOMAIN_UPPER + DOMAIN_LOWER = DOMAIN_UPPER + + [login] + krb4_convert = true + krb4_get_tickets = false + - path: "/active_directory_step01_pre" + content: | + #!/bin/sh + # Set up Active Directory + # ----------------------- + echo "Setting up Active Directory..." + # Ensure that sssd is running + echo "Ensuring that sssd is running" + systemctl status sssd.service + # Add information to hosts file + echo "Setting hostname" + echo "MACHINENAME" > /etc/hostname + cat /etc/hostname + echo "Adding MACHINENAME [$(hostname -I)] to /etc/hosts" + HOST_INFORMATION="$(hostname -I) MACHINENAME MACHINENAME.DOMAIN_LOWER" + sed -i "/127.0.0.1/ a $HOST_INFORMATION" /etc/hosts + cat /etc/hosts + # Set timezone + echo "Setting timezone" + timedatectl set-timezone Europe/London + # Create a default sssd.conf file + echo "Creating sssd config" + cp /usr/share/doc/sssd-common/examples/sssd-example.conf /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Edit LDAP config + echo "Creating LDAP config" + mv /ldap.conf /etc/ldap.conf + cat /etc/ldap.conf + # Store LDAP secret + echo "Storing LDAP secret" + echo "LDAP_SECRET_PLAINTEXT" > /etc/ldap.secret + chmod 0600 /etc/ldap.secret + # Edit Kerberos config + echo "Updating Kerberos config" + mv /krb5.conf /etc/krb5.conf + cat /etc/krb5.conf + - path: "/active_directory_step02_realm_join" + content: | + # Join the VM to the domain + echo "Joining VM to the domain" + cat /etc/ldap.secret | realm join --verbose -U LDAP_USER DOMAIN_LOWER --install=/ + - path: "/active_directory_step03_update_sssd" + content: | + # Check the sssd.conf file + echo "Updating sssd settings" + sed -i -E 's/(use_fully_qualified_names = ).*/\1False/' /etc/sssd/sssd.conf + sed -i -E 's|(fallback_homedir = ).*|\1/home/%u|' /etc/sssd/sssd.conf + sed -i -E 's/(access_provider = ).*/\1simple/' /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Restart the sssd daemon + echo "Restarting sssd" + systemctl restart sssd + - path: "/active_directory_step04_update_pam" + content: | + # Edit the pam session configuration file + echo "Updating PAM configuration" + PAM_INFORMATION="session required|pam_mkhomedir.so|skel=/etc/skel/|umask=0022" + sed "/pam_unix/ a $PAM_INFORMATION" /etc/pam.d/common-session | tr "|" "\t" > common-session + mv common-session /etc/pam.d/common-session + cat /etc/pam.d/common-session + +runcmd: + # ========================================== + # *** BEGINNING OF DSG-SPECIFIC COMMANDS *** + # Use explicit paths as cloud-init runs in /bin/sh not /bin/bash + # Upgrade pip in anticipation of using it to install some packages + - echo "Upgrading pip" + - /anaconda/envs/py27/bin/pip install --upgrade pip + - /anaconda/envs/py36/bin/pip install --upgrade pip + - /anaconda/envs/py35/bin/pip install --upgrade pip + # Install python packages: (list below) + - echo "Installing additional python packages" + - echo "*** Working on py27 environment... ***" + - export PYTHONALLPACKAGES="basemap bokeh fbprophet gensim geopandas keras matplotlib networkx numpy pandas pandas-profiling pyLDAvis pymc3 scikit-learn seaborn tsfresh" + - export PYTHON27PACKAGES="tensorflow" + - export PYTHON35PACKAGES="gpflow pygpu pyopengl pyopengl-accelerate tensorflow-gpu" + - export PYTHON36PACKAGES="gpflow pygpu pyopengl pyopengl-accelerate tensorflow-gpu" + # Remove packages that cause conflicts with desired packages + - echo "*** Working on py27 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON27PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py27 $PYTHONPACKAGES + # - echo "*** Working on py35 environment... ***" + # - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON35PACKAGES" + # - /anaconda/bin/conda install -y --verbose --name py35 $PYTHONPACKAGES + # - /anaconda/envs/py35/bin/pip install bluesky-simulator + - echo "*** Working on py36 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON36PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py36 $PYTHONPACKAGES + - /anaconda/envs/py36/bin/pip install bluesky-simulator + # Install R packages: + - echo "Installing additional R packages" + - Rscript -e "install.packages(c('anomalize', 'caTools', 'gdata', 'gplots', 'gtools', 'here', 'KernSmooth', 'plsgenomics', 'prophet', 'janitor', 'tableone', 'wavethresh'))" + # *** END OF DSG-SPECIFIC COMMANDS *** + # ========================================== + # Create shared data folder and grant all users access + - sudo mkdir /data + - sudo chmod go+rw /data + # Make sure that sssd is running + - echo "Restart sssd service" + - service sssd restart + # Give anaconda directory to plugdev group (which all new users are a part of) and set group permissions equal to user + - echo "Change ownership of /anaconda/" + - chgrp -R plugdev /anaconda/ + - chmod -R g=u /anaconda/ + - chmod -R go-w /anaconda/ + # Set py36 as default environment when launching a new shell + - echo "Add py36 conda environment setup to global bashrc" + - echo "source activate py36" >> /etc/bash.bashrc + # Disable light-locker which can cause irritating error messages + - echo "Disable screen lock" + - echo "Hidden=true" >> /etc/xdg/autostart/light-locker.desktop + # Set default session to xfce4 + - echo "Set default session to xfce4" + - mv /startwm.sh /etc/xrdp/startwm.sh + - chmod 0755 /etc/xrdp/startwm.sh + - echo xfce4-session > ~USERNAME/.xsession + # Set default terminal for xfce + - echo "Set default xfce terminal" + - sed -i -E 's/(TerminalEmulator=).*/\1xfce4-terminal/' /etc/xdg/xfce4/helpers.rc + # Ensure that user owns their home directory + - echo "Ensure that user owns their home directory" + - chown -R USERNAME ~USERNAME + # Restart xrdp to reflect changes made above + - echo "Restart xrdp" + - service xrdp restart + # Add execute permission to the Active Directory set up scripts + - sudo chmod +x /active_directory_step01_pre + - sudo chmod +x /active_directory_step02_realm_join + - sudo chmod +x /active_directory_step03_update_sssd + - sudo chmod +x /active_directory_step04_update_pam + # Run the Active Directory set up scripts + - sudo /active_directory_step01_pre + - sudo /active_directory_step02_realm_join + - sudo /active_directory_step03_update_sssd + - sudo /active_directory_step04_update_pam + # Remove the Active Directory set up scripts (as these contain secrets and are world readable + - sudo rm /active_directory_step01_pre + - sudo rm /active_directory_step02_realm_join + - sudo rm /active_directory_step03_update_sssd + - sudo rm /active_directory_step04_update_pam + # Shutdown so that we can tell when the job has finished by polling the VM state + - shutdown -P now + diff --git a/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-6.yaml b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-6.yaml new file mode 100644 index 0000000000..7d2e7ed547 --- /dev/null +++ b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-6.yaml @@ -0,0 +1,215 @@ +#cloud-config +package_upgrade: false + +write_files: + - path: "/startwm.sh" + content: | + #!/bin/sh + if [ -r /etc/default/locale ]; then + . /etc/default/locale + export LANG LANGUAGE + fi + # Start xfce4 + startxfce4 + - path: "/ldap.conf" + content: | + # The distinguished name of the search base. + base LDAP_BASE_DN + + # Another way to specify your LDAP server is to provide an + uri ldap://AD_DC_NAME_LOWER.DOMAIN_LOWER:389 + + # The LDAP version to use (defaults to 3 + # if supported by client library) + ldap_version 3 + + # The distinguished name to bind to the server with + # if the effective user ID is root. Password is + # stored in /etc/ldap.secret (mode 600) + rootbinddn LDAP_BIND_DN + + # Do not hash the password at all; presume + # the directory server will do it, if + # necessary. This is the default. + pam_password md5 + - path: "/krb5.conf" + content: | + [libdefaults] + default_realm = DOMAIN_UPPER + + # The following krb5.conf variables are only for MIT Kerberos. + krb4_config = /etc/krb.conf + krb4_realms = /etc/krb.realms + kdc_timesync = 1 + ccache_type = 4 + forwardable = true + proxiable = true + + # The following libdefaults parameters are only for Heimdal Kerberos. + v4_instance_resolve = false + v4_name_convert = { + host = { + rcmd = host + ftp = ftp + } + plain = { + something = something-else + } + } + fcc-mit-ticketflags = true + + [realms] + DOMAIN_UPPER = { + kdc = AD_DC_NAME_UPPER.DOMAIN_UPPER:88 + admin_server = AD_DC_NAME_UPPER.DOMAIN_UPPER + default_domain = DOMAIN_UPPER + } + + [domain_realm] + .DOMAIN_LOWER = DOMAIN_UPPER + DOMAIN_LOWER = DOMAIN_UPPER + + [login] + krb4_convert = true + krb4_get_tickets = false + - path: "/active_directory_step01_pre" + content: | + #!/bin/sh + # Set up Active Directory + # ----------------------- + echo "Setting up Active Directory..." + # Ensure that sssd is running + echo "Ensuring that sssd is running" + systemctl status sssd.service + # Add information to hosts file + echo "Setting hostname" + echo "MACHINENAME" > /etc/hostname + cat /etc/hostname + echo "Adding MACHINENAME [$(hostname -I)] to /etc/hosts" + HOST_INFORMATION="$(hostname -I) MACHINENAME MACHINENAME.DOMAIN_LOWER" + sed -i "/127.0.0.1/ a $HOST_INFORMATION" /etc/hosts + cat /etc/hosts + # Set timezone + echo "Setting timezone" + timedatectl set-timezone Europe/London + # Create a default sssd.conf file + echo "Creating sssd config" + cp /usr/share/doc/sssd-common/examples/sssd-example.conf /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Edit LDAP config + echo "Creating LDAP config" + mv /ldap.conf /etc/ldap.conf + cat /etc/ldap.conf + # Store LDAP secret + echo "Storing LDAP secret" + echo "LDAP_SECRET_PLAINTEXT" > /etc/ldap.secret + chmod 0600 /etc/ldap.secret + # Edit Kerberos config + echo "Updating Kerberos config" + mv /krb5.conf /etc/krb5.conf + cat /etc/krb5.conf + - path: "/active_directory_step02_realm_join" + content: | + # Join the VM to the domain + echo "Joining VM to the domain" + cat /etc/ldap.secret | realm join --verbose -U LDAP_USER DOMAIN_LOWER --install=/ + - path: "/active_directory_step03_update_sssd" + content: | + # Check the sssd.conf file + echo "Updating sssd settings" + sed -i -E 's/(use_fully_qualified_names = ).*/\1False/' /etc/sssd/sssd.conf + sed -i -E 's|(fallback_homedir = ).*|\1/home/%u|' /etc/sssd/sssd.conf + sed -i -E 's/(access_provider = ).*/\1simple/' /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Restart the sssd daemon + echo "Restarting sssd" + systemctl restart sssd + - path: "/active_directory_step04_update_pam" + content: | + # Edit the pam session configuration file + echo "Updating PAM configuration" + PAM_INFORMATION="session required|pam_mkhomedir.so|skel=/etc/skel/|umask=0022" + sed "/pam_unix/ a $PAM_INFORMATION" /etc/pam.d/common-session | tr "|" "\t" > common-session + mv common-session /etc/pam.d/common-session + cat /etc/pam.d/common-session + +runcmd: + # ========================================== + # *** BEGINNING OF DSG-SPECIFIC COMMANDS *** + # Use explicit paths as cloud-init runs in /bin/sh not /bin/bash + # Upgrade pip in anticipation of using it to install some packages + - echo "Upgrading pip" + - /anaconda/envs/py27/bin/pip install --upgrade pip + - /anaconda/envs/py36/bin/pip install --upgrade pip + - /anaconda/envs/py35/bin/pip install --upgrade pip + # Install python packages: (list below) + - echo "Installing additional python packages" + - echo "*** Working on py27 environment... ***" + - export PYTHONALLPACKAGES="basemap bokeh fbprophet gensim geopandas keras matplotlib networkx numpy pandas pandas-profiling pyLDAvis pymc3 scikit-learn seaborn tsfresh" + - export PYTHON27PACKAGES="tensorflow" + - export PYTHON35PACKAGES="gpflow pygpu tensorflow-gpu" + - export PYTHON36PACKAGES="gpflow pygpu tensorflow-gpu" + # Remove packages that cause conflicts with desired packages + - echo "*** Working on py27 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON27PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py27 $PYTHONPACKAGES + # - echo "*** Working on py35 environment... ***" + # - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON35PACKAGES" + # - /anaconda/bin/conda install -y --verbose --name py35 $PYTHONPACKAGES + - echo "*** Working on py36 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON36PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py36 $PYTHONPACKAGES + # Install R packages: + - echo "Installing additional R packages" + - Rscript -e "install.packages(c('anomalize', 'caTools', 'gdata', 'gplots', 'gtools', 'here', 'KernSmooth', 'plsgenomics', 'prophet', 'janitor', 'tableone', 'wavethresh'))" + # *** END OF DSG-SPECIFIC COMMANDS *** + # ========================================== + # Create shared data folder and grant all users access + - sudo mkdir /data + - sudo chmod go+rw /data + # Make sure that sssd is running + - echo "Restart sssd service" + - service sssd restart + # Give anaconda directory to plugdev group (which all new users are a part of) and set group permissions equal to user + - echo "Change ownership of /anaconda/" + - chgrp -R plugdev /anaconda/ + - chmod -R g=u /anaconda/ + - chmod -R go-w /anaconda/ + # Set py36 as default environment when launching a new shell + - echo "Add py36 conda environment setup to global bashrc" + - echo "source activate py36" >> /etc/bash.bashrc + # Disable light-locker which can cause irritating error messages + - echo "Disable screen lock" + - echo "Hidden=true" >> /etc/xdg/autostart/light-locker.desktop + # Set default session to xfce4 + - echo "Set default session to xfce4" + - mv /startwm.sh /etc/xrdp/startwm.sh + - chmod 0755 /etc/xrdp/startwm.sh + - echo xfce4-session > ~USERNAME/.xsession + # Set default terminal for xfce + - echo "Set default xfce terminal" + - sed -i -E 's/(TerminalEmulator=).*/\1xfce4-terminal/' /etc/xdg/xfce4/helpers.rc + # Ensure that user owns their home directory + - echo "Ensure that user owns their home directory" + - chown -R USERNAME ~USERNAME + # Restart xrdp to reflect changes made above + - echo "Restart xrdp" + - service xrdp restart + # Add execute permission to the Active Directory set up scripts + - sudo chmod +x /active_directory_step01_pre + - sudo chmod +x /active_directory_step02_realm_join + - sudo chmod +x /active_directory_step03_update_sssd + - sudo chmod +x /active_directory_step04_update_pam + # Run the Active Directory set up scripts + - sudo /active_directory_step01_pre + - sudo /active_directory_step02_realm_join + - sudo /active_directory_step03_update_sssd + - sudo /active_directory_step04_update_pam + # Remove the Active Directory set up scripts (as these contain secrets and are world readable + - sudo rm /active_directory_step01_pre + - sudo rm /active_directory_step02_realm_join + - sudo rm /active_directory_step03_update_sssd + - sudo rm /active_directory_step04_update_pam + # Shutdown so that we can tell when the job has finished by polling the VM state + - shutdown -P now + diff --git a/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-TEST.yaml b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-TEST.yaml new file mode 100644 index 0000000000..8a124b6636 --- /dev/null +++ b/new_dsg_environment/azure-vms/DSG2018/cloud-init-compute-vm-DSG-TEST.yaml @@ -0,0 +1,217 @@ +#cloud-config +package_upgrade: false + +write_files: + - path: "/startwm.sh" + content: | + #!/bin/sh + if [ -r /etc/default/locale ]; then + . /etc/default/locale + export LANG LANGUAGE + fi + # Start xfce4 + startxfce4 + - path: "/ldap.conf" + content: | + # The distinguished name of the search base. + base LDAP_BASE_DN + + # Another way to specify your LDAP server is to provide an + uri ldap://AD_DC_NAME_LOWER.DOMAIN_LOWER:389 + + # The LDAP version to use (defaults to 3 + # if supported by client library) + ldap_version 3 + + # The distinguished name to bind to the server with + # if the effective user ID is root. Password is + # stored in /etc/ldap.secret (mode 600) + rootbinddn LDAP_BIND_DN + + # Do not hash the password at all; presume + # the directory server will do it, if + # necessary. This is the default. + pam_password md5 + - path: "/krb5.conf" + content: | + [libdefaults] + default_realm = DOMAIN_UPPER + + # The following krb5.conf variables are only for MIT Kerberos. + krb4_config = /etc/krb.conf + krb4_realms = /etc/krb.realms + kdc_timesync = 1 + ccache_type = 4 + forwardable = true + proxiable = true + + # The following libdefaults parameters are only for Heimdal Kerberos. + v4_instance_resolve = false + v4_name_convert = { + host = { + rcmd = host + ftp = ftp + } + plain = { + something = something-else + } + } + fcc-mit-ticketflags = true + + [realms] + DOMAIN_UPPER = { + kdc = AD_DC_NAME_UPPER.DOMAIN_UPPER:88 + admin_server = AD_DC_NAME_UPPER.DOMAIN_UPPER + default_domain = DOMAIN_UPPER + } + + [domain_realm] + .DOMAIN_LOWER = DOMAIN_UPPER + DOMAIN_LOWER = DOMAIN_UPPER + + [login] + krb4_convert = true + krb4_get_tickets = false + - path: "/active_directory_step01_pre" + content: | + #!/bin/sh + # Set up Active Directory + # ----------------------- + echo "Setting up Active Directory..." + # Ensure that sssd is running + echo "Ensuring that sssd is running" + systemctl status sssd.service + # Add information to hosts file + echo "Setting hostname" + echo "MACHINENAME" > /etc/hostname + cat /etc/hostname + echo "Adding MACHINENAME [$(hostname -I)] to /etc/hosts" + HOST_INFORMATION="$(hostname -I) MACHINENAME MACHINENAME.DOMAIN_LOWER" + sed -i "/127.0.0.1/ a $HOST_INFORMATION" /etc/hosts + cat /etc/hosts + # Set timezone + echo "Setting timezone" + timedatectl set-timezone Europe/London + # Create a default sssd.conf file + echo "Creating sssd config" + cp /usr/share/doc/sssd-common/examples/sssd-example.conf /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Edit LDAP config + echo "Creating LDAP config" + mv /ldap.conf /etc/ldap.conf + cat /etc/ldap.conf + # Store LDAP secret + echo "Storing LDAP secret" + echo "LDAP_SECRET_PLAINTEXT" > /etc/ldap.secret + chmod 0600 /etc/ldap.secret + # Edit Kerberos config + echo "Updating Kerberos config" + mv /krb5.conf /etc/krb5.conf + cat /etc/krb5.conf + - path: "/active_directory_step02_realm_join" + content: | + # Join the VM to the domain + echo "Joining VM to the domain" + cat /etc/ldap.secret | realm join --verbose -U LDAP_USER DOMAIN_LOWER --install=/ + - path: "/active_directory_step03_update_sssd" + content: | + # Check the sssd.conf file + echo "Updating sssd settings" + sed -i -E 's/(use_fully_qualified_names = ).*/\1False/' /etc/sssd/sssd.conf + sed -i -E 's|(fallback_homedir = ).*|\1/home/%u|' /etc/sssd/sssd.conf + sed -i -E 's/(access_provider = ).*/\1simple/' /etc/sssd/sssd.conf + cat /etc/sssd/sssd.conf + # Restart the sssd daemon + echo "Restarting sssd" + systemctl restart sssd + - path: "/active_directory_step04_update_pam" + content: | + # Edit the pam session configuration file + echo "Updating PAM configuration" + PAM_INFORMATION="session required|pam_mkhomedir.so|skel=/etc/skel/|umask=0022" + sed "/pam_unix/ a $PAM_INFORMATION" /etc/pam.d/common-session | tr "|" "\t" > common-session + mv common-session /etc/pam.d/common-session + cat /etc/pam.d/common-session + +runcmd: + # ========================================== + # *** BEGINNING OF DSG-SPECIFIC COMMANDS *** + # Use explicit paths as cloud-init runs in /bin/sh not /bin/bash + # Upgrade pip in anticipation of using it to install some packages + - echo "Upgrading pip" + - /anaconda/envs/py27/bin/pip install --upgrade pip + - /anaconda/envs/py36/bin/pip install --upgrade pip + - /anaconda/envs/py35/bin/pip install --upgrade pip + # Install python packages: (list below) + - echo "Installing additional python packages" + - echo "*** Working on py27 environment... ***" + - export PYTHONALLPACKAGES="basemap bokeh fbprophet gensim geopandas keras matplotlib networkx numpy pandas pandas-profiling pyLDAvis pymc3 scikit-learn seaborn tsfresh" + - export PYTHON27PACKAGES="tensorflow" + - export PYTHON35PACKAGES="gpflow pygpu pyopengl pyopengl-accelerate tensorflow-gpu" + - export PYTHON36PACKAGES="gpflow pygpu pyopengl pyopengl-accelerate tensorflow-gpu" + # Remove packages that cause conflicts with desired packages + - echo "*** Working on py27 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON27PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py27 $PYTHONPACKAGES + # - echo "*** Working on py35 environment... ***" + # - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON35PACKAGES" + # - /anaconda/bin/conda install -y --verbose --name py35 $PYTHONPACKAGES + # - /anaconda/envs/py35/bin/pip install bluesky-simulator + - echo "*** Working on py36 environment... ***" + - export PYTHONPACKAGES="$PYTHONALLPACKAGES $PYTHON36PACKAGES" + - /anaconda/bin/conda install -y --verbose --name py36 $PYTHONPACKAGES + - /anaconda/envs/py36/bin/pip install bluesky-simulator + # Install R packages: + - echo "Installing additional R packages" + - Rscript -e "install.packages(c('anomalize', 'caTools', 'gdata', 'gplots', 'gtools', 'here', 'KernSmooth', 'plsgenomics', 'prophet', 'janitor', 'tableone', 'wavethresh'))" + # *** END OF DSG-SPECIFIC COMMANDS *** + # ========================================== + # Create shared data folder and grant all users access + - sudo mkdir /data + - sudo chmod go+rw /data + # Make sure that sssd is running + - echo "Restart sssd service" + - service sssd restart + # Give anaconda directory to plugdev group (which all new users are a part of) and set group permissions equal to user + - echo "Change ownership of /anaconda/" + - chgrp -R plugdev /anaconda/ + - chmod -R g=u /anaconda/ + - chmod -R go-w /anaconda/ + # Set py36 as default environment when launching a new shell + - echo "Add py36 conda environment setup to global bashrc" + - echo "source activate py36" >> /etc/bash.bashrc + # Disable light-locker which can cause irritating error messages + - echo "Disable screen lock" + - echo "Hidden=true" >> /etc/xdg/autostart/light-locker.desktop + # Set default session to xfce4 + - echo "Set default session to xfce4" + - mv /startwm.sh /etc/xrdp/startwm.sh + - chmod 0755 /etc/xrdp/startwm.sh + - echo xfce4-session > ~USERNAME/.xsession + # Set default terminal for xfce + - echo "Set default xfce terminal" + - sed -i -E 's/(TerminalEmulator=).*/\1xfce4-terminal/' /etc/xdg/xfce4/helpers.rc + # Ensure that user owns their home directory + - echo "Ensure that user owns their home directory" + - chown -R USERNAME ~USERNAME + # Restart xrdp to reflect changes made above + - echo "Restart xrdp" + - service xrdp restart + # Add execute permission to the Active Directory set up scripts + - sudo chmod +x /active_directory_step01_pre + - sudo chmod +x /active_directory_step02_realm_join + - sudo chmod +x /active_directory_step03_update_sssd + - sudo chmod +x /active_directory_step04_update_pam + # Run the Active Directory set up scripts + - sudo /active_directory_step01_pre + - sudo /active_directory_step02_realm_join + - sudo /active_directory_step03_update_sssd + - sudo /active_directory_step04_update_pam + # Remove the Active Directory set up scripts (as these contain secrets and are world readable + - sudo rm /active_directory_step01_pre + - sudo rm /active_directory_step02_realm_join + - sudo rm /active_directory_step03_update_sssd + - sudo rm /active_directory_step04_update_pam + # Shutdown so that we can tell when the job has finished by polling the VM state + - shutdown -P now + diff --git a/new_dsg_environment/azure-vms/README.md b/new_dsg_environment/azure-vms/README.md index ac0d5fd0aa..9e3c4f1bf5 100644 --- a/new_dsg_environment/azure-vms/README.md +++ b/new_dsg_environment/azure-vms/README.md @@ -68,18 +68,25 @@ This deploys from an image stored in a gallery in `subscription_source` into a r This deployment should be into a pre-created environment, so the `nsg_name`, `vnet_name` and `subnet_name` must all exist before this script is run. ``` -usage: deploy_azure_dsg_vm.sh -s subscription_source -t subscription_target [-h] [-g nsg_name] [-i source_image] [-n machine_name] [-r resource_group] [-u user_name] +usage: ./deploy_azure_dsg_vm.sh -s subscription_source -t subscription_target [-h] [-g nsg_name] [-i source_image] [-x source_image_version] [-n machine_name] [-r resource_group] [-u user_name] -h display help -g nsg_name specify which NSG to connect to (defaults to 'NSG_Linux_Servers') - -i source_image specify source_image: either 'Ubuntu' (default) or 'DataScience' - -n machine_name specify name of created VM, which must be unique in this resource group (defaults to 'DSGComputeMachineVM') - -r resource_group specify resource group for deploying the VM image - will be created if it does not already exist (defaults tG_TEST') + -i source_image specify source_image: either 'Ubuntu' (default) 'UbuntuTorch' (as default but with Torch included) or 'DataScience' + -x source_image_version specify the version of the source image to use (defaults to prompting to select from available versions) + -n machine_name specify name of created VM, which must be unique in this resource group (defaults to 'DSGYYYYMMDDHHMM') + -r resource_group specify resource group for deploying the VM image - will be created if it does not already exist (defaults to 'RG_DSG_COMPUTE') -u user_name specify a username for the admin account (defaults to 'atiadmin') -s subscription_source specify source subscription that images are taken from [required]. (Test using 'Safe Haven Management Testing') -t subscription_target specify target subscription for deploying the VM image [required]. (Test using 'Data Study Group Testing') -v vnet_name specify a VNET to connect to (defaults to 'DSG_DSGROUPTEST_VNet1') -w subnet_name specify a subnet to connect to (defaults to 'Subnet-Data') -z vm_size specify a VM size to use (defaults to 'Standard_DS2_v2') + -m management_vault_name specify name of KeyVault containing management secrets (required) + -l ldap_secret_name specify name of KeyVault secret containing LDAP secret (required) + -j ldap_user specify the LDAP user (required) + -p password_secret_name specify name of KeyVault secret containing VM admin password (required) + -d domain specify domain name for safe haven (required) + ``` Example usage @@ -88,4 +95,4 @@ Example usage ./deploy_azure_dsg_vm.sh -s "Safe Haven Management Testing" -t "Data Study Group Testing" -i Ubuntu -r RS_DSG_TEST ``` - +For monitoring deployments without SSH access, enable "Boot Diagnostics" for that VM through the Azure portal and then access through the serial console. diff --git a/new_dsg_environment/azure-vms/build_azure_vm_image.sh b/new_dsg_environment/azure-vms/build_azure_vm_image.sh index 6940de3fe6..46af17c5a6 100755 --- a/new_dsg_environment/azure-vms/build_azure_vm_image.sh +++ b/new_dsg_environment/azure-vms/build_azure_vm_image.sh @@ -21,11 +21,11 @@ NSGNAME="NSG_IMAGE_BUILD" # Document usage for this script print_usage_and_exit() { echo "usage: $0 [-h] -s subscription [-i source_image] [-n machine_name] [-r resource_group]" - echo " -h display help" + echo " -h display help" echo " -s subscription (required) specify subscription for storing the VM images. (Test using 'Safe Haven Management Testing')" echo " -i source_image (optional) specify source image: either 'Ubuntu' (default) 'UbuntuTorch' (as 'Ubuntu' but with Torch included) or 'DataScience' (uses the Microsoft Data Science VM from the Azure Marketplace)" echo " -r resource_group (optional) specify resource group - will be created if it does not already exist (defaults to 'RG_SH_IMAGEGALLERY')" - echo " -z vm_size (optional) Size of the VM to use for build (defaults to 'Standard_F2s_v2')" + echo " -z vm_size (optional) size of the VM to use for build (defaults to 'Standard_F2s_v2')" exit 1 } diff --git a/new_dsg_environment/azure-vms/cloud-init-compute-vm.yaml b/new_dsg_environment/azure-vms/cloud-init-compute-vm.yaml index 868e175203..979d185d81 100644 --- a/new_dsg_environment/azure-vms/cloud-init-compute-vm.yaml +++ b/new_dsg_environment/azure-vms/cloud-init-compute-vm.yaml @@ -14,10 +14,10 @@ write_files: - path: "/ldap.conf" content: | # The distinguished name of the search base. - base ou=safe haven research users,dc=dsgroupdev,dc=co,dc=uk + base LDAP_BASE_DN # Another way to specify your LDAP server is to provide an - uri ldap://mgmtdevdc.dsgroupdev.co.uk:389 + uri ldap://AD_DC_NAME_LOWER.DOMAIN_LOWER:389 # The LDAP version to use (defaults to 3 # if supported by client library) @@ -26,7 +26,7 @@ write_files: # The distinguished name to bind to the server with # if the effective user ID is root. Password is # stored in /etc/ldap.secret (mode 600) - rootbinddn cn=data science ldap,ou=safe haven service accounts,dc=dsgroupdev,dc=co,dc=uk + rootbinddn LDAP_BIND_DN # Do not hash the password at all; presume # the directory server will do it, if @@ -35,7 +35,7 @@ write_files: - path: "/krb5.conf" content: | [libdefaults] - default_realm = DSGROUPDEV.CO.UK + default_realm = DOMAIN_UPPER # The following krb5.conf variables are only for MIT Kerberos. krb4_config = /etc/krb.conf @@ -59,15 +59,15 @@ write_files: fcc-mit-ticketflags = true [realms] - DSGROUPDEV.CO.UK = { - kdc = MGMTDEVDC.DSGROUPDEV.CO.UK:88 - admin_server = MGMTDEVDC.DSGROUPDEV.CO.UK - default_domain = DSGROUPDEV.CO.UK + DOMAIN_UPPER = { + kdc = AD_DC_NAME_UPPER.DOMAIN_UPPER:88 + admin_server = AD_DC_NAME_UPPER.DOMAIN_UPPER + default_domain = DOMAIN_UPPER } - + [domain_realm] - .dsgroupdev.co.uk = DSGROUPDEV.CO.UK - dsgroupdev.co.uk = DSGROUPDEV.CO.UK + .DOMAIN_LOWER = DOMAIN_UPPER + DOMAIN_LOWER = DOMAIN_UPPER [login] krb4_convert = true @@ -86,7 +86,7 @@ write_files: echo "MACHINENAME" > /etc/hostname cat /etc/hostname echo "Adding MACHINENAME [$(hostname -I)] to /etc/hosts" - HOST_INFORMATION="$(hostname -I) MACHINENAME MACHINENAME.dsgroupdev.co.uk" + HOST_INFORMATION="$(hostname -I) MACHINENAME MACHINENAME.DOMAIN_LOWER" sed -i "/127.0.0.1/ a $HOST_INFORMATION" /etc/hosts cat /etc/hosts # Set timezone @@ -104,7 +104,6 @@ write_files: echo "Storing LDAP secret" echo "LDAP_SECRET_PLAINTEXT" > /etc/ldap.secret chmod 0600 /etc/ldap.secret - cat /etc/ldap.secret # Edit Kerberos config echo "Updating Kerberos config" mv /krb5.conf /etc/krb5.conf @@ -113,7 +112,7 @@ write_files: content: | # Join the VM to the domain echo "Joining VM to the domain" - cat /etc/ldap.secret | realm join --verbose -U dsgpuldap dsgroupdev.co.uk --install=/ + cat /etc/ldap.secret | realm join --verbose -U LDAP_USER DOMAIN_LOWER --install=/ - path: "/active_directory_step03_update_sssd" content: | # Check the sssd.conf file @@ -129,14 +128,16 @@ write_files: content: | # Edit the pam session configuration file echo "Updating PAM configuration" - cat /etc/pam.d/common-session PAM_INFORMATION="session required|pam_mkhomedir.so|skel=/etc/skel/|umask=0022" sed "/pam_unix/ a $PAM_INFORMATION" /etc/pam.d/common-session | tr "|" "\t" > common-session - cat common-session mv common-session /etc/pam.d/common-session cat /etc/pam.d/common-session runcmd: + # ========================================== + # *** BEGINNING OF DSG-SPECIFIC COMMANDS *** + # *** END OF DSG-SPECIFIC COMMANDS *** + # ========================================== # Make sure that sssd is running - echo "Restart sssd service" - service sssd restart @@ -175,6 +176,11 @@ runcmd: - sudo /active_directory_step02_realm_join - sudo /active_directory_step03_update_sssd - sudo /active_directory_step04_update_pam - # Reboot - - reboot + # Remove the Active Directory set up scripts (as these contain secrets and are world readable + - sudo rm /active_directory_step01_pre + - sudo rm /active_directory_step02_realm_join + - sudo rm /active_directory_step03_update_sssd + - sudo rm /active_directory_step04_update_pam + # Shutdown so that we can tell when the job has finished by polling the VM state + - shutdown -P now diff --git a/new_dsg_environment/azure-vms/create-new-dsg-vm-image.sh b/new_dsg_environment/azure-vms/create-new-dsg-vm-image.sh new file mode 100755 index 0000000000..a7d08276c6 --- /dev/null +++ b/new_dsg_environment/azure-vms/create-new-dsg-vm-image.sh @@ -0,0 +1,202 @@ +#!/usr/bin/env bash + +# Constants for colourised output +BOLD="\033[1m" +RED="\033[0;31m" +BLUE="\033[0;36m" +END="\033[0m" + +SOURCEIMAGE="Ubuntu" +RESOURCEGROUP="RG_SH_IMAGEGALLERY" +IMAGES_GALLERY="SIG_SH_COMPUTE" +VM_SIZE="Standard_DS2_v2" + +LOCATION="westeurope" # have to build in West Europe in order to use Shared Image Gallery +NSGNAME="NSG_IMAGE_BUILD" + +# Document usage for this script +print_usage_and_exit() { + echo "usage: $0 -s subscription [-i source_image] [-x source_image_version] [-n machine_name] [-r resource_group] [-u user_name]" + echo " -s subscription specify subscription to use" + echo " -h display help" + echo " -i source_image specify source_image: either 'Ubuntu' (default) 'UbuntuTorch' (as default but with Torch included) or 'DataScience' (the Microsoft Azure DSVM) or 'DSG' (the current base image for Data Study Groups)" + echo " -x source_image_version specify the version of the source image to use (defaults to prompting to select from available versions)" + echo " -r resource_group specify resource group for deploying the VM image - will be created if it does not already exist (defaults to 'RG_SH_IMAGEGALLERY')" + echo " -u user_name specify a username for the admin account (defaults to 'atiadmin')" + exit 1 +} + +# Read command line arguments, overriding defaults where necessary +while getopts "g:hi:x:r:u:s:" opt; do + case $opt in + h) + print_usage_and_exit + ;; + i) + SOURCEIMAGE=$OPTARG + ;; + x) + VERSION=$OPTARG + ;; + r) + RESOURCEGROUP=$OPTARG + ;; + u) + USERNAME=$OPTARG + ;; + s) + SUBSCRIPTION=$OPTARG + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + ;; + esac +done + +# Set default machine name +if [ "$MACHINENAME" = "" ]; then + MACHINENAME="ComputeVM-DSGBase" +fi + +# Check that a source subscription has been provided +if [ "$SUBSCRIPTION" = "" ]; then + echo -e "${RED}Subscription is a required argument!${END}" + print_usage_and_exit +fi + +# Look up specified image definition +az account set --subscription "$SUBSCRIPTION" +if [ "$SOURCEIMAGE" = "Ubuntu" ]; then + IMAGE_DEFINITION="ComputeVM-Ubuntu1804Base" +elif [ "$SOURCEIMAGE" = "UbuntuTorch" ]; then + IMAGE_DEFINITION="ComputeVM-UbuntuTorch1804Base" +elif [ "$SOURCEIMAGE" = "DataScience" ]; then + IMAGE_DEFINITION="ComputeVM-DataScienceBase" +elif [ "$SOURCEIMAGE" = "DSG" ]; then + IMAGE_DEFINITION="ComputeVM-DsgBase" +else + echo -e "${RED}Could not interpret ${BLUE}${SOURCEIMAGE}${END} as an image type${END}" + print_usage_and_exit +fi + +# Prompt user to select version if not already supplied +if [ "$VERSION" = "" ]; then + # List available versions and set the last one in the list as default + echo -e "${BOLD}Found the following versions of ${BLUE}$IMAGE_DEFINITION${END}" + VERSIONS=$(az sig image-version list \ + --resource-group $RESOURCEGROUP \ + --gallery-name $IMAGES_GALLERY \ + --gallery-image-definition $IMAGE_DEFINITION \ + --query "[].name" -o table) + echo -e "$VERSIONS" + DEFAULT_VERSION=$(echo -e "$VERSIONS" | tail -n1) + echo -e "${BOLD}Please type the version you would like to use, followed by [ENTER]. To accept the default ${BLUE}$DEFAULT_VERSION${END} ${BOLD}simply press [ENTER]${END}" + read VERSION + if [ "$VERSION" = "" ]; then VERSION=$DEFAULT_VERSION; fi +fi + +# Check that this is a valid version and then get the image ID +echo -e "${BOLD}Finding ID for image ${BLUE}${IMAGE_DEFINITION}${END} version ${BLUE}${VERSION}${END}${BOLD}...${END}" +if [ "$(az sig image-version show --resource-group $RESOURCEGROUP --gallery-name $IMAGES_GALLERY --gallery-image-definition $IMAGE_DEFINITION --gallery-image-version $VERSION 2>&1 | grep 'not found')" != "" ]; then + echo -e "${RED}Version $VERSION could not be found.${END}" + print_usage_and_exit +fi +IMAGE_ID=$(az sig image-version show --resource-group $RESOURCEGROUP --gallery-name $IMAGES_GALLERY --gallery-image-definition $IMAGE_DEFINITION --gallery-image-version $VERSION --query "id" | xargs) + +# Switch subscription and setup resource groups if they do not already exist +# -------------------------------------------------------------------------- +az account set --subscription "$SUBSCRIPTION" +if [ "$(az group exists --name $RESOURCEGROUP)" != "true" ]; then + echo -e "${BOLD}Creating resource group ${BLUE}$RESOURCEGROUP${END} ${BOLD}in ${BLUE}$SUBSCRIPTIONTARGET${END}" + az group create --name $RESOURCEGROUP --location $LOCATION +fi + +# If using the Data Science VM then the terms must be added before creating the VM +PLANDETAILS="" +if [[ "$SOURCEIMAGE" == *"DataScienceBase"* ]]; then + PLANDETAILS="--plan-name linuxdsvmubuntubyol --plan-publisher microsoft-ads --plan-product linux-data-science-vm-ubuntu" +fi + +# Ensure required features for shared image galleries are enabled for this subscription +FEATURE="GalleryPreview" +NAMESPACE="Microsoft.Compute" +FEATURE_STATE="$(az feature show --namespace $NAMESPACE --name $FEATURE --query 'properties.state' | xargs)" +RESOURCE="galleries/images/versions" +RESOURCE_METADATA_QUERY="resourceTypes[?resourceType=='$RESOURCE']" +RESOURCE_METADATA="$(az provider show --namespace $NAMESPACE --query $RESOURCE_METADATA_QUERY)" + +echo "Ensuring $FEATURE feature is registered and $RESOURCE resource is present in namespace $NAMESPACE (this may take some time)." +echo "Current $FEATURE feature state is $FEATURE_STATE." +if [ "$RESOURCE_METADATA" = "[]" ]; then + echo "Resource $RESOURCE is not present." +else + echo "Resource $RESOURCE is present." +fi + +while [ "$FEATURE_STATE" != "Registered" -o "$RESOURCE_METADATA" = "[]" ]; do + if [ "$FEATURE_STATE" = "NotRegistered" ]; then + # Register feature + echo -e "${BOLD}Registering ${BLUE}$FEATURE${END} ${BOLD}for ${BLUE}$SUBSCRIPTION${END}" + az feature register --namespace Microsoft.Compute --name "$FEATURE" --subscription "$SUBSCRIPTION" + az provider register --namespace Microsoft.Compute + elif [ "$FEATURE_STATE" = "Pending" -o "$FEATURE_STATE" = "Registering" -o "$RESOURCE_METADATA" = "[]" ]; then + echo -ne "." + sleep 30 + else + echo -e "${RED}$FEATURE state or $RESOURCE resource could not be found. Try updating Azure CLI.${END}" + exit 1 + fi + FEATURE_STATE="$(az feature show --namespace $NAMESPACE --name $FEATURE --query 'properties.state' | xargs)" + RESOURCE_METADATA="$(az provider show --namespace $NAMESPACE --query $RESOURCE_METADATA_QUERY)" +done + +# Add an NSG group to deny inbound connections except Turing-based SSH +if [ "$(az network nsg show --resource-group $RESOURCEGROUP --name $NSGNAME 2> /dev/null)" = "" ]; then + echo -e "${BOLD}Creating NSG for image build: ${BLUE}$NSGNAME${END}" + az network nsg create --resource-group $RESOURCEGROUP --name $NSGNAME + az network nsg rule create \ + --resource-group $RESOURCEGROUP \ + --nsg-name $NSGNAME \ + --direction Inbound \ + --name ManualConfigSSH \ + --description "Allow port 22 for management over ssh" \ + --source-address-prefixes 193.60.220.253 \ + --source-port-ranges "*" \ + --destination-address-prefixes "*" \ + --destination-port-ranges 22 \ + --protocol TCP \ + --priority 100 + az network nsg rule create \ + --resource-group $RESOURCEGROUP \ + --nsg-name $NSGNAME \ + --direction Inbound \ + --name DenyAll \ + --description "Deny all" \ + --access "Deny" \ + --source-address-prefixes "*" \ + --source-port-ranges "*" \ + --destination-address-prefixes "*" \ + --destination-port-ranges "*" \ + --protocol "*" \ + --priority 3000 +fi + +# Create the VM based off the selected source image +# Append timestamp to allow unique naming +DISKSIZEGB=60 +BASENAME="Generalized${MACHINENAME}-$(date '+%Y%m%d%H%M')" +echo -e "${BOLD}Provisioning a new VM image in ${BLUE}$RESOURCEGROUP${END} ${BOLD}as part of ${BLUE}$SUBSCRIPTION${END}" +echo -e "${BOLD} VM name: ${BLUE}$BASENAME${END}" +echo -e "${BOLD} Base image: ${BLUE}$SOURCEIMAGE${END} ($IMAGE_ID)" +STARTTIME=$(date +%s) + +az vm create \ + --resource-group $RESOURCEGROUP \ + --name $BASENAME \ + --image $IMAGE_ID \ + --os-disk-size-gb $DISKSIZEGB \ + --nsg $NSGNAME \ + --size $VM_SIZE \ + --admin-username atiadmin \ + --generate-ssh-keys + diff --git a/new_dsg_environment/azure-vms/deploy_azure_dsg_vm.sh b/new_dsg_environment/azure-vms/deploy_azure_dsg_vm.sh index 03686ea480..cc0602439f 100755 --- a/new_dsg_environment/azure-vms/deploy_azure_dsg_vm.sh +++ b/new_dsg_environment/azure-vms/deploy_azure_dsg_vm.sh @@ -3,7 +3,7 @@ # Options which are configurable at the command line SOURCEIMAGE="Ubuntu" MACHINENAME="" -RESOURCEGROUP="RS_DSG_TEST" +RESOURCEGROUP="RG_DSG_COMPUTE" SUBSCRIPTIONSOURCE="" # must be provided SUBSCRIPTIONTARGET="" # must be provided USERNAME="atiadmin" @@ -11,6 +11,8 @@ DSG_NSG="NSG_Linux_Servers" # NB. this will disallow internet connection during DSG_VNET="DSG_DSGROUPTEST_VNet1" DSG_SUBNET="Subnet-Data" VM_SIZE="Standard_DS2_v2" +VERSION="" +CLOUD_INIT_YAML="cloud-init-compute-vm.yaml" # Constants for colourised output BOLD="\033[1m" @@ -23,29 +25,39 @@ IMAGES_RESOURCEGROUP="RG_SH_IMAGEGALLERY" IMAGES_GALLERY="SIG_SH_COMPUTE" LOCATION="uksouth" LDAP_RESOURCEGROUP="RG_SH_LDAP" -LDAP_VAULT_NAME="kvldap" -LDAP_SECRET_NAME="ldap-secret" +DEPLOYMENT_NSG="NSG_IMAGE_DEPLOYMENT" # NB. this will *allow* internet connection during deployment # Document usage for this script print_usage_and_exit() { - echo "usage: $0 -s subscription_source -t subscription_target [-h] [-g nsg_name] [-i source_image] [-n machine_name] [-r resource_group] [-u user_name]" + echo "usage: $0 -s subscription_source -t subscription_target [-h] [-g nsg_name] [-i source_image] [-x source_image_version] [-n machine_name] [-r resource_group] [-u user_name]" echo " -h display help" echo " -g nsg_name specify which NSG to connect to (defaults to 'NSG_Linux_Servers')" - echo " -i source_image specify source_image: either 'Ubuntu' (default) 'UbuntuTorch' (as default but with Torch included) or 'DataScience'" + echo " -i source_image specify source_image: either 'Ubuntu' (default) 'UbuntuTorch' (as default but with Torch included) or 'DataScience' (the Microsoft Azure DSVM) or 'DSG' (the current base image for Data Study Groups)" + echo " -x source_image_version specify the version of the source image to use (defaults to prompting to select from available versions)" echo " -n machine_name specify name of created VM, which must be unique in this resource group (defaults to 'DSGYYYYMMDDHHMM')" - echo " -r resource_group specify resource group for deploying the VM image - will be created if it does not already exist (defaults to 'RS_DSG_TEST')" + echo " -r resource_group specify resource group for deploying the VM image - will be created if it does not already exist (defaults to 'RG_DSG_COMPUTE')" echo " -u user_name specify a username for the admin account (defaults to 'atiadmin')" echo " -s subscription_source specify source subscription that images are taken from [required]. (Test using 'Safe Haven Management Testing')" echo " -t subscription_target specify target subscription for deploying the VM image [required]. (Test using 'Data Study Group Testing')" echo " -v vnet_name specify a VNET to connect to (defaults to 'DSG_DSGROUPTEST_VNet1')" echo " -w subnet_name specify a subnet to connect to (defaults to 'Subnet-Data')" echo " -z vm_size specify a VM size to use (defaults to 'Standard_DS2_v2')" + echo " -m management_vault_name specify name of KeyVault containing management secrets (required)" + echo " -l ldap_secret_name specify name of KeyVault secret containing LDAP secret (required)" + echo " -j ldap_user specify the LDAP user (required)" + echo " -p password_secret_name specify name of KeyVault secret containing VM admin password (required)" + echo " -d domain specify domain name for safe haven (required)" + echo " -a ad_dc_name specify Active Directory Domain Controller name (required)" + echo " -b ldap_base_dn specify LDAP base DN" + echo " -c ldap_bind_dn specify LDAP bind DN" + echo " -q ip_address specify a specific IP address to deploy the VM to (required)" + echo " -y yaml_cloud_init specify a custom cloud-init YAML script" exit 1 } # Read command line arguments, overriding defaults where necessary -while getopts "g:hi:n:r:u:s:t:v:w:z:" opt; do +while getopts "g:hi:x:n:r:u:s:t:v:w:z:m:l:p:j:d:a:b:c:q:y:" opt; do case $opt in g) DSG_NSG=$OPTARG @@ -56,6 +68,9 @@ while getopts "g:hi:n:r:u:s:t:v:w:z:" opt; do i) SOURCEIMAGE=$OPTARG ;; + x) + VERSION=$OPTARG + ;; n) MACHINENAME=$OPTARG ;; @@ -80,13 +95,43 @@ while getopts "g:hi:n:r:u:s:t:v:w:z:" opt; do z) VM_SIZE=$OPTARG ;; + m) + MANAGEMENT_VAULT_NAME=$OPTARG + ;; + l) + LDAP_SECRET_NAME=$OPTARG + ;; + p) + ADMIN_PASSWORD_SECRET_NAME=$OPTARG + ;; + j) + LDAP_USER=$OPTARG + ;; + d) + DOMAIN=$OPTARG + ;; + a) + AD_DC_NAME=$OPTARG + ;; + b) + LDAP_BASE_DN=$OPTARG + ;; + c) + LDAP_BIND_DN=$OPTARG + ;; + q) + IP_ADDRESS=$OPTARG + ;; + y) + CLOUD_INIT_YAML=$OPTARG + ;; \?) echo "Invalid option: -$OPTARG" >&2 ;; esac done -# Set default subscription +# Set default machine name if [ "$MACHINENAME" = "" ]; then MACHINENAME="DSG$(date '+%Y%m%d%H%M')" fi @@ -96,13 +141,45 @@ if [ "$SUBSCRIPTIONSOURCE" = "" ]; then echo -e "${RED}Source subscription is a required argument!${END}" print_usage_and_exit fi + +# Check that a management KeyVault name has been provided +if [ "$MANAGEMENT_VAULT_NAME" = "" ]; then + echo -e "${RED}Management KeyVault name is a required argument!${END}" + print_usage_and_exit +fi + + +# Check that an LDAP secret KeyVault secret name has been provided +if [ "$LDAP_SECRET_NAME" = "" ]; then + echo -e "${RED}LDAP secret KeyVault secret name is a required argument!${END}" + print_usage_and_exit +fi + +# Check that an LDAP username has been provided +if [ "$LDAP_USER" = "" ]; then + echo -e "${RED}LDAP user is a required argument!${END}" + print_usage_and_exit +fi + +# Check that an domain has been provided +if [ "$DOMAIN" = "" ]; then + echo -e "${RED}Domain is a required argument!${END}" + print_usage_and_exit +fi + +# Check that an admin password KeyVault secret name has been provided +if [ "$ADMIN_PASSWORD_SECRET_NAME" = "" ]; then + echo -e "${RED}Admin password KeyVault secret name is a required argument!${END}" + print_usage_and_exit +fi + # Check that a target subscription has been provided if [ "$SUBSCRIPTIONTARGET" = "" ]; then echo -e "${RED}Target subscription is a required argument!${END}" print_usage_and_exit fi -# Search for available images and prompt user to select one +# Look up specified image definition az account set --subscription "$SUBSCRIPTIONSOURCE" if [ "$SOURCEIMAGE" = "Ubuntu" ]; then IMAGE_DEFINITION="ComputeVM-Ubuntu1804Base" @@ -110,26 +187,31 @@ elif [ "$SOURCEIMAGE" = "UbuntuTorch" ]; then IMAGE_DEFINITION="ComputeVM-UbuntuTorch1804Base" elif [ "$SOURCEIMAGE" = "DataScience" ]; then IMAGE_DEFINITION="ComputeVM-DataScienceBase" +elif [ "$SOURCEIMAGE" = "DSG" ]; then + IMAGE_DEFINITION="ComputeVM-DsgBase" else echo -e "${RED}Could not interpret ${BLUE}${SOURCEIMAGE}${END} as an image type${END}" print_usage_and_exit fi -# List available versions and set the last one in the list as default -echo -e "${BOLD}Found the following versions of ${BLUE}$IMAGE_DEFINITION${END}" -VERSIONS=$(az sig image-version list \ - --resource-group $IMAGES_RESOURCEGROUP \ - --gallery-name $IMAGES_GALLERY \ - --gallery-image-definition $IMAGE_DEFINITION \ - --query "[].name" -o table) -echo -e "$VERSIONS" -DEFAULT_VERSION=$(echo -e "$VERSIONS" | tail -n1) -echo -e "${BOLD}Please type the version you would like to use, followed by [ENTER]. To accept the default ${BLUE}$DEFAULT_VERSION${END} ${BOLD}simply press [ENTER]${END}" -read VERSION -if [ "$VERSION" = "" ]; then VERSION=$DEFAULT_VERSION; fi +# Prompt user to select version if not already supplied +if [ "$VERSION" = "" ]; then + # List available versions and set the last one in the list as default + echo -e "${BOLD}Found the following versions of ${BLUE}$IMAGE_DEFINITION${END}" + VERSIONS=$(az sig image-version list \ + --resource-group $IMAGES_RESOURCEGROUP \ + --gallery-name $IMAGES_GALLERY \ + --gallery-image-definition $IMAGE_DEFINITION \ + --query "[].name" -o table) + echo -e "$VERSIONS" + DEFAULT_VERSION=$(echo -e "$VERSIONS" | tail -n1) + echo -e "${BOLD}Please type the version you would like to use, followed by [ENTER]. To accept the default ${BLUE}$DEFAULT_VERSION${END} ${BOLD}simply press [ENTER]${END}" + read VERSION + if [ "$VERSION" = "" ]; then VERSION=$DEFAULT_VERSION; fi +fi # Check that this is a valid version and then get the image ID -echo -e "${BOLD}Finding ID for image ${BLUE}${VERSION}${END}${BOLD}...${END}" +echo -e "${BOLD}Finding ID for image ${BLUE}${IMAGE_DEFINITION}${END} version ${BLUE}${VERSION}${END}${BOLD}...${END}" if [ "$(az sig image-version show --resource-group $IMAGES_RESOURCEGROUP --gallery-name $IMAGES_GALLERY --gallery-image-definition $IMAGE_DEFINITION --gallery-image-version $VERSION 2>&1 | grep 'not found')" != "" ]; then echo -e "${RED}Version $VERSION could not be found.${END}" print_usage_and_exit @@ -143,31 +225,9 @@ if [ "$(az group exists --name $RESOURCEGROUP)" != "true" ]; then echo -e "${BOLD}Creating resource group ${BLUE}$RESOURCEGROUP${END} ${BOLD}in ${BLUE}$SUBSCRIPTIONTARGET${END}" az group create --name $RESOURCEGROUP --location $LOCATION fi -if [ "$(az group exists --name $LDAP_RESOURCEGROUP)" != "true" ]; then - echo -e "${BOLD}Creating resource group ${BLUE}$LDAP_RESOURCEGROUP${END} ${BOLD}in ${BLUE}$SUBSCRIPTIONTARGET${END}" - az group create --name $LDAP_RESOURCEGROUP --location $LOCATION -fi - -# Create keyvault for secrets if it does not already exist -# ------------------------------------------------------- -# Create keyvault if it does not already exist -if [ "$(az keyvault list | grep $LDAP_VAULT_NAME)" = "" ]; then - echo -e "${BOLD}Creating keyvault ${BLUE}$LDAP_VAULT_NAME${END} ${BOLD}in ${BLUE}$LDAP_RESOURCEGROUP${END}" - az keyvault create --name ${LDAP_VAULT_NAME} --resource-group ${LDAP_RESOURCEGROUP} --enabled-for-deployment true -fi -# Wait for DNS propagation of keyvault -sleep 10 - -# Add password to vault -if [ "$(az keyvault secret list --vault-name $LDAP_VAULT_NAME --query "[].id" | grep $LDAP_SECRET_NAME)" = "" ]; then - read -s -p "Enter LDAP password for this DSG (only needs to be done once): " LDAP_PASSWORD - echo "" - echo -e "${BOLD}Storing password in keyvault ${BLUE}$LDAP_VAULT_NAME${END}" - az keyvault secret set --vault-name $LDAP_VAULT_NAME --name $LDAP_SECRET_NAME --value "$LDAP_PASSWORD" -fi -# Check that NSG exists -# --------------------- +# Check that secure NSG exists +# ---------------------------- DSG_NSG_RG="" DSG_NSG_ID="" for RG in $(az group list --query "[].name" -o tsv); do @@ -177,12 +237,80 @@ for RG in $(az group list --query "[].name" -o tsv); do fi done if [ "$DSG_NSG_RG" = "" ]; then - echo -e "${RED}Could not find NSG ${BLUE}$DSG_NSG ${RED}in any resource group${END}" + echo -e "${RED}Could not find NSG ${BLUE}$DSG_NSG${END} ${RED}in any resource group${END}" print_usage_and_exit else echo -e "${BOLD}Found NSG ${BLUE}$DSG_NSG${END} ${BOLD}in resource group ${BLUE}$DSG_NSG_RG${END}" fi +# Ensure that NSG with outbound internet access exists (used for deployment only) +# ------------------------------------------------------------------------------- +if [ "$(az network nsg show --resource-group $DSG_NSG_RG --name $DEPLOYMENT_NSG 2> /dev/null)" = "" ]; then + echo -e "${BOLD}Creating NSG ${BLUE}$DEPLOYMENT_NSG${END} ${BOLD}with outbound internet access ${RED}(for use during deployment *only*)${END}${BOLD} in resource group ${BLUE}$DSG_NSG_RG${END}" + az network nsg create --resource-group $DSG_NSG_RG --name $DEPLOYMENT_NSG + if [ "$SUBSCRIPTIONTARGET" == "Data Study Group Testing" ]; then + LDAP_SERVER_IP_RANGE="10.220.1.0/24" + else + LDAP_SERVER_IP_RANGE="10.251.0.0/24" + fi + # Inbound: allow LDAP then deny all + az network nsg rule create \ + --resource-group $DSG_NSG_RG \ + --nsg-name $DEPLOYMENT_NSG \ + --direction Inbound \ + --name InboundAllowLDAP \ + --description "Inbound allow LDAP" \ + --access "Allow" \ + --source-address-prefixes $LDAP_SERVER_IP_RANGE \ + --source-port-ranges 88 389 636 \ + --destination-address-prefixes VirtualNetwork \ + --destination-port-ranges "*" \ + --protocol "*" \ + --priority 2000 + az network nsg rule create \ + --resource-group $DSG_NSG_RG \ + --nsg-name $DEPLOYMENT_NSG \ + --direction Inbound \ + --name InboundDenyAll \ + --description "Inbound deny all" \ + --access "Deny" \ + --source-address-prefixes "*" \ + --source-port-ranges "*" \ + --destination-address-prefixes "*" \ + --destination-port-ranges "*" \ + --protocol "*" \ + --priority 3000 + # Outbound: allow LDAP then deny all Virtual Network + az network nsg rule create \ + --resource-group $DSG_NSG_RG \ + --nsg-name $DEPLOYMENT_NSG \ + --direction Outbound \ + --name OutboundAllowLDAP \ + --description "Outbound allow LDAP" \ + --access "Allow" \ + --source-address-prefixes VirtualNetwork \ + --source-port-ranges "*" \ + --destination-address-prefixes $LDAP_SERVER_IP_RANGE \ + --destination-port-ranges "*" \ + --protocol "*" \ + --priority 2000 + az network nsg rule create \ + --resource-group $DSG_NSG_RG \ + --nsg-name $DEPLOYMENT_NSG \ + --direction Outbound \ + --name OutboundDenyVNet \ + --description "Outbound deny virtual network" \ + --access "Deny" \ + --source-address-prefixes "*" \ + --source-port-ranges "*" \ + --destination-address-prefixes VirtualNetwork \ + --destination-port-ranges "*" \ + --protocol "*" \ + --priority 3000 +fi +DEPLOYMENT_NSG_ID=$(az network nsg show --resource-group $DSG_NSG_RG --name $DEPLOYMENT_NSG --query 'id' | xargs) +echo -e "${RED}Deploying into NSG ${BLUE}$DEPLOYMENT_NSG${END} ${RED}with outbound internet access to allow package installation. Will switch NSGs at end of deployment.${END}" + # Check that VNET and subnet exist # -------------------------------- DSG_SUBNET_RG="" @@ -195,7 +323,7 @@ for RG in $(az group list --query "[].name" -o tsv); do fi done if [ "$DSG_SUBNET_RG" = "" ]; then - echo -e "${RED}Could not find subnet ${BLUE}$DSG_SUBNET${END} ${RED}in any resource group${END}" + echo -e "${RED}Could not find subnet ${BLUE}$DSG_SUBNET${END} ${RED}in vnet ${BLUE}$DSG_VNET${END} in ${RED}any resource group${END}" print_usage_and_exit else echo -e "${BOLD}Found subnet ${BLUE}$DSG_SUBNET${END} ${BOLD}as part of VNET ${BLUE}$DSG_VNET${END} ${BOLD}in resource group ${BLUE}$DSG_SUBNET_RG${END}" @@ -207,53 +335,93 @@ if [[ "$SOURCEIMAGE" == *"DataScienceBase"* ]]; then PLANDETAILS="--plan-name linuxdsvmubuntubyol --plan-publisher microsoft-ads --plan-product linux-data-science-vm-ubuntu" fi -# Prompt for a user password -echo -e "${BOLD}Admin username will be: ${BLUE}${USERNAME}${END}" -read -s -p "Enter password for this user: " USER_PASSWORD -echo "" +# Construct the cloud-init yaml file for the target subscription +# -------------------------------------------------------------- +# Retrieve admin password from keyvault +ADMIN_PASSWORD=$(az keyvault secret show --vault-name $MANAGEMENT_VAULT_NAME --name $ADMIN_PASSWORD_SECRET_NAME --query "value" | xargs) # Get LDAP secret file with password in it (can't pass as a secret at VM creation) -LDAP_SECRET_PLAINTEXT=$(az keyvault secret show --vault-name $LDAP_VAULT_NAME --name $LDAP_SECRET_NAME --query "value" | xargs) +LDAP_SECRET_PLAINTEXT=$(az keyvault secret show --vault-name $MANAGEMENT_VAULT_NAME --name $LDAP_SECRET_NAME --query "value" | xargs) # Create a new config file with the appropriate username and LDAP password TMP_CLOUD_CONFIG_PREFIX=$(mktemp) -TMP_CLOUD_CONFIG_YAML=$(mktemp "${TMP_CLOUD_CONFIG_PREFIX}.yaml") +TMP_CLOUD_CONFIG_YAML="${TMP_CLOUD_CONFIG_PREFIX}.yaml" rm $TMP_CLOUD_CONFIG_PREFIX -sed -e 's/USERNAME/'${USERNAME}'/g' -e 's/LDAP_SECRET_PLAINTEXT/'${LDAP_SECRET_PLAINTEXT}'/g' -e 's/MACHINENAME/'${MACHINENAME}'/g' cloud-init-compute-vm.yaml > $TMP_CLOUD_CONFIG_YAML +DOMAIN_UPPER=$(echo "$DOMAIN" | tr '[:lower:]' '[:upper:]') +DOMAIN_LOWER=$(echo "$DOMAIN" | tr '[:upper:]' '[:lower:]') +AD_DC_NAME_UPPER=$(echo "$AD_DC_NAME" | tr '[:lower:]' '[:upper:]') +AD_DC_NAME_LOWER=$(echo "$AD_DC_NAME" | tr '[:upper:]' '[:lower:]') + +# Define regexes +USERNAME_REGEX="s/USERNAME/"${USERNAME}"/g" +LDAP_SECRET_REGEX="s/LDAP_SECRET_PLAINTEXT/"${LDAP_SECRET_PLAINTEXT}"/g" +MACHINE_NAME_REGEX="s/MACHINENAME/${MACHINENAME}/g" +LDAP_USER_REGEX="s/LDAP_USER/${LDAP_USER}/g" +DOMAIN_LOWER_REGEX="s/DOMAIN_LOWER/${DOMAIN_LOWER}/g" +DOMAIN_UPPER_REGEX="s/DOMAIN_UPPER/${DOMAIN_UPPER}/g" +LDAP_BASE_DN_REGEX="s/LDAP_BASE_DN/${LDAP_BASE_DN}/g" +LDAP_BIND_DN_REGEX="s/LDAP_BIND_DN/${LDAP_BIND_DN}/g" +AD_DC_NAME_UPPER_REGEX="s/AD_DC_NAME_UPPER/${AD_DC_NAME_UPPER}/g" +AD_DC_NAME_LOWER_REGEX="s/AD_DC_NAME_LOWER/${AD_DC_NAME_LOWER}/g" +# Substitute regexes +sed -e "${USERNAME_REGEX}" -e "${LDAP_SECRET_REGEX}" -e "${MACHINE_NAME_REGEX}" -e "${LDAP_USER_REGEX}" -e "${DOMAIN_LOWER_REGEX}" -e "${DOMAIN_UPPER_REGEX}" -e "${LDAP_CN_REGEX}" -e "${LDAP_BASE_DN_REGEX}" -e "${LDAP_BIND_DN_REGEX}" -e "${AD_DC_NAME_UPPER_REGEX}" -e "${AD_DC_NAME_LOWER_REGEX}" $CLOUD_INIT_YAML > $TMP_CLOUD_CONFIG_YAML # Create the VM based off the selected source image # ------------------------------------------------- echo -e "${BOLD}Creating VM ${BLUE}$MACHINENAME${END} ${BOLD}as part of ${BLUE}$RESOURCEGROUP${END}" echo -e "${BOLD}This will use the ${BLUE}$SOURCEIMAGE${END}${BOLD}-based compute machine image${END}" STARTTIME=$(date +%s) -az vm create ${PLANDETAILS} \ - --resource-group $RESOURCEGROUP \ - --name $MACHINENAME \ - --image $IMAGE_ID \ - --subnet $DSG_SUBNET_ID \ - --nsg $DSG_NSG_ID \ - --public-ip-address "" \ - --custom-data $TMP_CLOUD_CONFIG_YAML \ - --size $VM_SIZE \ - --admin-username $USERNAME \ - --admin-password $USER_PASSWORD + +if [ "$IP_ADDRESS" = "" ]; then + echo -e "${BOLD}Requesting a dynamic IP address${END}" + az vm create ${PLANDETAILS} \ + --resource-group $RESOURCEGROUP \ + --name $MACHINENAME \ + --image $IMAGE_ID \ + --subnet $DSG_SUBNET_ID \ + --nsg $DEPLOYMENT_NSG_ID \ + --public-ip-address "" \ + --custom-data $TMP_CLOUD_CONFIG_YAML \ + --size $VM_SIZE \ + --admin-username $USERNAME \ + --admin-password $ADMIN_PASSWORD \ + --os-disk-size-gb 1024 +else + echo -e "${BOLD}Creating VM with static IP address ${BLUE}$IP_ADDRESS${END}" + az vm create ${PLANDETAILS} \ + --resource-group $RESOURCEGROUP \ + --name $MACHINENAME \ + --image $IMAGE_ID \ + --subnet $DSG_SUBNET_ID \ + --nsg $DEPLOYMENT_NSG_ID \ + --public-ip-address "" \ + --custom-data $TMP_CLOUD_CONFIG_YAML \ + --size $VM_SIZE \ + --admin-username $USERNAME \ + --admin-password $ADMIN_PASSWORD \ + --os-disk-size-gb 1024 \ + --private-ip-address $IP_ADDRESS +fi # Remove temporary init file if it exists rm $TMP_CLOUD_CONFIG_YAML 2> /dev/null # allow some time for the system to finish initialising sleep 30 +# Poll VM to see whether it has finished running +echo -e "${BOLD}Waiting for VM setup to finish (this may take several minutes)...${END}" +while true; do + POLL=$(az vm get-instance-view --resource-group $RESOURCEGROUP --name $MACHINENAME --query "instanceView.statuses[?code == 'PowerState/running'].displayStatus") + if [ "$(echo $POLL | grep 'VM running')" == "" ]; then break; fi + sleep 10 +done + +# Switch NSG and restart +echo -e "${BOLD}Switching to secure NSG: ${BLUE}${DSG_NSG}${END}" +az network nic update --resource-group $RESOURCEGROUP --name "${MACHINENAME}VMNic" --network-security-group $DSG_NSG_ID +echo -e "${BOLD}Restarting VM: ${BLUE}${MACHINENAME}${END}" +az vm start --resource-group $RESOURCEGROUP --name $MACHINENAME + # Get public IP address for this machine. Piping to echo removes the quotemarks around the address PRIVATEIP=$(az vm list-ip-addresses --resource-group $RESOURCEGROUP --name $MACHINENAME --query "[0].virtualMachine.network.privateIpAddresses[0]" | xargs echo) -echo -e "${BOLD}This new VM can be accessed with remote desktop at ${BLUE}${PRIVATEIP}${END}" - -# # Wait until it reboots and then reset the atiadmin password -# echo -e "${BOLD}Waiting for 10 minutes then resetting admin password${END}" -# sleep 600 - -# # Reset the atiadmin password -# az vm extension set --name VMAccessForLinux \ -# --publisher Microsoft.OSTCExtensions \ -# --version 1.4 \ -# --vm-name $MACHINENAME \ -# --resource-group $RESOURCEGROUP \--protected-settings '{"username":"atiadmin", "password":"$USER_PASSWORD","expiration":"2099-01-01"}' +echo -e "${BOLD}This new VM can be accessed with SSH or remote desktop at ${BLUE}${PRIVATEIP}${END}" diff --git a/new_dsg_environment/azure-vms/deploy_dsg_dec18.sh b/new_dsg_environment/azure-vms/deploy_dsg_dec18.sh new file mode 100755 index 0000000000..21af0c2114 --- /dev/null +++ b/new_dsg_environment/azure-vms/deploy_dsg_dec18.sh @@ -0,0 +1,147 @@ +#!/usr/bin/env bash + +# Options which are configurable at the command line +DSG_ID="" +FIXED_IP="" +VM_SIZE="Standard_DS2_v2" + +# Document usage for this script +print_usage_and_exit() { + echo "usage: $0 -g dsg_group_id [-h] [-i source_image] [-x source_image_version] [-z vm_size]" + echo " -h display help" + echo " -d dsg_group_id specify the DSG group to deploy to ('TEST' for test or 1-6 for production)" + echo " -z vm_size specify a VM size to use (defaults to 'Standard_DS2_v2')" + echo " -q fixed_ip Last part of IP address (first three parts are fixed for each DSG group)" + exit 1 +} + +# Read command line arguments, overriding defaults where necessary +while getopts "d:hz:q:" opt; do + case $opt in + d) + DSG_ID=$OPTARG + ;; + h) + print_usage_and_exit + ;; + z) + VM_SIZE=$OPTARG + ;; + q) + FIXED_IP=$OPTARG + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + ;; + esac +done + +# Check that a DSG group ID has been provided +if [ "$DSG_ID" = "" ]; then + echo -e "${RED}DSG Group ID is a required argument!${END}" + print_usage_and_exit +fi +# Check DSG group ID is valid +DSG_ID_UPPER=$(echo "$DSG_ID" | tr '[:lower:]' '[:upper:]') +DSG_ID_LOWER=$(echo "$DSG_ID" | tr '[:upper:]' '[:lower:]') +if [ "$DSG_ID_UPPER" != "TEST" -a "$DSG_ID_UPPER" != "1" -a "$DSG_ID_UPPER" != "2" -a "$DSG_ID_UPPER" != "3" \ + -a "$DSG_ID_UPPER" != "4" -a "$DSG_ID_UPPER" != "5" -a "$DSG_ID_UPPER" != "6" ]; then + echo -e "${RED}DSG Group ID is not valid!${END}" + print_usage_and_exit +fi + +# Deployed VM parameters +USERNAME="atiadmin" + +# Deployment environment +RESOURCEGROUP="RG_DSG_COMPUTE" +DSG_SUBNET="Subnet-Data" +DSG_NSG="NSG_Linux_Servers" + +# Secrets +MANAGEMENT_VAULT_NAME="dsg-management-test" +LDAP_SECRET_NAME="ldap-secret-dsg${DSG_ID_LOWER}" +ADMIN_PASSWORD_SECRET_NAME="vm-admin-password" + +# Set defaults for test and production environments +if [ "$DSG_ID_UPPER" = "TEST" ]; then + DSG_VNET="DSG_DSGROUPTEST_VNet1" + SUBSCRIPTIONSOURCE="Safe Haven Management Testing" + SUBSCRIPTIONTARGET="Data Study Group Testing" + LDAP_USER="dsgpuldap" + DOMAIN="dsgroupdev.co.uk" + AD_DC_NAME="MGMTDEVDC" + LDAP_BASE_DN="ou=safe haven research users,dc=dsgroupdev,dc=co,dc=uk" + LDAP_BIND_DN="cn=data science ldap,ou=safe haven service accounts,dc=dsgroupdev,dc=co,dc=uk" +else + DSG_VNET="DSG_DSGROUP${DSG_ID_UPPER}_VNET1" + SUBSCRIPTIONSOURCE="Safe Haven Management Testing" + SUBSCRIPTIONTARGET="Data Study Group ${DSG_ID_LOWER}" + LDAP_USER="dsg${DSG_ID_LOWER}dsgpuldap" + DOMAIN="turingsafehaven.ac.uk" + AD_DC_NAME="SHMDC1" + LDAP_BASE_DN="OU=Safe Haven Research Users,DC=turingsafehaven,DC=ac,DC=uk" + LDAP_BIND_DN="CN=DSG${DSG_ID_LOWER} Data Science LDAP,OU=Safe Haven Service Accounts,DC=turingsafehaven,DC=ac,DC=uk" +fi + +# ComputeVM-DsgBase version 0.0.2018121000 is a direct copy of Ubuntu version 0.0.2018120701 (/subscriptions/1e79c270-3126-43de-b035-22c3118dd488/resourceGroups/RG_SH_IMAGEGALLERY/providers/Microsoft.Compute/images/ImageComputeVM-Ubuntu1804Base-201812071437) + +# Overwite defaults for per-DSG settings +if [ "$DSG_ID_UPPER" = "TEST" ]; then + IP_PREFIX="10.250.250." + CLOUD_INIT_YAML="DSG2018/cloud-init-compute-vm-DSG-TEST.yaml" + # Only change settings below here during a DSG + SOURCEIMAGE="Ubuntu" + VERSION="0.0.2018120701" +fi +if [ "$DSG_ID_UPPER" = "1" ]; then + DSG_VNET="DSG_EXTREMISM_VNET1" + IP_PREFIX="10.250.2." + CLOUD_INIT_YAML="DSG2018/cloud-init-compute-vm-DSG-1.yaml" + # Only change settings below here during a DSG + SOURCEIMAGE="Ubuntu" + VERSION="0.0.2018120701" +fi +if [ "$DSG_ID_UPPER" = "2" ]; then + DSG_VNET="DSG_NEWS_VNET1" + IP_PREFIX="10.250.10." + CLOUD_INIT_YAML="DSG2018/cloud-init-compute-vm-DSG-2.yaml" + # Only change settings below here during a DSG + SOURCEIMAGE="Ubuntu" + VERSION="0.0.2018120701" +fi +if [ "$DSG_ID_UPPER" = "3" ]; then + IP_PREFIX="10.250.18." + CLOUD_INIT_YAML="DSG2018/cloud-init-compute-vm-DSG-3.yaml" + # Only change settings below here during a DSG + SOURCEIMAGE="Ubuntu" + VERSION="0.0.2018120701" +fi +if [ "$DSG_ID_UPPER" = "4" ]; then + IP_PREFIX="10.250.26." + CLOUD_INIT_YAML="DSG2018/cloud-init-compute-vm-DSG-4.yaml" + # Only change settings below here during a DSG + SOURCEIMAGE="Ubuntu" + VERSION="0.0.2018120701" +fi +if [ "$DSG_ID_UPPER" = "6" ]; then + IP_PREFIX="10.250.42." + CLOUD_INIT_YAML="DSG2018/cloud-init-compute-vm-DSG-6.yaml" + # Only change settings below here during a DSG + SOURCEIMAGE="Ubuntu" + VERSION="0.0.2018120701" +fi + + +if [ "$FIXED_IP" = "" ]; then + ./deploy_azure_dsg_vm.sh -s "$SUBSCRIPTIONSOURCE" -t "$SUBSCRIPTIONTARGET" -i "$SOURCEIMAGE" -x "$VERSION" -g "$DSG_NSG" \ + -r "$RESOURCEGROUP" -v "$DSG_VNET" -w "$DSG_SUBNET" -z "$VM_SIZE" -m "$MANAGEMENT_VAULT_NAME" -l "$LDAP_SECRET_NAME" \ + -p "$ADMIN_PASSWORD_SECRET_NAME" -j "$LDAP_USER" -d "$DOMAIN" -a "$AD_DC_NAME" -b "$LDAP_BASE_DN" -c "$LDAP_BIND_DN" \ + -y $CLOUD_INIT_YAML +else + IP_ADDRESS="${IP_PREFIX}${FIXED_IP}" + ./deploy_azure_dsg_vm.sh -s "$SUBSCRIPTIONSOURCE" -t "$SUBSCRIPTIONTARGET" -i "$SOURCEIMAGE" -x "$VERSION" -g "$DSG_NSG" \ + -r "$RESOURCEGROUP" -v "$DSG_VNET" -w "$DSG_SUBNET" -z "$VM_SIZE" -m "$MANAGEMENT_VAULT_NAME" -l "$LDAP_SECRET_NAME" \ + -p "$ADMIN_PASSWORD_SECRET_NAME" -j "$LDAP_USER" -d "$DOMAIN" -a "$AD_DC_NAME" -b "$LDAP_BASE_DN" -c "$LDAP_BIND_DN" \ + -q "$IP_ADDRESS" -y $CLOUD_INIT_YAML +fi \ No newline at end of file diff --git a/new_dsg_environment/azure-vms/fetch_lanl_summary_data.sh b/new_dsg_environment/azure-vms/fetch_lanl_summary_data.sh new file mode 100755 index 0000000000..d2ddaeeff9 --- /dev/null +++ b/new_dsg_environment/azure-vms/fetch_lanl_summary_data.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +# Constants for colourised output +BOLD="\033[1m" +RED="\033[0;31m" +BLUE="\033[0;36m" +END="\033[0m" + +SUMMARY_DATA_DIR=summary-dataset-2017 + +# Document usage for this script +print_usage_and_exit() { + echo "usage: $0 -d destination_directory [-h]" + echo " -h display help" + echo " -d destination_directory specify the directory in which to create a '$SUMMARY_DATA_DIR' containing the LANL summary data" + exit 1 +} + +# Read command line arguments, overriding defaults where necessary +while getopts "d:h" opt; do + case $opt in + d) + DESTINATION_DIR=$OPTARG + ;; + h) + print_usage_and_exit + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + ;; + esac +done + +# Check that a DSG group ID has been provided +if [ "$DESTINATION_DIR" = "" ]; then + echo -e "${RED}Destination directory is a required argument!${END}" + print_usage_and_exit +fi + +MAIN_DIR=$DESTINATION_DIR/$SUMMARY_DATA_DIR +mkdir -p $MAIN_DIR + +if [ ! -d "$MAIN_DIR" ]; then + echo -e "${RED}Failed to create ${BLUE}${SUMMARY_DATA_DIR}${END} directory in ${BLUE}$DESTINATION_DIR${END}" + print_usage_and_exit +else + echo "${BOLD}Downloading summary date to ${BLUE}${MAIN_DIR}${END}" +fi + +# Fetch red team summary data +mkdir $MAIN_DIR/red_team +wget -c https://dsgimperiallanl.blob.core.windows.net/lanl-data/summary-dataset-2017/red_team/redteam_authentications_summary.txt -O $MAIN_DIR/red_team/redteam_authentications_summary.txt +wget -c https://dsgimperiallanl.blob.core.windows.net/lanl-data/summary-dataset-2017/red_team/redteam_process_summary.txt -O $MAIN_DIR/red_team/redteam_process_summary.txt +wget -c https://dsgimperiallanl.blob.core.windows.net/lanl-data/summary-dataset-2017/red_team/session_hosts.txt -O $MAIN_DIR/red_team/session_hosts.txt + + +# Fetch daily data +mkdir $MAIN_DIR/wls +mkdir $MAIN_DIR/netflow +for i in $(seq -f "%02g" 1 90); do + # wls data + wget -c https://dsgimperiallanl.blob.core.windows.net/lanl-data/summary-dataset-2017/wls/process_wls_summary-${i}.gz -O $MAIN_DIR/wls/authentications_wls_summary-$i.bz2 + wget -c https://dsgimperiallanl.blob.core.windows.net/lanl-data/summary-dataset-2017/wls/process_wls_summary-${i}.gz -O $MAIN_DIR/wls/process_wls_summary-$i.bz2 + # netflow data (missing for day 01) + if [ "$i" != "01" ]; then + wget -c https://dsgimperiallanl.blob.core.windows.net/lanl-data/summary-dataset-2017/netflow/netflow_summary-${i}.gz -O $MAIN_DIR/netflow/netflow_day-$i.bz2 + fi +done diff --git a/new_dsg_environment/azure-vms/register_images_in_gallery.sh b/new_dsg_environment/azure-vms/register_images_in_gallery.sh index 096078b527..83ee9e1ca7 100755 --- a/new_dsg_environment/azure-vms/register_images_in_gallery.sh +++ b/new_dsg_environment/azure-vms/register_images_in_gallery.sh @@ -14,7 +14,7 @@ BLUE="\033[0;36m" END="\033[0m" # Other constants -SUPPORTEDIMAGES=("ComputeVM-DataScienceBase" "ComputeVM-Ubuntu1804Base" "ComputeVM-UbuntuTorch1804Base") +SUPPORTEDIMAGES=("ComputeVM-DataScienceBase" "ComputeVM-Ubuntu1804Base" "ComputeVM-UbuntuTorch1804Base" "ComputeVM-DsgBase") GALLERYNAME="SIG_SH_COMPUTE" # must be unique within this subscription VERSIONMAJOR="0" VERSIONMINOR="0" diff --git a/new_dsg_environment/azure-vms/transfer_lanl_data_to_azure.sh b/new_dsg_environment/azure-vms/transfer_lanl_data_to_azure.sh new file mode 100755 index 0000000000..84c1ee0ecd --- /dev/null +++ b/new_dsg_environment/azure-vms/transfer_lanl_data_to_azure.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +# Constants for colourised output +BOLD="\033[1m" +RED="\033[0;31m" +BLUE="\033[0;36m" +END="\033[0m" + +# Environment +SUBSCRIPTION="DSG - Imperial/LANL" +STORAGE_ACCOUNT="dsgimperiallanl" +STORAGE_CONTAINER="lanl-data" + +# Ensure we are using the right subscritpion +az account set --subscription "$SUBSCRIPTION" +# Generate SAS token +SAS_EXPIRY=$(date -v+2d '+%Y-%m-%dT%H:%MZ') +SAS_PERMISSIONS="rw" +SAS_SERVICES="b" +SAS_RESOURCE_TYPES="co" + +REQUEST_DELAY=0.5 +# Transfer netflow data (2-90) +echo "" +echo "Transferring netflow data" +echo "=========================" +for i in $(seq -f "%02g" 2 90); do + SOURCE_URL="https://csr.lanl.gov/data/unified-host-network-dataset-2017/netflow/netflow_day-$i.bz2" + BLOB_NAME="unified-host-network-dataset-2017/netflow/netflow_day-$i.bz2" + BLOB_EXISTS="$(az storage blob exists --account-name $STORAGE_ACCOUNT --container-name $STORAGE_CONTAINER --name $BLOB_NAME --query 'exists' | xargs echo)" + + echo -n "- netflow ${i}: ${BLOB_NAME}..." + if [ "$BLOB_EXISTS" = "false" ]; then + echo -n "starting copy..." + RESULT=$(az storage blob copy start \ + --account-name $STORAGE_ACCOUNT \ + --destination-blob $BLOB_NAME \ + --destination-container $STORAGE_CONTAINER \ + --source-uri $SOURCE_URL --query 'status') + echo "done (status = $RESULT)" + else + COPY_STATUS=$(az storage blob show --account-name $STORAGE_ACCOUNT --container-name $STORAGE_CONTAINER --name $BLOB_NAME --query "join(' - copied ', [properties.copy.status, properties.copy.progress])" | xargs echo) + echo "skipping (copy status: $COPY_STATUS)" + fi + # Throttle requests to avoid failures due to Azure throttling us + sleep REQUEST_DELAY +done + +# Transfer wls data (1-90) +echo "" +echo "Transferring wls data" +echo "======================" +for i in $(seq -f "%02g" 1 90); do + SOURCE_URL="https://csr.lanl.gov/data/unified-host-network-dataset-2017/wls/wls_day-$i.bz2" + BLOB_NAME="unified-host-network-dataset-2017/wls/wls_day-$i.bz2" + BLOB_EXISTS="$(az storage blob exists --account-name $STORAGE_ACCOUNT --container-name $STORAGE_CONTAINER --name $BLOB_NAME --query 'exists' | xargs echo)" + + echo -n " - wls ${i}: ${BLOB_NAME}..." + if [ "$BLOB_EXISTS" = "false" ]; then + echo -n "starting copy..." + RESULT=$(az storage blob copy start \ + --account-name $STORAGE_ACCOUNT \ + --destination-blob $BLOB_NAME \ + --destination-container $STORAGE_CONTAINER \ + --source-uri $SOURCE_URL --query 'status') + echo "done (status = $RESULT)" + else + COPY_STATUS=$(az storage blob show --account-name $STORAGE_ACCOUNT --container-name $STORAGE_CONTAINER --name $BLOB_NAME --query "join(' - copied ', [properties.copy.status, properties.copy.progress])" | xargs echo) + echo "skipping (copy status: $COPY_STATUS)" + fi + # Throttle requests to avoid failures due to Azure throttling us + sleep REQUEST_DELAY +done diff --git a/new_dsg_environment/infrastructure/Azure-Peering-Network.ps1 b/new_dsg_environment/infrastructure/Azure-Peering-Network.ps1 new file mode 100644 index 0000000000..71ded57ccf --- /dev/null +++ b/new_dsg_environment/infrastructure/Azure-Peering-Network.ps1 @@ -0,0 +1,17 @@ +# Subscription IDs required and user performing the task needs to have access to other subscriptions and logged into both + +# Safe Haven Management Subscription +$vNetA= Get-AzureRmVirtualNetwork -Name LOCALVNETNAME -ResourceGroupName VNETRESOURCE GROUP + Add-AzureRmVirtualNetworkPeering ` + -Name 'PEER_TARGETNETWORKNAME' ` #VNET in DSG subscription + -VirtualNetwork $vNetA ` + -RemoteVirtualNetworkId "/subscriptions/DSGSubscriptionId>/resourceGroups/VNETResourceGroup/providers/Microsoft.Network/virtualNetworks/TARGETNETWORKNAME" + + +# DSG Subscription +$vNetB = Get-AzureRmVirtualNetwork -Name LOCALVNETNAME -ResourceGroupName VNETRESOURCE GROUP + Add-AzureRmVirtualNetworkPeering ` + -Name 'PEER_TARGETNETWORKNAME' ` #VNET in Safe Haven Mangement subscription + -VirtualNetwork $vNetB ` + -RemoteVirtualNetworkId "/subscriptions/SafeHavenManagmentSubscriptionId>/resourceGroups/VNETResourceGroup/providers/Microsoft.Network/virtualNetworks/TARGETNETWORKNAME" + diff --git a/new_dsg_environment/infrastructure/Create_SafeHavenManagement_VNET.ps1 b/new_dsg_environment/infrastructure/Create_SafeHavenManagement_VNET.ps1 new file mode 100644 index 0000000000..a2702ce02c --- /dev/null +++ b/new_dsg_environment/infrastructure/Create_SafeHavenManagement_VNET.ps1 @@ -0,0 +1,88 @@ +#VNet Name +$vnetname = "SHM_VNET1" #UPDATE NAME BEFORE RUNNING! + +#VNet configuration +$rg = "RG_SHM_VNET" +$region = "UK South" +$subnetid = "Subnet-Identity" +$subnetweb = "Subnet-Web" +$subnetgw = "GatewaySubnet" + +$vnetprefix = "10.251.0.0/21" +$idsubprefix = "10.251.0.0/24" +$websubprefix = "10.251.1.0/24" +$gwsubprefix = "10.251.7.0/27" +$VPNClientAddressPool = "172.16.201.0/24" +$GWName = "SHM_VNET1_GW" +$GWIPName = "SHM_VNET1_GW_PIP" +$GWIPconfName = "shmgwipconf" + + +#Select subscription +write-Host -ForegroundColor Cyan "Select the correct subscription..." +$subscription = ( + Get-AzureRmSubscription | + Sort-Object -Property Name | + Select-Object -Property Name,Id | + Out-GridView -OutputMode Single -Title 'Select an subscription' +).name + +Select-AzureRmSubscription -SubscriptionName $subscription +write-Host -ForegroundColor Green "Ok, lets go!" + +Read-Host -Prompt "Check that the subscription has been selected above, press enter key to continue or Ctrl+C to abort" + + +#Create Virtual Network Resource Group +write-Host -ForegroundColor Cyan "Creating resouce group...." +New-AzureRmResourceGroup -Name $rg -Location $region +write-Host -ForegroundColor Green "Done!" + +#Create Subnet configuration +write-Host -ForegroundColor Cyan "Creating subnets...." +$idsub = New-AzureRmVirtualNetworkSubnetConfig -Name $subnetid -AddressPrefix $idsubprefix +$websub = New-AzureRmVirtualNetworkSubnetConfig -Name $subnetweb -AddressPrefix $websubprefix +$gwsub = New-AzureRmVirtualNetworkSubnetConfig -Name $subnetgw -AddressPrefix $gwsubprefix +write-Host -ForegroundColor Green "Done!" + +#Create Virtual Network +write-Host -ForegroundColor Cyan "Creating virtual network...." +New-AzureRmVirtualNetwork -Name $vnetname -ResourceGroupName $rg -Location $region -AddressPrefix $vnetprefix -Subnet $idsub, $websub, $gwsub +$vnet = Get-AzureRmVirtualNetwork -Name $vnetname -ResourceGroupName $rg +$subnet = Get-AzureRmVirtualNetworkSubnetConfig -Name "GatewaySubnet" -VirtualNetwork $vnet +write-Host -ForegroundColor Green "Done!" + +#Create public IP address +write-Host -ForegroundColor Cyan "Creating public IP address...." +$pip = New-AzureRmPublicIpAddress -Name $GWIPName -ResourceGroupName $RG -Location $region -AllocationMethod Dynamic +$ipconf = New-AzureRmVirtualNetworkGatewayIpConfig -Name $GWIPconfName -Subnet $subnet -PublicIpAddress $pip +write-Host -ForegroundColor Green "Done!" + +#Create VPN Gateway +write-Host -ForegroundColor Cyan "Creating virtual gateway..." +New-AzureRmVirtualNetworkGateway -Name $GWName ` + -ResourceGroupName $RG ` + -Location $region ` + -IpConfigurations $ipconf ` + -GatewayType Vpn ` + -VpnType RouteBased ` + -EnableBgp $false ` + -GatewaySku VpnGw1 ` + -VpnClientProtocol "SSTP" +write-Host -ForegroundColor Green "Done!" + +#Add VPN client address Pool +write-Host -ForegroundColor Cyan "Creating client address pool...." +$Gateway = Get-AzureRmVirtualNetworkGateway -ResourceGroupName $RG -Name $GWName +Set-AzureRmVirtualNetworkGateway -VirtualNetworkGateway $Gateway -VpnClientAddressPool $VPNClientAddressPool +write-Host -ForegroundColor Green "Done!" + +#Upload certificate +write-Host -ForegroundColor Cyan "Uploading certificate...." +$P2SRootCertName = "ATISafeHaven-P2SRootCert.cer" +$filePathForCert = "ATISafeHaven-P2SRootCert.cer" +$cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2($filePathForCert) +$CertBase64 = [system.convert]::ToBase64String($cert.RawData) +$p2srootcert = New-AzureRmVpnClientRootCertificate -Name $P2SRootCertName -PublicCertData $CertBase64 +Add-AzureRmVpnClientRootCertificate -VpnClientRootCertificateName $P2SRootCertName -VirtualNetworkGatewayname $GWName -ResourceGroupName $RG -PublicCertData $CertBase64 +write-Host -ForegroundColor Green "VNet and VPN Gateway Done!"