Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Azure Virtual Machine Support #16

Merged
merged 8 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describing the target cloud infrastructure.
| GCloud | Compute Engine - VM |:white_check_mark:|
| GCloud | CloudSQL |:white_check_mark:|
| GCloud | AlloyDB |:white_check_mark:|
| Azure | VM | :x: |
| Azure | VM |:white_check_mark:|
| Azure | Database - Flexible | :x: |
| Azure | CosmosDB | :x: |

Expand Down Expand Up @@ -332,11 +332,12 @@ $ export GOOGLE_PROJECT=<project_id>
```

#### Terraform
Install manually or [use terraform for latest instructions](https://developer.hashicorp.com/terraform/downloads)

```console
$ sudo apt install unzip -y
$ wget https://releases.hashicorp.com/terraform/1.2.6/terraform_1.2.6_linux_amd64.zip
$ unzip terraform_1.2.6_linux_amd64.zip
$ wget https://releases.hashicorp.com/terraform/1.3.6/terraform_1.3.6_linux_amd64.zip
$ unzip terraform_1.3.6_linux_amd64.zip
$ sudo install terraform /usr/bin
```

Expand Down
7 changes: 7 additions & 0 deletions edbterraform/data/templates/azure/agreements.tf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module "agreements" {
source = "./modules/agreement"

publisher = var.operating_system.publisher
offer = var.operating_system.offer
plan = var.operating_system.sku
}
14 changes: 14 additions & 0 deletions edbterraform/data/templates/azure/key_pair.tf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module "key_pair_{{ region_ }}" {
source = "./modules/key_pair"

name = "{{ region }}-${random_id.apply.hex}"
resource_name = module.vpc_{{ region_ }}.resource_name
region = module.vpc_{{ region_ }}.region
public_key = var.ssh_pub_key

depends_on = [module.vpc_{{ region_ }}]

providers = {
azurerm = azurerm.{{ region_ }}
}
}
38 changes: 38 additions & 0 deletions edbterraform/data/templates/azure/machine.tf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module "machine_{{ region_ }}" {
source = "./modules/machine"

for_each = {
for rm in lookup(local.region_machines, "{{ region }}", []) :
rm.name => rm
}

resource_name = module.vpc_{{ region_ }}.resource_name
subnet_id = module.network_{{ region_ }}[each.value.spec.zone].subnet_id
operating_system = var.operating_system
cluster_name = var.cluster_name
machine = (
merge(
each.value.spec,
{name = each.value.name},
{zone = tostring(each.value.spec.zone) == "0" ? null : each.value.spec.zone},
)
)
additional_volumes = try(each.value.spec.additional_volumes, null)
ssh_user = var.ssh_user
private_key = var.ssh_priv_key
public_key_name = module.key_pair_{{ region_ }}.name
name_id = random_id.apply.hex

depends_on = [
module.vpc_{{ region_ }},
module.key_pair_{{ region_ }},
module.network_{{ region_ }},
module.security_{{ region_ }},
module.agreements,
]

providers = {
azurerm = azurerm.{{ region_ }}
}

}
80 changes: 80 additions & 0 deletions edbterraform/data/templates/azure/main.tf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
locals {
region_az_networks = {
for region, region_spec in var.regions: region => {
for zone, network in try(region_spec.zones, {}): zone => network
}
}
region_machines = {
for name, machine_spec in var.machines: machine_spec.region => {
name = name
spec = machine_spec
}...
}
}

resource "random_id" "apply" {
byte_length = 4
}

{% if has_machines %}
{% include "agreements.tf.j2" %}
{% endif %}

{% for region in regions.keys() %}
{% set region_ = region | replace('-', '_') %}

{% if has_regions %}
{% include "network.tf.j2" %}
{% endif %}

{% if has_machines %}
{% include "key_pair.tf.j2" %}

{% include "machine.tf.j2" %}
{% endif %}

{% endfor %}

{% if has_region_peering %}
{% include "region_peering.tf.j2" %}
{% endif %}

resource "local_file" "servers_yml" {
filename = "${abspath(path.root)}/servers.yml"
file_permission = "0600"
content = <<-EOT
---
servers:
{% set boxes = {
'machines': {
'active': has_machines,
'regions': machine_regions,
'module_base': 'module.machine_',
},
} %}
{% for type, attributes in boxes.items() if attributes["active"] %}
{{type}}:
{% for region in attributes["regions"] -%}
{% set module = attributes["module_base"] ~ region | replace('-', '_') %}
%{ for key, value in {{ module }} ~}
${key}:
%{ for name, item in value ~}
${name}: ${try(jsonencode(item), "Error, unsupported type",)}
%{ endfor ~}
%{ endfor ~}
{% endfor %}
{% endfor %}
EOT
}

{% for type, attributes in boxes.items() if attributes["active"] %}
output "{{type}}" {
value = [
{% for region in attributes["regions"] -%}
{% set module = attributes["module_base"] ~ region | replace('-', '_') %}
{{ module }}[*],
{% endfor %}
]
sensitive = true
}
{% endfor %}
56 changes: 56 additions & 0 deletions edbterraform/data/templates/azure/network.tf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
module "vpc_{{ region_ }}"{
source = "./modules/vpc"

name = "${var.vpc_tag}-{{ region }}-${random_id.apply.hex}"
cidr_blocks = [ lookup(lookup(var.regions, "{{ region }}"), "cidr_block") ]
region = "{{ region }}"

providers = {
azurerm = azurerm.{{ region_ }}
}
}

module "network_{{ region_ }}" {
source = "./modules/network"

for_each = lookup(local.region_az_networks, "{{ region }}", null)

resource_name = module.vpc_{{ region_ }}.resource_name
network_name = module.vpc_{{ region_ }}.network_name
region = module.vpc_{{ region_ }}.region
zone = tostring(each.key) == "0" ? null : each.key
ip_cidr_range = [ each.value ]
name = "{{region}}-${each.key}-${random_id.apply.hex}"

depends_on = [module.vpc_{{ region_ }}]

providers = {
azurerm = azurerm.{{ region_ }}
}
}

module "security_{{ region_ }}" {
source = "./modules/security"

for_each = lookup(local.region_az_networks, "{{ region }}", null)

subnet_id = module.network_{{ region_ }}[each.key].subnet_id
region = module.vpc_{{ region_ }}.region
resource_name = module.vpc_{{ region_ }}.resource_name
service_name = "service-{{ region }}-${each.key}-${random_id.apply.hex}"
service_ports = lookup(lookup(var.regions, "{{ region }}", null), "service_ports", [])
public_cidrblock = var.public_cidrblock
region_name = "region-{{ region }}-${each.key}-${random_id.apply.hex}"
region_ports = lookup(lookup(var.regions, "{{ region }}", null), "region_ports", [])
region_cidrblocks = flatten([
for region in try(var.regions, []) : [
for ip_cidr in try(region.zones, []) : ip_cidr
]
])

depends_on = [module.vpc_{{ region_ }}, module.network_{{ region_ }}]

providers = {
azurerm = azurerm.{{ region_ }}
}
}
16 changes: 16 additions & 0 deletions edbterraform/data/templates/azure/providers.tf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
provider "azurerm" {
features {}
}

{% for region in regions.keys() %}
{% set region_ = region | replace('-', '_') %}
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
alias = "{{ region_ }}"
}

{% endfor %}
41 changes: 41 additions & 0 deletions edbterraform/data/templates/azure/region_peering.tf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{% set previous_created = [] %}
{% for (requester, accepter) in peers %}
{% set requester_ = requester|replace('-', '_') %}
{% set accepter_ = accepter|replace('-', '_') %}
module "vpc_peering_{{ requester_ }}_{{ accepter_ }}" {
source = "./modules/vpc_peering"

peering_name = "peer-{{ requester }}-{{ accepter }}-${random_id.apply.hex}"
resource_name = module.vpc_{{ requester_ }}.resource_name
network_name = module.vpc_{{ requester_ }}.network_name
peer_network_id = module.vpc_{{ accepter_ }}.network_id

depends_on = [
module.network_{{ requester_ }},
module.network_{{ accepter_ }},
{% if previous_created %}{{ previous_created[-1] }},{% endif %}
]

providers = {
azurerm = azurerm.{{ requester_ }}
}

}

module "vpc_peering_{{ accepter_ }}_{{ requester_ }}" {
source = "./modules/vpc_peering"

peering_name = "peer-{{ accepter }}-{{ requester }}-${random_id.apply.hex}"
resource_name = module.vpc_{{ accepter_ }}.resource_name
network_name = module.vpc_{{ accepter_ }}.network_name
peer_network_id = module.vpc_{{ requester_ }}.network_id

depends_on = [module.vpc_peering_{{ requester_ }}_{{ accepter_ }}]

providers = {
azurerm = azurerm.{{ accepter_ }}
}

}
{% set dummy = previous_created.append("module.vpc_peering_" + accepter_ + "_" + requester_) %}
{% endfor %}
5 changes: 5 additions & 0 deletions edbterraform/data/terraform/azure/modules/agreement/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "azurerm_marketplace_agreement" "image" {
publisher = var.publisher
offer = var.offer
plan = var.plan
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.37.0"
}
}
required_version = ">= 1.3.6"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
variable "publisher" {}
variable "offer" {}
variable "plan" {}
6 changes: 6 additions & 0 deletions edbterraform/data/terraform/azure/modules/key_pair/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "azurerm_ssh_public_key" "main" {
name = var.name
resource_group_name = var.resource_name
location = var.region
public_key = file(var.public_key)
}
11 changes: 11 additions & 0 deletions edbterraform/data/terraform/azure/modules/key_pair/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
output "name" {
value = azurerm_ssh_public_key.main.name
}

output "public_key" {
value = azurerm_ssh_public_key.main.public_key
}

output "id" {
value = azurerm_ssh_public_key.main.id
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.37.0"
}
}
required_version = ">= 1.3.6"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
variable "name" {}
variable "resource_name" {}
variable "public_key" {}
variable "region" {}
Loading