From 4a42fbea35167de1b139dad95405189f3b3e8e69 Mon Sep 17 00:00:00 2001 From: Jack Ivanov <17044561+jackivanov@users.noreply.github.com> Date: Mon, 17 Sep 2018 03:19:29 +0300 Subject: [PATCH] Move to the ARM deployment schema (#1107) --- CHANGELOG.md | 4 + config.cfg | 6 +- roles/cloud-azure/defaults/main.yml | 2 +- roles/cloud-azure/files/deployment.json | 209 ++++++++++++++++++++++++ roles/cloud-azure/tasks/main.yml | 135 +++------------ roles/cloud-azure/tasks/prompts.yml | 10 +- 6 files changed, 245 insertions(+), 121 deletions(-) create mode 100644 roles/cloud-azure/files/deployment.json diff --git a/CHANGELOG.md b/CHANGELOG.md index e7f566a..417b757 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 7 Sep 2018 +### Changed +- Azure: Deployment via Azure Resource Manager + ## 27 Aug 2018 ### Changed - Large refactor to support Ansible 2.5. [Details](https://github.com/trailofbits/algo/pull/976) diff --git a/config.cfg b/config.cfg index c838a64..0967d26 100644 --- a/config.cfg +++ b/config.cfg @@ -95,11 +95,7 @@ SSH_keys: cloud_providers: azure: size: Basic_A0 - image: - offer: UbuntuServer - publisher: Canonical - sku: '18.04-LTS' - version: latest + image: 18.04-LTS digitalocean: size: s-1vcpu-1gb image: "ubuntu-18-04-x64" diff --git a/roles/cloud-azure/defaults/main.yml b/roles/cloud-azure/defaults/main.yml index 9170a15..cd5301d 100644 --- a/roles/cloud-azure/defaults/main.yml +++ b/roles/cloud-azure/defaults/main.yml @@ -1,5 +1,5 @@ --- -azure_regions: > +_azure_regions: > [ { "displayName": "East Asia", diff --git a/roles/cloud-azure/files/deployment.json b/roles/cloud-azure/files/deployment.json new file mode 100644 index 0000000..646ea8a --- /dev/null +++ b/roles/cloud-azure/files/deployment.json @@ -0,0 +1,209 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "AlgoServerName": { + "type": "string" + }, + "sshKeyData": { + "type": "string" + }, + "location": { + "type": "string" + }, + "WireGuardPort": { + "type": "int" + }, + "vmSize": { + "type": "string" + }, + "imageReferenceSku": { + "type": "string" + } + }, + "variables": { + "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', parameters('AlgoServerName'))]", + "subnet1Ref": "[concat(variables('vnetID'),'/subnets/', parameters('AlgoServerName'))]" + }, + "resources": [ + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/networkSecurityGroups", + "name": "[parameters('AlgoServerName')]", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "AllowSSH", + "properties": { + "description": "Locks inbound down to ssh default port 22.", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "22", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 100, + "direction": "Inbound" + } + }, + { + "name": "AllowIPSEC500", + "properties": { + "description": "Allow UDP to port 500", + "protocol": "Udp", + "sourcePortRange": "*", + "destinationPortRange": "500", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 110, + "direction": "Inbound" + } + }, + { + "name": "AllowIPSEC4500", + "properties": { + "description": "Allow UDP to port 4500", + "protocol": "Udp", + "sourcePortRange": "*", + "destinationPortRange": "4500", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 120, + "direction": "Inbound" + } + }, + { + "name": "AllowWireGuard", + "properties": { + "description": "Locks inbound down to ssh default port 22.", + "protocol": "Udp", + "sourcePortRange": "*", + "destinationPortRange": "[parameters('WireGuardPort')]", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 130, + "direction": "Inbound" + } + } + ] + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/publicIPAddresses", + "name": "[parameters('AlgoServerName')]", + "location": "[parameters('location')]", + "properties": { + "publicIPAllocationMethod": "Static" + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/virtualNetworks", + "name": "[parameters('AlgoServerName')]", + "location": "[parameters('location')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "10.10.0.0/16" + ] + }, + "subnets": [ + { + "name": "[parameters('AlgoServerName')]", + "properties": { + "addressPrefix": "10.10.0.0/24" + } + } + ] + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/networkInterfaces", + "name": "[parameters('AlgoServerName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkSecurityGroups/', parameters('AlgoServerName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('AlgoServerName'))]", + "[concat('Microsoft.Network/virtualNetworks/', parameters('AlgoServerName'))]" + ], + "properties": { + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('AlgoServerName'))]" + }, + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('AlgoServerName'))]" + }, + "subnet": { + "id": "[variables('subnet1Ref')]" + } + } + } + ] + } + }, + { + "apiVersion": "2016-04-30-preview", + "type": "Microsoft.Compute/virtualMachines", + "name": "[parameters('AlgoServerName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', parameters('AlgoServerName'))]" + ], + "properties": { + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "osProfile": { + "computerName": "[parameters('AlgoServerName')]", + "adminUsername": "ubuntu", + "linuxConfiguration": { + "disablePasswordAuthentication": true, + "ssh": { + "publicKeys": [ + { + "path": "/home/ubuntu/.ssh/authorized_keys", + "keyData": "[parameters('sshKeyData')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "publisher": "Canonical", + "offer": "UbuntuServer", + "sku": "[parameters('imageReferenceSku')]", + "version": "latest" + }, + "osDisk": { + "createOption": "FromImage" + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('AlgoServerName'))]" + } + ] + } + } + } + ], + "outputs": { + "publicIPAddresses": { + "type": "string", + "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses',parameters('AlgoServerName')),providers('Microsoft.Network', 'publicIPAddresses').apiVersions[0]).ipAddress]", + } + } +} diff --git a/roles/cloud-azure/tasks/main.yml b/roles/cloud-azure/tasks/main.yml index 682fcb3..27e2def 100644 --- a/roles/cloud-azure/tasks/main.yml +++ b/roles/cloud-azure/tasks/main.yml @@ -4,123 +4,38 @@ import_tasks: prompts.yml - set_fact: - resource_group: "Algo_{{ region }}" - secret: "{{ azure_secret | default(lookup('env','AZURE_SECRET'), true) }}" - tenant: "{{ azure_tenant | default(lookup('env','AZURE_TENANT'), true) }}" - client_id: "{{ azure_client_id | default(lookup('env','AZURE_CLIENT_ID'), true) }}" - subscription_id: "{{ azure_subscription_id | default(lookup('env','AZURE_SUBSCRIPTION_ID'), true) }}" + algo_region: >- + {% if region is defined %}{{ region }} + {%- elif _algo_region.user_input is defined and _algo_region.user_input != "" %}{{ azure_regions[_algo_region.user_input | int -1 ]['name'] }} + {%- else %}{{ azure_regions[default_region | int - 1]['name'] }}{% endif %} - - name: Create a resource group - azure_rm_resourcegroup: + - name: Create AlgoVPN Server + azure_rm_deployment: + state: present + deployment_name: "AlgoVPN-{{ algo_server_name }}" + template: "{{ lookup('file', 'deployment.json') }}" secret: "{{ secret }}" tenant: "{{ tenant }}" client_id: "{{ client_id }}" subscription_id: "{{ subscription_id }}" - name: "{{ resource_group }}" - location: "{{ region }}" - tags: - Environment: Algo - - - name: Create a virtual network - azure_rm_virtualnetwork: - secret: "{{ secret }}" - tenant: "{{ tenant }}" - client_id: "{{ client_id }}" - subscription_id: "{{ subscription_id }}" - resource_group: "{{ resource_group }}" - name: algo_net - address_prefixes: "10.10.0.0/16" - tags: - Environment: Algo - - - name: Create a security group - azure_rm_securitygroup: - secret: "{{ secret }}" - tenant: "{{ tenant }}" - client_id: "{{ client_id }}" - subscription_id: "{{ subscription_id }}" - resource_group: "{{ resource_group }}" - name: AlgoSecGroup - purge_rules: yes - rules: - - name: AllowSSH - protocol: Tcp - destination_port_range: 22 - access: Allow - priority: 100 - direction: Inbound - - name: AllowIPSEC500 - protocol: Udp - destination_port_range: 500 - access: Allow - priority: 110 - direction: Inbound - - name: AllowIPSEC4500 - protocol: Udp - destination_port_range: 4500 - access: Allow - priority: 120 - direction: Inbound - - name: AllowWireGuard - protocol: Udp - destination_port_range: "{{ wireguard_port }}" - access: Allow - priority: 130 - direction: Inbound - - - name: Create a subnet - azure_rm_subnet: - secret: "{{ secret }}" - tenant: "{{ tenant }}" - client_id: "{{ client_id }}" - subscription_id: "{{ subscription_id }}" - resource_group: "{{ resource_group }}" - name: algo_subnet - address_prefix: "10.10.0.0/24" - virtual_network: algo_net - security_group_name: AlgoSecGroup - tags: - Environment: Algo - - - name: Create an instance - azure_rm_virtualmachine: - secret: "{{ secret }}" - tenant: "{{ tenant }}" - client_id: "{{ client_id }}" - subscription_id: "{{ subscription_id }}" - resource_group: "{{ resource_group }}" - admin_username: ubuntu - virtual_network: algo_net - name: "{{ azure_server_name }}" - ssh_password_enabled: false - vm_size: "{{ cloud_providers.azure.size }}" - tags: - Environment: Algo - ssh_public_keys: - - { path: "/home/ubuntu/.ssh/authorized_keys", key_data: "{{ lookup('file', '{{ SSH_keys.public }}') }}" } - image: "{{ cloud_providers.azure.image }}" - register: azure_rm_virtualmachine - - # To-do: Add error handling - if vm_size requested is not available, can we fall back to another, ideally with a prompt? + resource_group_name: "AlgoVPN-{{ algo_server_name }}" + parameters: + AlgoServerName: + value: "{{ algo_server_name }}" + sshKeyData: + value: "{{ lookup('file', '{{ SSH_keys.public }}') }}" + location: + value: "{{ algo_region }}" + WireGuardPort: + value: "{{ wireguard_port }}" + vmSize: + value: "{{ cloud_providers.azure.size }}" + imageReferenceSku: + value: "{{ cloud_providers.azure.image }}" + register: azure_rm_deployment - set_fact: - ip_address: "{{ azure_rm_virtualmachine.ansible_facts.azure_vm.properties.networkProfile.networkInterfaces[0].properties.ipConfigurations[0].properties.publicIPAddress.properties.ipAddress }}" - networkinterface_name: "{{ azure_rm_virtualmachine.ansible_facts.azure_vm.properties.networkProfile.networkInterfaces[0].name }}" - - - name: Ensure the network interface includes all required parameters - azure_rm_networkinterface: - secret: "{{ secret }}" - tenant: "{{ tenant }}" - client_id: "{{ client_id }}" - subscription_id: "{{ subscription_id }}" - name: "{{ networkinterface_name }}" - resource_group: "{{ resource_group }}" - virtual_network_name: algo_net - subnet_name: algo_subnet - security_group_name: AlgoSecGroup - - - set_fact: - cloud_instance_ip: "{{ ip_address }}" + cloud_instance_ip: "{{ azure_rm_deployment.deployment.outputs.publicIPAddresses.value }}" ansible_ssh_user: ubuntu rescue: diff --git a/roles/cloud-azure/tasks/prompts.yml b/roles/cloud-azure/tasks/prompts.yml index aadffd6..28d4252 100644 --- a/roles/cloud-azure/tasks/prompts.yml +++ b/roles/cloud-azure/tasks/prompts.yml @@ -48,20 +48,20 @@ - block: - name: Set facts about the regions set_fact: - aws_regions: "{{ azure_regions | sort(attribute='region_name') }}" + azure_regions: "{{ _azure_regions|from_json | sort(attribute='name') }}" - name: Set the default region set_fact: default_region: >- - {% for r in aws_regions %} - {%- if r['region_name'] == "us-east-1" %}{{ loop.index }}{% endif %} + {% for r in azure_regions %} + {%- if r['name'] == "eastus" %}{{ loop.index }}{% endif %} {%- endfor %} - pause: prompt: | What region should the server be located in? - {% for r in aws_regions %} - {{ loop.index }}. {{ r['region_name'] }} + {% for r in azure_regions %} + {{ loop.index }}. {{ r['displayName'] }} {% endfor %} Enter the number of your desired region