Skip to content

Commit

Permalink
Merge pull request #3 from jpfulton:linux-vm
Browse files Browse the repository at this point in the history
Linux-vm
  • Loading branch information
jpfulton authored Aug 17, 2023
2 parents 0481b74 + 3e8f206 commit a5179df
Show file tree
Hide file tree
Showing 13 changed files with 711 additions and 3 deletions.
61 changes: 61 additions & 0 deletions bicep/linux-server.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
@description('Bool to determine if the vm will be created as a spot instance.')
param isSpot bool = true

@description('Name for the virtual machine.')
param serverName string

@description('Size for the virtual machine. Allowed SKUs support nested virtualization for the WSL.')
@allowed([
'Standard_DS1_v2'
'Standard_DS2_v2'
'Standard_DS3_v2'
'Standard_DS4_v2'
'Standard_DS5_v2'
'Standard_D2s_v3'
'Standard_D4s_v3'
'Standard_D8s_v3'
'Standard_D16s_v3'
'Standard_D32s_v3'
'Standard_D48s_v3'
'Standard_D64s_v3'
])
param vmSize string = 'Standard_DS1_v2'

@description(
'''Region for the virtual machine and associated resources.
Allowed values include US regions.
Defaults to the region of the resource group.
'''
)
param location string = resourceGroup().location

@description('Name of the virtual network for this VM to attach to.')
param vnetName string = 'personal-network-vnet'

@description('Admin username.')
param adminUsername string = 'jpfulton'

@description('Public key data for the admin user.')
param adminPublicKeyData string

module nicModule 'modules/nic.bicep' = {
name: 'nic-deploy'
params: {
location: location
serverName: serverName
vnetName: vnetName
}
}

module vmModule 'modules/linux-server/vm.bicep' = {
name: 'vm-deploy'
params: {
adminUsername: adminUsername
adminPublicKeyData: adminPublicKeyData
location: location
nicId: nicModule.outputs.nicId
serverName: serverName
vmSize: vmSize
isSpot: isSpot
}
}
7 changes: 7 additions & 0 deletions bicep/linux-server.bicepparam
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using './linux-server.bicep'

param isSpot = bool(readEnvironmentVariable('IS_SPOT', 'true'))
param serverName = readEnvironmentVariable('SERVER_NAME')
param vmSize = readEnvironmentVariable('VM_SIZE')
param adminUsername = readEnvironmentVariable('ADMIN_USERNAME')
param adminPublicKeyData = readEnvironmentVariable('ADMIN_PUBLIC_KEY')
152 changes: 152 additions & 0 deletions bicep/modules/linux-server/vm.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
@description('Server name for the virtual machine.')
param serverName string

@description('Region for the resources. Allowed values include US regions.')
@allowed([
'centralus'
'eastus'
'eastus2'
'eastus3'
'northcentralus'
'southcentralus'
'westcentralus'
])
param location string

@description('Admin account user name.')
param adminUsername string

@description('Resource Id of the NIC to associate with the virtual machine.')
param nicId string

@description('Size for the virtual machine.')
@allowed([
'Standard_DS1_v2'
'Standard_DS2_v2'
'Standard_DS3_v2'
'Standard_DS4_v2'
'Standard_DS5_v2'
'Standard_D2s_v3'
'Standard_D4s_v3'
'Standard_D8s_v3'
'Standard_D16s_v3'
'Standard_D32s_v3'
'Standard_D48s_v3'
'Standard_D64s_v3'
])
param vmSize string = 'Standard_DS1_v2'

@description('Indicates if this vm instance should be a spot instance.')
param isSpot bool = true

@description('Public key of the admin user.')
param adminPublicKeyData string

// configuration properties required for spot instance creation
var spotConfig = {
priority: 'Spot'
evictionPolicy: 'Deallocate'
billingProfile: {
maxPrice: -1
}
}

// configuration properties required for standard instance creation
var standardConfig = {
priority: 'Regular'
}

// core virtual machine properties
var coreVmProperties = {
hardwareProfile: {
vmSize: vmSize
}
storageProfile: {
imageReference: {
publisher: 'canonical'
offer: '0001-com-ubuntu-server-jammy'
sku: '22_04-lts-gen2'
version: 'latest'
}
osDisk: {
osType: 'Linux'
name: '${serverName}_OsDisk'
createOption: 'FromImage'
caching: 'ReadWrite'
managedDisk: {
storageAccountType: 'Standard_LRS'
}
deleteOption: 'Delete'
diskSizeGB: 32
}
dataDisks: []
diskControllerType: 'SCSI'
}
osProfile: {
computerName: serverName
adminUsername: adminUsername
linuxConfiguration: {
disablePasswordAuthentication: true
ssh: {
publicKeys: [
{
path: '/home/${adminUsername}/.ssh/authorized_keys'
keyData: adminPublicKeyData
}
]
}
provisionVMAgent: true
patchSettings: {
patchMode: 'ImageDefault'
assessmentMode: 'ImageDefault'
}
enableVMAgentPlatformUpdates: false
}
secrets: []
allowExtensionOperations: true
}
securityProfile: {
uefiSettings: {
secureBootEnabled: true
vTpmEnabled: true
}
encryptionAtHost: true
securityType: 'TrustedLaunch'
}
networkProfile: {
networkInterfaces: [
{
id: nicId
properties: {
deleteOption: 'Delete'
}
}
]
}
diagnosticsProfile: {
bootDiagnostics: {
enabled: true
}
}
}

resource virtualMachine 'Microsoft.Compute/virtualMachines@2023-03-01' = {
name: serverName
location: location
identity: {
type: 'SystemAssigned'
}
properties: isSpot ? union(coreVmProperties, spotConfig) : union(coreVmProperties, standardConfig)
}

resource AADSSHLoginForLinuxExtension 'Microsoft.Compute/virtualMachines/extensions@2023-03-01' = {
parent: virtualMachine
name: 'AADSSHLoginForLinux'
location: location
properties: {
publisher: 'Microsoft.Azure.ActiveDirectory'
type: 'AADSSHLoginForLinux'
typeHandlerVersion: '1.0'
autoUpgradeMinorVersion: true
}
}
5 changes: 2 additions & 3 deletions bicep/modules/nic.bicep
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@description('Server name for the virtual machine.')
@maxLength(15)
param serverName string

@description('Region for the resources. Allowed values include US regions.')
Expand All @@ -21,11 +20,11 @@ param vnetName string
param subnetName string = 'default'

var publicIpAddressName = '${serverName}-public-ip'
var publicIPAddressType = 'Dynamic'
var publicIPAddressType = 'Static'

resource publicIp 'Microsoft.Network/publicIPAddresses@2021-03-01' = {
sku: {
name: 'Basic'
name: 'Standard'
}
name: publicIpAddressName
location: location
Expand Down
3 changes: 3 additions & 0 deletions linux-scripts/clean-up.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

rm -f *;
18 changes: 18 additions & 0 deletions linux-scripts/setup-eviction-shutdown-system.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash

BASE_REPO_URL="https://raw.githubusercontent.com/jpfulton/example-linux-configs/main";

# Set up eviction query and shutdown script
EVICTION_QUERY_CRON_SNIPPET_FILE="preempt-query";
EVICTION_QUERY_SCRIPT="query-for-preempt-event.sh";
echo "Setting up eviction query script...";

sudo wget -q ${BASE_REPO_URL}/usr/local/sbin/${EVICTION_QUERY_SCRIPT};
sudo chmod ug+x ./${EVICTION_QUERY_SCRIPT}
sudo mv ./${EVICTION_QUERY_SCRIPT} /usr/local/sbin/

sudo wget -q ${BASE_REPO_URL}/etc/cron.d/${EVICTION_QUERY_CRON_SNIPPET_FILE};
sudo mv ./${EVICTION_QUERY_CRON_SNIPPET_FILE} /etc/cron.d/

echo "---";
echo;
24 changes: 24 additions & 0 deletions linux-scripts/setup-firewall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

BASE_REPO_URL="https://raw.githubusercontent.com/jpfulton/example-linux-configs/main";

# Set up local firewall basics
DEFAULTS_PATH="/etc/default/";
UFW_DEFAULTS_FILE="ufw";
if [ $(sudo ufw status | grep -c inactive) -ge 1 ]
then
echo "Local firewall is inactive. Configuring and enabling with SSH rule...";

sudo wget -q ${BASE_REPO_URL}${DEFAULTS_PATH}${UFW_DEFAULTS_FILE} -O ${UFW_DEFAULTS_FILE};
sudo mv ${UFW_DEFAULTS_FILE} ${DEFAULTS_PATH};

sudo ufw allow ssh;
sudo ufw show added;
sudo ufw --force enable;
sudo ufw status numbered;

else
echo "Local fireall is active. No configuration or rules applied.";
fi
echo "---";
echo;
20 changes: 20 additions & 0 deletions linux-scripts/setup-motd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash

DEBIAN_FRONTEND="noninteractive";
BASE_REPO_URL="https://raw.githubusercontent.com/jpfulton/example-linux-configs/main";

# Set up custom MOTD script
MOTD_PATH="/etc/update-motd.d/";
MOTD_FILE="01-custom";
if [ ! -f ${MOTD_PATH}${MOTD_FILE} ]
then
echo "Setting up custom MOTD script...";

sudo -E apt-get install -y neofetch inxi;
sudo wget -q ${BASE_REPO_URL}${MOTD_PATH}${MOTD_FILE} -O ${MOTD_FILE};
sudo chmod a+x ./${MOTD_FILE};
sudo mv ./${MOTD_FILE} ${MOTD_PATH}${MOTD_FILE};

echo "---";
echo;
fi
53 changes: 53 additions & 0 deletions linux-scripts/setup-node-and-yarn.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash

DEBIAN_FRONTEND="noninteractive";
BASE_REPO_URL="https://raw.githubusercontent.com/jpfulton/example-linux-configs/main";

setup-nodejs () {
# Install Node as needed
which node >> /dev/null;
if [ $? -eq 0 ]
then
local NODE_VERSION=$(node --version);
if [ $NODE_VERSION == "v12.22.9" ]
then
echo "Default node package detected. Removing.";
sudo -E apt-get remove nodejs;
sudo -E apt-get autoremove;
else
echo "Detected alternate version of node: ${NODE_VERSION}";
echo "Ensure that version is above v18.0.0 or manually use nvm.";
fi
else
echo "Node not detected. Preparing installation of node v18.x.";

sudo curl -sL https://deb.nodesource.com/setup_18.x | sudo bash -;
sudo -E apt-get install -y nodejs;
fi

echo "---";
echo;
}

setup-yarn () {
# Install Yarn as needed
which yarn >> /dev/null;
if [ $? -eq 1 ]
then
echo "Yarn not detected. Preparing to install.";

sudo curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null;
sudo echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list;
sudo -E apt-get update;
sudo -E apt-get install -y yarn;
else
local YARN_VERSION=$(yarn --version);
echo "Found yarn version: ${YARN_VERSION}";
fi

echo "---";
echo;
}

setup-nodejs;
setup-yarn;
Loading

0 comments on commit a5179df

Please sign in to comment.