Sfoglia il codice sorgente

Add first code.

master
jdongmo 3 anni fa
parent
commit
4b6cd5d212
35 ha cambiato i file con 1395 aggiunte e 0 eliminazioni
  1. +49
    -0
      README.md
  2. +88
    -0
      main.tf
  3. +78
    -0
      modules/azure_alert/main.tf
  4. +4
    -0
      modules/azure_alert/outputs.tf
  5. +29
    -0
      modules/azure_alert/variables.tf
  6. +33
    -0
      modules/azure_law/main.tf
  7. +4
    -0
      modules/azure_law/outputs.tf
  8. +14
    -0
      modules/azure_law/variables.tf
  9. +167
    -0
      modules/azure_lb/main.tf
  10. +4
    -0
      modules/azure_lb/outputs.tf
  11. +9
    -0
      modules/azure_lb/variables.tf
  12. +32
    -0
      modules/azure_nsg/main.tf
  13. +4
    -0
      modules/azure_nsg/outputs.tf
  14. +9
    -0
      modules/azure_nsg/variables.tf
  15. +14
    -0
      modules/azure_rg/main.tf
  16. +4
    -0
      modules/azure_rg/outputs.tf
  17. +4
    -0
      modules/azure_rg/variables.tf
  18. +27
    -0
      modules/azure_rtb/main.tf
  19. +9
    -0
      modules/azure_rtb/outputs.tf
  20. +9
    -0
      modules/azure_rtb/variables.tf
  21. +160
    -0
      modules/azure_sa/main.tf
  22. +4
    -0
      modules/azure_sa/outputs.tf
  23. +9
    -0
      modules/azure_sa/variables.tf
  24. +101
    -0
      modules/azure_subnet_link/main.tf
  25. +8
    -0
      modules/azure_subnet_link/outputs.tf
  26. +9
    -0
      modules/azure_subnet_link/variables.tf
  27. +219
    -0
      modules/azure_vm/main.tf
  28. +4
    -0
      modules/azure_vm/outputs.tf
  29. +14
    -0
      modules/azure_vm/variables.tf
  30. +51
    -0
      modules/azure_vnet/main.tf
  31. +4
    -0
      modules/azure_vnet/outputs.tf
  32. +9
    -0
      modules/azure_vnet/variables.tf
  33. +54
    -0
      outputs.tf
  34. +48
    -0
      run.sh
  35. +110
    -0
      variables.tf

+ 49
- 0
README.md Vedi File

@@ -1,2 +1,51 @@
# terraform.azure.automation

Terraform repository to perform automatic tasks in Azure cloud.

## Requirements
First you must have *terraform* installed on host who run your automatism.

To install *terraform*, you should have **wget** and **unzip**.
```bash
sudo apt install wget unzip
```
```bash
wget -O terraform_0.12.20_linux_amd64.zip https://releases.hashicorp.com/terraform/0.12.20/terraform_0.12.20_linux_amd64.zip \
&& wget -O terraform_0.12.20_SHA256SUMS https://releases.hashicorp.com/terraform/0.12.20/terraform_0.12.20_SHA256SUMS \
&& sha256sum --ignore-missing -c terraform_0.12.20_SHA256SUMS \
&& unzip -qn terraform_0.12.20_linux_amd64.zip \
&& mv terraform ${PATH%%:*}/ \
&& rm terraform_0.12.20_linux_amd64.zip terraform_0.12.20_SHA256SUMS
```

To run terraform against Azure cloud, you should have Azure variable
(credentials and location) set in environment

```
$ export ARM_CLIENT_ID="00000000-0000-0000-0000-000000000000"
$ export ARM_CLIENT_CERTIFICATE_PATH="/path/to/my/client/certificate.pfx"
$ export ARM_CLIENT_CERTIFICATE_PASSWORD="Pa55w0rd123"
$ export ARM_SUBSCRIPTION_ID="00000000-0000-0000-0000-000000000000"
$ export ARM_TENANT_ID="00000000-0000-0000-0000-000000000000"
```

## Run
To run terraform, we'll use wrapper script run.sh
To run default infrastructure playbook *infra.tf* who create all the infra
```
./run.sh -v
```
To only play another state file *state.tf*
```
TERRAFORM_FILE=state.tf ./run.sh -v
```

## Docker
We'll have a Dockerfile in order to generate a docker image to use it for
running play in an controled environment.
- Build image: ```docker build -t devops-docker .```
- Run terraform using this image:
```
docker run -e "TERRAFORM_FILE=state.tf" --entrypoint "./run.sh"
devops-docker -v
```

+ 88
- 0
main.tf Vedi File

@@ -0,0 +1,88 @@
terraform {
required_version = "~> 0.12.21"
required_providers {
azurerm = "~> 1.44"
}
}
provider "azurerm" {
subscription_id = var.ARM_SUBSCRIPTION_ID
client_id = var.ARM_CLIENT_ID
client_secret = var.ARM_CLIENT_SECRET
tenant_id = var.ARM_TENANT_ID
}
module "azure_rg" {
source = "./modules/azure_rg"
rgs = var.resource_groups
}
module "azure_sa" {
source = "./modules/azure_sa"
sas = var.storage_accounts
azsa_depends_on = [module.azure_rg.ids]
}
module "azure_nsg" {
source = "./modules/azure_nsg"
nsgs = var.network_security_groups
aznsg_depends_on = [module.azure_rg.ids]
}
module "azure_vnet" {
source = "./modules/azure_vnet"
vnets = var.virtual_networks
azvnet_depends_on = [module.azure_rg.ids, module.azure_nsg.ids]
}
module "azure_rtb" {
source = "./modules/azure_rtb"
rtbs = var.route_tables
azrtb_depends_on = [module.azure_rg.ids]
}
module "azure_subnet_link" {
source = "./modules/azure_subnet_link"
sub_links = var.subnets_associations
azsub_link_depends_on = [module.azure_rg.ids, module.azure_nsg.ids, module.azure_vnet.ids, module.azure_rtb.ids]
}
module "azure_vm" {
source = "./modules/azure_vm"
vms = var.virtual_machines
default_ssh_pubkey = var.ssh_pubkey
azvm_depends_on = [module.azure_rg.ids, module.azure_vnet.ids, module.azure_nsg.ids]
}
module "azure_lb" {
source = "./modules/azure_lb"
lbs = var.load_balancers
azlb_depends_on = [module.azure_rg.ids, module.azure_vnet.ids, module.azure_vm.ids]
}
module "azure_law" {
source = "./modules/azure_law"
laws = var.workspaces
solutions = var.solutions
azlaw_depends_on = [module.azure_rg.ids]
}
module "azure_alert" {
source = "./modules/azure_alert"
vms = var.vms_to_alert
ags = var.action_groups
als = var.alerts
tags = var.tags
rg_name = var.rg_name
azalert_depends_on = [module.azure_rg.ids, module.azure_law.ids]
}

+ 78
- 0
modules/azure_alert/main.tf Vedi File

@@ -0,0 +1,78 @@
terraform {
required_version = "~> 0.12.21"
required_providers {
azurerm = "~> 1.44"
}
}
data "azurerm_virtual_machine" "vm" {
count = length(var.vms)
name = var.vms[count.index].name
resource_group_name = var.vms[count.index].resource_group_name
}
resource "azurerm_monitor_action_group" "azag" {
count = length(var.ags)
name = var.ags[count.index].name
resource_group_name = var.rg_name
short_name = var.ags[count.index].short_name
email_receiver {
name = var.ags[count.index].email_name
email_address = var.ags[count.index].email_address
}
tags = var.tags
}
locals {
alerts = flatten([
for azal in var.als : [
for vm in data.azurerm_virtual_machine.vm : {
name = join(" on ", [azal.name,vm.name])
scopes = vm.id
description = azal.description
frequency = azal.frequency
window_size = azal.window_size
severity = azal.severity
metric_namespace = azal.metric_namespace
metric_name = azal.metric_name
aggregation = azal.aggregation
operator = azal.operator
threshold = azal.threshold
actiongroup_id = azal.actiongroup_id
}
]
])
}
resource "azurerm_monitor_metric_alert" "azalert" {
for_each = {for alert in local.alerts: alert.name => alert}
name = each.key
resource_group_name = var.rg_name
scopes = [ each.value.scopes ]
description = each.value.description
frequency = each.value.frequency
window_size = each.value.window_size
severity = each.value.severity
criteria {
metric_namespace = each.value.metric_namespace
metric_name = each.value.metric_name
aggregation = each.value.aggregation
operator = each.value.operator
threshold = each.value.threshold
}
action {
action_group_id = element(azurerm_monitor_action_group.azag.*.id, each.value.actiongroup_id)
}
tags = var.tags
depends_on = [var.azalert_depends_on]
}

+ 4
- 0
modules/azure_alert/outputs.tf Vedi File

@@ -0,0 +1,4 @@
output "ids" {
value = [for azal in azurerm_monitor_metric_alert.azalert : azal.id]
description = "List of Azure Alert ids."
}

+ 29
- 0
modules/azure_alert/variables.tf Vedi File

@@ -0,0 +1,29 @@
variable "vms" {
type = list
description = "Virtual machine list"
}
variable "ags" {
type = list
description = "Action Group list"
}
variable "als" {
type = list
description = "Alerts list"
}
variable "tags" {
type = map(string)
description = "Tags pour les ressources"
}
variable "rg_name" {
type = string
description = "Resource Group Name"
}
variable "azalert_depends_on" {
type = any
default = null
}

+ 33
- 0
modules/azure_law/main.tf Vedi File

@@ -0,0 +1,33 @@
terraform {
required_version = "~> 0.12.21"
required_providers {
azurerm = "~> 1.44"
}
}
resource "azurerm_log_analytics_workspace" "azlaw" {
count = length(var.laws)
name = var.laws[count.index].name
resource_group_name = var.laws[count.index].resource_group_name
location = var.laws[count.index].location
tags = var.laws[count.index].tags
sku = var.laws[count.index].sku
retention_in_days = var.laws[count.index].retention_in_days
}
resource "azurerm_log_analytics_solution" "solution" {
count = length(var.solutions) * length(var.laws)
solution_name = var.solutions[count.index % length(var.solutions)]
location = azurerm_log_analytics_workspace.azlaw[count.index % length(var.laws)].location
resource_group_name = azurerm_log_analytics_workspace.azlaw[count.index % length(var.laws)].resource_group_name
workspace_resource_id = azurerm_log_analytics_workspace.azlaw[count.index % length(var.laws)].id
workspace_name = azurerm_log_analytics_workspace.azlaw[count.index % length(var.laws)].name
plan {
publisher = "Microsoft"
product = "OMSGallery/${var.solutions[count.index % length(var.solutions)]}"
}
depends_on = [var.azlaw_depends_on]
}

+ 4
- 0
modules/azure_law/outputs.tf Vedi File

@@ -0,0 +1,4 @@
output "ids" {
value = azurerm_log_analytics_workspace.azlaw[*].id
description = "List of workspace ids."
}

+ 14
- 0
modules/azure_law/variables.tf Vedi File

@@ -0,0 +1,14 @@
variable "solutions" {
type = list(string)
default = ["AzureActivity"]
}
variable "laws" {
type = list
description = "List of Log Analytic Workspace definition"
}
variable "azlaw_depends_on" {
type = any
default = null
}

+ 167
- 0
modules/azure_lb/main.tf Vedi File

@@ -0,0 +1,167 @@
terraform {
required_version = "~> 0.12.21"
required_providers {
azurerm = "~> 1.44"
}
}
resource "azurerm_lb" "azlb" {
for_each = var.lbs
name = each.key
resource_group_name = each.value.resource_group_name
location = each.value.location
tags = each.value.tags
sku = try(each.value.sku, "Basic") #Basic or Standard
dynamic "frontend_ip_configuration" {
for_each = try(each.value.frontend_ip_configurations, {})
content {
name = try(frontend_ip_configuration.value.name, join("-ipc", [each.key, index(each.value.frontend_ip_configurations, frontend_ip_configuration)]))
subnet_id = data.azurerm_subnet.sub[frontend_ip_configuration.value.name].id
private_ip_address_allocation = try(frontend_ip_configuration.value.private_ip_address_allocation, "Static") #Static or Dynamic
private_ip_address = try(frontend_ip_configuration.value.private_ip_address_allocation, "Static") == "Static" ? frontend_ip_configuration.value.private_ip_address : null
public_ip_address_id = try(frontend_ip_configuration.value.public_ip_address_id, null)
public_ip_prefix_id = try(frontend_ip_configuration.value.public_ip_prefix_id, null)
zones = try(frontend_ip_configuration.value.zones, null)
}
}
depends_on = [var.azlb_depends_on]
}
locals {
fipcs = flatten([
for lbkey, lb in var.lbs : [
for fipc in try(lb.frontend_ip_configurations, []) : {
name = fipc.name
rules = try(fipc.rules, [])
lb_name = lbkey
resource_group_name = lb.resource_group_name
subnet = {
name = fipc.subnet.name
virtual_network_name = fipc.subnet.virtual_network_name
resource_group_name = try(fipc.subnet.resource_group_name, lb.resource_group_name)
}
}
]
])
}
data "azurerm_subnet" "sub" {
for_each = {for fipc in local.fipcs: fipc.name => fipc}
name = each.value.subnet.name
virtual_network_name = each.value.subnet.virtual_network_name
resource_group_name = each.value.subnet.resource_group_name
depends_on = [var.azlb_depends_on]
}
locals {
bps = flatten([
for lbkey, lb in var.lbs : [
for bp in try(lb.backend_pools, []) : {
name = bp.name
resource_group_name = lb.resource_group_name
lb_name = lbkey
nics = bp.nics
}
]
])
}
resource "azurerm_lb_backend_address_pool" "azlbbpool" {
for_each = {for bp in local.bps: bp.name => bp}
name = each.key
resource_group_name = each.value.resource_group_name
loadbalancer_id = azurerm_lb.azlb[each.value.lb_name].id
}
locals {
rules = flatten([
for fipc in local.fipcs : [
for rule in fipc.rules : {
name = rule.name
resource_group_name = fipc.resource_group_name
lb_name = fipc.lb_name
fipc_name = fipc.name
protocol = rule.protocol # Tcp, Udp or All
frontend_port = rule.frontend_port
backend_port = rule.backend_port
backend_pool_name = rule.backend_pool_name
load_distribution = rule.load_distribution # 'Default', SourceIP, SourceIPProtocol
probe = rule.probe
}
]
])
}
locals {
probes = flatten([
for rule in local.rules : {
name = rule.probe.name
resource_group_name = rule.resource_group_name
lb_name = rule.lb_name
protocol = rule.probe.protocol # Tcp, Http or Https
port = try(rule.probe.port, rule.backend_port)
request_path = try(rule.probe.request_path, null)
}
])
}
resource "azurerm_lb_probe" "azlbprobe" {
for_each = {for probe in local.probes: probe.name => probe}
name = each.key
resource_group_name = each.value.resource_group_name
loadbalancer_id = azurerm_lb.azlb[each.value.lb_name].id
protocol = each.value.protocol
port = each.value.port
request_path = try(each.value.request_path, null)
}
resource "azurerm_lb_rule" "azlbrule" {
for_each = {for rule in local.rules: rule.name => rule}
name = each.key
resource_group_name = each.value.resource_group_name
loadbalancer_id = azurerm_lb.azlb[each.value.lb_name].id
frontend_ip_configuration_name = each.value.fipc_name
protocol = each.value.protocol
backend_address_pool_id = azurerm_lb_backend_address_pool.azlbbpool[each.value.backend_pool_name].id
frontend_port = each.value.frontend_port
backend_port = each.value.backend_port
load_distribution = each.value.load_distribution
probe_id = azurerm_lb_probe.azlbprobe[each.value.probe.name].id
# depends_on = [azurerm_marketplace_agreement.accept]
}
locals {
nics = flatten([
for bp in local.bps : [
for nic in bp.nics : {
name = nic.name
resource_group_name = nic.resource_group_name
lb_name = bp.lb_name
ipc_name = nic.ipc_name
bp_name = bp.name
}
]
])
}
data "azurerm_network_interface" "nic" {
for_each = {for nic in local.nics: nic.name => nic}
name = each.key
resource_group_name = each.value.resource_group_name
depends_on = [var.azlb_depends_on]
}
resource "azurerm_network_interface_backend_address_pool_association" "aznicbpass" {
for_each = {for nic in local.nics: nic.name => nic}
network_interface_id = data.azurerm_network_interface.nic[each.key].id
ip_configuration_name = each.value.ipc_name
backend_address_pool_id = azurerm_lb_backend_address_pool.azlbbpool[each.value.bp_name].id
}

+ 4
- 0
modules/azure_lb/outputs.tf Vedi File

@@ -0,0 +1,4 @@
output "ids" {
value = [for lbname, lb in var.lbs: try(azurerm_lb.azlb[lbname].id, null)]
description = "List of load balancer ids."
}

+ 9
- 0
modules/azure_lb/variables.tf Vedi File

@@ -0,0 +1,9 @@
variable "lbs" {
type = map
description = "Load balancer definition list."
}
variable "azlb_depends_on" {
type = any
default = null
}

+ 32
- 0
modules/azure_nsg/main.tf Vedi File

@@ -0,0 +1,32 @@
terraform {
required_version = "~> 0.12.21"
required_providers {
azurerm = "~> 1.44"
}
}
resource "azurerm_network_security_group" "aznsg" {
count = length(var.nsgs)
name = var.nsgs[count.index].name
resource_group_name = var.nsgs[count.index].resource_group_name
location = var.nsgs[count.index].location
tags = var.nsgs[count.index].tags
dynamic "security_rule" {
for_each = var.nsgs[count.index].security_rules
content {
name = security_rule.key
description = security_rule.value.description
protocol = security_rule.value.protocol #Tcp, Udp, Icmp, or *
source_port_range = security_rule.value.source_port_range # [Integer or range between 0 and 65535 or *]
destination_port_range = security_rule.value.destination_port_range # [Integer or range between 0 and 65535 or *]
source_address_prefix = security_rule.value.source_address_prefix # [CIDR or destination IP range or * or tags such as ‘VirtualNetwork’, ‘AzureLoadBalancer’ and ‘Internet’ ]
destination_address_prefix = security_rule.value.destination_address_prefix # [CIDR or destination IP range or * or tags such as ‘VirtualNetwork’, ‘AzureLoadBalancer’ and ‘Internet’ ]
access = security_rule.value.access #Allow or Deny
priority = security_rule.value.priority
direction = security_rule.value.direction #Inbound or Outbound.
}
}
depends_on = [var.aznsg_depends_on]
}

+ 4
- 0
modules/azure_nsg/outputs.tf Vedi File

@@ -0,0 +1,4 @@
output "ids" {
value = azurerm_network_security_group.aznsg[*].id
description = "List of network security group ids."
}

+ 9
- 0
modules/azure_nsg/variables.tf Vedi File

@@ -0,0 +1,9 @@
variable "nsgs" {
type = list
description = "Network security group definition list"
}
variable "aznsg_depends_on" {
type = any
default = null
}

+ 14
- 0
modules/azure_rg/main.tf Vedi File

@@ -0,0 +1,14 @@
terraform {
required_version = "~> 0.12.21"
required_providers {
azurerm = "~> 1.44"
}
}
resource "azurerm_resource_group" "azrg" {
for_each = var.rgs
name = each.key
location = each.value.location
tags = each.value.tags
}

+ 4
- 0
modules/azure_rg/outputs.tf Vedi File

@@ -0,0 +1,4 @@
output "ids" {
value = [for rgname, rg in var.rgs: try(azurerm_resource_group.azrg[rgname].id, null)]
description = "List of resource group ids."
}

+ 4
- 0
modules/azure_rg/variables.tf Vedi File

@@ -0,0 +1,4 @@
variable "rgs" {
type = map
description = "Resources group definition"
}

+ 27
- 0
modules/azure_rtb/main.tf Vedi File

@@ -0,0 +1,27 @@
terraform {
required_version = "~> 0.12.21"
required_providers {
azurerm = "~> 1.44"
}
}
resource "azurerm_route_table" "azrtb" {
count = length(var.rtbs)
name = var.rtbs[count.index].name
resource_group_name = var.rtbs[count.index].resource_group_name
location = var.rtbs[count.index].location
disable_bgp_route_propagation = var.rtbs[count.index].disable_bgp_route_propagation
tags = var.rtbs[count.index].tags
dynamic "route" {
for_each = var.rtbs[count.index].routes
content {
name = route.key
address_prefix = route.value.address_prefix
next_hop_type = route.value.next_hop_type # VirtualNetworkGateway, VnetLocal, Internet, VirtualAppliance and None
next_hop_in_ip_address = route.value.next_hop_in_ip_address # if next_hop_type = VirtualAppliance
}
}
depends_on = [var.azrtb_depends_on]
}

+ 9
- 0
modules/azure_rtb/outputs.tf Vedi File

@@ -0,0 +1,9 @@
output "ids" {
value = azurerm_route_table.azrtb[*].id
description = "List of route table ids."
}
output "subnets" {
value = azurerm_route_table.azrtb[*].subnets
description = "List of subnets associate to route table."
}

+ 9
- 0
modules/azure_rtb/variables.tf Vedi File

@@ -0,0 +1,9 @@
variable "rtbs" {
type = list
description = "List of route table definition"
}
variable "azrtb_depends_on" {
type = any
default = null
}

+ 160
- 0
modules/azure_sa/main.tf Vedi File

@@ -0,0 +1,160 @@
terraform {
required_version = "~> 0.12.21"
required_providers {
azurerm = "~> 1.44"
}
}
resource "azurerm_storage_account" "azsa" {
depends_on = [var.azsa_depends_on]
for_each = var.sas
name = each.key
resource_group_name = each.value.resource_group_name
location = each.value.location
account_kind = try(each.value.kind, null)
account_tier = try(each.value.tier, "Standard")
account_replication_type = try(each.value.replication_type, "GRS")
access_tier = try(each.value.access, null)
enable_https_traffic_only = try(each.value.https_traffic, true)
is_hns_enabled = try(each.value.hns, null)
tags = try(each.value.tags, null)
dynamic "custom_domain" {
for_each = try(each.value.custom_domain, {})
content {
name = try(custom_domain.value.cname, null)
use_subdomain = try(custom_domain.value.subdomain, null)
}
}
identity {
type = try(each.value.identity.type, "SystemAssigned")
}
blob_properties {
/*dynamic "cors_rule" {
for_each = try(each.value.blob_properties.cors_rule, {})
content {
allowed_headers = try(cors_rule.value.headers, [])
allowed_methods = try(cors_rule.value.methods, [])
allowed_origins = try(cors_rule.value.origins, [])
exposed_headers = try(cors_rule.value.exposed, [])
max_age_in_seconds = try(cors_rule.value.age, 30)
}
}*/
delete_retention_policy {
days = try(each.value.blob_properties.retention, 7)
}
}
dynamic "queue_properties" {
for_each = try(each.value.queue_properties, {})
content {
dynamic "cors_rule" {
for_each = try(queue_properties.value.cors_rule, {})
content {
allowed_headers = try(cors_rule.value.headers, [])
allowed_methods = try(cors_rule.value.methods, [])
allowed_origins = try(cors_rule.value.origins, [])
exposed_headers = try(cors_rule.value.exposed, [])
max_age_in_seconds = try(cors_rule.value.age, 30)
}
}
dynamic "logging" {
for_each = try(queue_properties.value.logging, {})
content {
delete = try(logging.value.delete, true)
read = try(logging.value.read, true)
version = try(logging.value.version, "1.0")
write = try(logging.value.write, true)
retention_policy_days = try(logging.value.retention, null)
}
}
dynamic "minute_metrics" {
for_each = try(queue_properties.value.minutes, {})
content {
enabled = try(minute_metrics.value.enabled, true)
version = try(minute_metrics.value.version, "1.0")
include_apis = try(minute_metrics.value.include_api, null)
retention_policy_days = try(minute_metrics.value.retention, null)
}
}
dynamic "hour_metrics" {
for_each = try(queue_properties.value.hours, {})
content {
enabled = try(hour_metrics.value.enabled, true)
version = try(hour_metrics.value.version, "1.0")
include_apis = try(hour_metrics.value.include_api, null)
retention_policy_days = try(hour_metrics.value.retention, null)
}
}
}
}
/*dynamic "stactic_website" {
for_each = try(each.value.kind, "StorageV2") == "StorageV2" ? try(each.value.website, {}) : {}
content {
index_document = try(stactic_website.value.index, null)
error_404_document = try(stactic_website.value.error, null)
}
}*/
network_rules {
default_action = try(each.value.network_rules.default, "Deny")
bypass = try(each.value.network_rules.bypass, null) #Logging, Metrics, AzureServices, None
ip_rules = try(each.value.network_rules.publicips, null)
virtual_network_subnet_ids = try(each.value.network_rules.subnets, null)
#virtual_network_subnet_ids = [ for subnet in try(each.value.network_rules.subnets, []) : data.azurerm_subnet.subnet[join("_", [subnet.name, subnet.vnet, subnet.resource_group])].id ]
}
}
/*
locals {
# flatten ensures that this local value is a flat list of objects, rather
# than a list of lists of objects.
subnets = flatten([
for sa in var.sas : [
for subnet in try(sa.network_rules.subnets, []) : {
key = join("_", [subnet.name, subnet.vnet, subnet.resource_group])
name = subnet.name
vnet = subnet.vnet
resource_group = subnet.resource_group
}
]
])
}
data "azurerm_subnet" "subnet" {
for_each = {for subnet in local.subnets: subnet.key => subnet...}
name = each.value.subnet.name
virtual_network_name = each.value.subnet.vnet
resource_group_name = each.value.sunnet.resource_group
}
*/
locals {
# flatten ensures that this local value is a flat list of objects, rather
# than a list of lists of objects.
containers = flatten([
for saname, sa in var.sas : [
for container in try(sa.containers, []) : {
name = container.name
storage_account_name = saname
container_access_type = try(container.access_type, null)
metadata = try(container.metadata, null)
}
]
])
}
resource "azurerm_storage_container" "azsc" {
depends_on = [azurerm_storage_account.azsa]
count = length(local.containers)
name = local.containers[count.index].name
storage_account_name = local.containers[count.index].storage_account_name
container_access_type = try(local.containers[count.index].container_access_type, "private")
metadata = try(local.containers[count.index].metadata, null)
}

+ 4
- 0
modules/azure_sa/outputs.tf Vedi File

@@ -0,0 +1,4 @@
output "ids" {
value = [for saname, sa in var.sas: try(azurerm_storage_account.azsa[saname].id, null)]
description = "List of storage account ids."
}

+ 9
- 0
modules/azure_sa/variables.tf Vedi File

@@ -0,0 +1,9 @@
variable "sas" {
type = map
description = "storage accounts definition"
}
variable "azsa_depends_on" {
type = any
default = null
}

+ 101
- 0
modules/azure_subnet_link/main.tf Vedi File

@@ -0,0 +1,101 @@
terraform {
required_version = "~> 0.12.21"
required_providers {
azurerm = "~> 1.44"
}
}
locals {
linkrtbs = distinct(flatten([
for link in var.sub_links : [
for rtb in try(link.subnet.rtb, []) : {
subnet = link.subnet.name
route_table_name = link.subnet.rtb.name
}
]
]))
}
resource "azurerm_subnet_route_table_association" "azsub_rtb_link" {
depends_on = [var.azsub_link_depends_on]
for_each = {for link in try(local.linkrtbs, []): link.subnet => link}
subnet_id = data.azurerm_subnet.sub[each.value.subnet].id
route_table_id = data.azurerm_route_table.rtb[each.value.route_table_name].id
}
locals {
linknatgws = distinct(flatten([
for link in var.sub_links : [
for rtb in try(link.subnet.natgw, []) : {
subnet = link.subnet.name
nat_gateway_name = link.subnet.natgw.name
}
]
]))
}
resource "azurerm_subnet_nat_gateway_association" "azsub_natgw_link" {
depends_on = [var.azsub_link_depends_on]
for_each = {for link in try(local.linknatgws, []): link.subnet => link}
subnet_id = data.azurerm_subnet.sub[each.value.subnet].id
nat_gateway_id = data.azurerm_nat_gateway.natgw[each.value.nat_gateway_name].id
}
locals {
subnets = distinct(flatten([
for link in var.sub_links : {
name = link.subnet.name
virtual_network_name = link.subnet.virtual_network_name
resource_group_name = link.subnet.resource_group_name
}
]))
}
data "azurerm_subnet" "sub" {
depends_on = [var.azsub_link_depends_on]
for_each = {for subnet in local.subnets: subnet.name => subnet}
name = each.value.name
virtual_network_name = each.value.virtual_network_name
resource_group_name = each.value.resource_group_name
}
locals {
rtbs = distinct(flatten([
for link in var.sub_links : [
for rtb in try(link.subnet.rtb, []) : {
name = link.subnet.rtb.name
resource_group_name = link.subnet.rtb.resource_group_name
}
]
]))
}
data "azurerm_route_table" "rtb" {
depends_on = [var.azsub_link_depends_on]
for_each = {for rtb in local.rtbs: rtb.name => rtb}
name = each.value.name
resource_group_name = each.value.resource_group_name
}
locals {
natgws = distinct(flatten([
for link in var.sub_links : [
for rtb in try(link.subnet.natgw, []) : {
name = link.natgw.name
resource_group_name = link.natgw.resource_group_name
}
]
]))
}
data "azurerm_nat_gateway" "natgw" {
depends_on = [var.azsub_link_depends_on]
for_each = {for natgw in local.natgws: natgw.name => natgw}
name = each.value.name
resource_group_name = each.value.resource_group_name
}

+ 8
- 0
modules/azure_subnet_link/outputs.tf Vedi File

@@ -0,0 +1,8 @@
output "subnet_rtb_ids" {
value = azurerm_subnet_route_table_association.azsub_rtb_link[*].id
description = "List of association ids of subnet and route table."
}
output "subnet_natgw_ids" {
value = azurerm_subnet_nat_gateway_association.azsub_natgw_link[*].id
description = "List of association ids of subnet and nat gateway."
}

+ 9
- 0
modules/azure_subnet_link/variables.tf Vedi File

@@ -0,0 +1,9 @@
variable "sub_links" {
type = list
description = "List of subnet association"
}
variable "azsub_link_depends_on" {
type = any
default = null
}

+ 219
- 0
modules/azure_vm/main.tf Vedi File

@@ -0,0 +1,219 @@
terraform {
required_version = "~> 0.12.21"
required_providers {
azurerm = "~> 1.44"
}
}
resource "azurerm_virtual_machine" "azvm" {
count = length(var.vms)
name = var.vms[count.index].name
resource_group_name = var.vms[count.index].resource_group_name
location = var.vms[count.index].location
network_interface_ids = [for nic in var.vms[count.index].nics: azurerm_network_interface.nic[join("-nic", [var.vms[count.index].name, index(var.vms[count.index].nics, nic)])].id]
vm_size = var.vms[count.index].vm_size #Standard_D2s_v3, Standard_B2s
availability_set_id = azurerm_availability_set.avset[var.vms[count.index].avset.name].id
tags = var.vms[count.index].tags
delete_os_disk_on_termination = try(var.vms[count.index].delete_os_disk_on_termination, true)
delete_data_disks_on_termination = try(var.vms[count.index].delete_data_disks_on_termination, true)
#zones = try(var.vms[count.index].zones, null)
storage_os_disk {
name = join("-", [var.vms[count.index].name, "disk"])
caching = var.vms[count.index].storage_os_disk.caching #None, ReadOnly or ReadWrite
create_option = var.vms[count.index].storage_os_disk.create_option #Attach, FromImage
disk_size_gb = var.vms[count.index].storage_os_disk.disk_size_gb
os_type = var.vms[count.index].storage_os_disk.os_type #Linux or Windows
}
dynamic "os_profile" {
for_each = var.vms[count.index].os_profile
content {
computer_name = var.vms[count.index].name
admin_username = try(os_profile.value.admin_username, "") != "" ? os_profile.value.admin_username : "master"
admin_password = try(os_profile.value.admin_password, null)
}
}
dynamic "os_profile_linux_config" {
for_each = try(var.vms[count.index].os_profile_linux_config, [])
content {
disable_password_authentication = os_profile_linux_config.value.disable_password_authentication
dynamic "ssh_keys" {
for_each = os_profile_linux_config.value.disable_password_authentication ? os_profile_linux_config.value.ssh_keys : {}
content {
key_data = try(ssh_keys.value.file, "") != "" ? file("${ssh_keys.value.file}") : var.default_ssh_pubkey
path = try(ssh_keys.value.dst_path, "") != "" ? ssh_keys.value.dst_path : format("/home/%s/.ssh/authorized_keys", "master")
}
}
}
}
dynamic "os_profile_windows_config" {
for_each = try(var.vms[count.index].os_profile_windows_config, [])
content {
provision_vm_agent = os_profile_windows_config.value.provision_vm_agent
enable_automatic_upgrades = os_profile_windows_config.value.enable_automatic_upgrades
timezone = os_profile_windows_config.value.timezone #https://jackstromberg.com/2017/01/list-of-time-zones-consumed-by-azure/
winrm {
protocol = os_profile_windows_config.value.protocol #HTTP or HTTPS
certificate_url = os_profile_windows_config.value.certificate_url
}
}
}
dynamic "plan" {
for_each = try(var.vms[count.index].plan, [])
content {
name = plan.value.name
publisher = plan.value.publisher
product = plan.value.product
}
}
dynamic "storage_data_disk" {
for_each = try(var.vms[count.index].storage_data_disk, [])
content {
name = storage_data_disk.value.name
caching = try(storage_data_disk.value.caching, "ReadOnly") #None, ReadOnly or ReadWrite
create_option = try(storage_data_disk.value.create_option, "Empty") #Attach, FromImage and Empty
disk_size_gb = storage_data_disk.value.disk_size_gb
lun = storage_data_disk.value.lun
}
}
dynamic "storage_image_reference" {
for_each = var.vms[count.index].storage_image_reference
content {
publisher = storage_image_reference.value.publisher
offer = storage_image_reference.value.offer
sku = storage_image_reference.value.sku
version = storage_image_reference.value.version
id = try(storage_image_reference.value.id, null)
}
}
depends_on = [azurerm_marketplace_agreement.accept, var.azvm_depends_on]
}
locals {
# flatten ensures that this local value is a flat list of objects, rather
# than a list of lists of objects.
avsets = flatten([
for vm in var.vms : {
name = vm.avset.name
location = vm.location
resource_group_name = try(vm.avset.resource_group_name, vm.resource_group_name)
platform_update_domain_count = try(vm.avset.platform_update_domain_count, 2)
platform_fault_domain_count = try(vm.avset.platform_fault_domain_count, 2)
managed = try(vm.avset.managed, true) #true => Aligned, false => Classic
tags = try(vm.avset.tags, vm.tags)
}
])
}
resource "azurerm_availability_set" "avset" {
for_each = {
for avs in local.avsets:
avs.name => avs...
}
name = each.value[0].name
location = each.value[0].location
resource_group_name = each.value[0].resource_group_name
platform_update_domain_count = each.value[0].platform_update_domain_count
platform_fault_domain_count = each.value[0].platform_fault_domain_count
managed = each.value[0].managed
tags = each.value[0].tags
}
locals {
# flatten ensures that this local value is a flat list of objects, rather
# than a list of lists of objects.
images = flatten([
for vm in var.vms : [
for image in vm.storage_image_reference : {
name = join("-", [image.publisher, image.offer, image.sku])
publisher = image.publisher
offer = image.offer
plan = image.sku
}
]
])
}
resource "azurerm_marketplace_agreement" "accept" {
for_each = {
for image in local.images:
image.name => image...
}
publisher = each.value[0].publisher
offer = each.value[0].offer
plan = each.value[0].plan
}
locals {
# flatten ensures that this local value is a flat list of objects, rather
# than a list of lists of objects.
nics = flatten([
for vm in var.vms : [
for nic in vm.nics : {
name = join("-nic", [vm.name, index(vm.nics, nic)])
location = vm.location
resource_group_name = nic.resource_group_name
enable_ip_forwarding = try(nic.enable_ip_forwarding, false)
enable_accelerated_networking = try(nic.enable_accelerated_networking, false)
tags = nic.tags
nsg = nic.nsg
subnet = nic.subnet
ip_configuration = {
"name" = "${join("-nic", [vm.name, index(vm.nics, nic)])}-ipc"
"private_ip_address_allocation" = try(nic.ip_configuration.private_ip_address_allocation, "Static")
"private_ip_address_version" = try(nic.ip_configuration.private_ip_address_version, "IPv4")
"private_ip_address" = try(nic.ip_configuration.private_ip_address_allocation, "Static") == "Static" ? nic.ip_configuration.private_ip_address : null
"public_ip_address_id" = try(nic.ip_configuration.public_ip_address_id, null)
}
}
]
])
}
resource "azurerm_network_interface" "nic" {
for_each = {for nic in local.nics: nic.name => nic}
name = each.value.name
location = each.value.location
resource_group_name = each.value.resource_group_name
enable_ip_forwarding = each.value.enable_ip_forwarding
enable_accelerated_networking = each.value.enable_accelerated_networking
network_security_group_id = data.azurerm_network_security_group.nsg[each.value.name].id
tags = each.value.tags
ip_configuration {
name = each.value.ip_configuration.name
subnet_id = data.azurerm_subnet.sub[each.value.name].id
private_ip_address_allocation = each.value.ip_configuration.private_ip_address_allocation
private_ip_address_version = each.value.ip_configuration.private_ip_address_version
private_ip_address = try(each.value.ip_configuration.private_ip_address, null)
public_ip_address_id = try(each.value.ip_configuration.public_ip_address_id, null)
}
}
data "azurerm_network_security_group" "nsg" {
for_each = {for nic in local.nics: nic.name => nic}
name = each.value.nsg.name
resource_group_name = each.value.nsg.resource_group_name
depends_on = [var.azvm_depends_on]
}
data "azurerm_subnet" "sub" {
for_each = {for nic in local.nics: nic.name => nic}
name = each.value.subnet.name
virtual_network_name = each.value.subnet.virtual_network_name
resource_group_name = each.value.subnet.resource_group_name
depends_on = [var.azvm_depends_on]
}

+ 4
- 0
modules/azure_vm/outputs.tf Vedi File

@@ -0,0 +1,4 @@
output "ids" {
value = azurerm_virtual_machine.azvm[*].id
description = "List of virtual machine ids."
}

+ 14
- 0
modules/azure_vm/variables.tf Vedi File

@@ -0,0 +1,14 @@
variable "vms" {
type = list
description = "Virtual machine definition list."
}
variable "default_ssh_pubkey" {
type = string
description = "Public key to use to connect on system"
}
variable "azvm_depends_on" {
type = any
default = null
}

+ 51
- 0
modules/azure_vnet/main.tf Vedi File

@@ -0,0 +1,51 @@
terraform {
required_version = "~> 0.12.21"
required_providers {
azurerm = "~> 1.44"
}
}
resource "azurerm_virtual_network" "azvnet" {
count = length(var.vnets)
name = var.vnets[count.index].name
resource_group_name = var.vnets[count.index].resource_group_name
address_space = var.vnets[count.index].address_space
location = var.vnets[count.index].location
dns_servers = var.vnets[count.index].dns_servers
tags = var.vnets[count.index].tags
dynamic "subnet" {
for_each = var.vnets[count.index].subnets
content {
name = subnet.key
address_prefix = subnet.value.address_prefix
security_group = try(data.azurerm_network_security_group.nsg[subnet.value.nsg.name].id, null)
}
}
/* ddos_protection_plan {
id = azurerm_ddos_protection_plan.example.id
enable = true
}*/
depends_on = [var.azvnet_depends_on]
}
locals {
nsgs = distinct(flatten([
for vnet in var.vnets : [
for subkey, subnet in vnet.subnets : {
name = subnet.nsg.name
resource_group_name = try(subnet.nsg.resource_group_name, vnet.resource_group_name)
}
]
]))
}
data "azurerm_network_security_group" "nsg" {
for_each = {for nsg in local.nsgs: nsg.name => nsg}
name = each.value.name
resource_group_name = each.value.resource_group_name
depends_on = [var.azvnet_depends_on]
}

+ 4
- 0
modules/azure_vnet/outputs.tf Vedi File

@@ -0,0 +1,4 @@
output "ids" {
value = azurerm_virtual_network.azvnet[*].id
description = "List of virtual network ids."
}

+ 9
- 0
modules/azure_vnet/variables.tf Vedi File

@@ -0,0 +1,9 @@
variable "vnets" {
type = list
description = "List of virtual network definition"
}
variable "azvnet_depends_on" {
type = any
default = null
}

+ 54
- 0
outputs.tf Vedi File

@@ -0,0 +1,54 @@
output "azrgid" {
value = module.azure_rg.ids
description = "List of resource group ids."
}
output "azsaid" {
value = module.azure_sa.ids
description = "List of storage account ids."
}
output "azvnetid" {
value = module.azure_vnet.ids
description = "List of virtual network ids."
}
output "azrtbid" {
value = module.azure_rtb.ids
description = "List of route table ids."
}
output "azrtbsubnet" {
value = module.azure_rtb.subnets
description = "List of route table subnets."
}
output "azsub_rtb_id" {
value = module.azure_subnet_link.subnet_rtb_ids
description = "List of subnet route table association ids."
}
output "azsub_natgw_id" {
value = module.azure_subnet_link.subnet_natgw_ids
description = "List of subnet nat gateway association ids."
}
output "aznsgid" {
value = module.azure_nsg.ids
description = "List of network security groups ids."
}
output "azvmid" {
value = module.azure_vm.ids
description = "List of virtual machine ids."
}
output "azlbid" {
value = module.azure_lb.ids
description = "List of load balancer ids."
}
output "azlawid" {
value = module.azure_law.ids
description = "List of workspace ids."
}

+ 48
- 0
run.sh Vedi File

@@ -0,0 +1,48 @@
#!/usr/bin/env bash
# ENV Vars:
# TERRAFORM_FILE - defaults to "infra.tf"
# - specify state file to pass to terraform
export TERRAFORM_FILE="${TERRAFORM_FILE:-infra.tf}"
export TERRAFORM_ACTION="${TERRAFORM_ACTION:-apply}"
run_terraform() {
INOPTS=( "$@" )
if [ -d "${INOPTS[-1]}" ]
then
DIR="${INOPTS[-1]}"
unset 'INOPTS[${#}-1]'
else
DIR="."
fi
# Plaintext vault decryption key, not checked into SCM
if time terraform init -get=true -get-plugins=true -reconfigure -upgrade -verify-plugins=true "${INOPTS[@]}" "${DIR}"; then
time terraform fmt -list=true -check -recursive "${DIR}"
fi
coderun=$?
if [ $coderun ]
then
time terraform validate "${DIR}"
coderun=$?
if [ $coderun ]
then
if [ $TERRAFORM_ACTION == "destroy" ]
then
time terraform plan -${TERRAFORM_ACTION} -input=false "${INOPTS[@]}" "${DIR}" \
&& time terraform ${TERRAFORM_ACTION} -auto-approve -input=false "${INOPTS[@]}" "${DIR}"
else
rm terraform.tfstate*
time terraform plan -input=false "${INOPTS[@]}" "${DIR}" \
&& time terraform ${TERRAFORM_ACTION} -auto-approve -input=false "${INOPTS[@]}" "${DIR}"
fi
return $?
fi
else
return $codefmt
fi
}
run_terraform "$@"
retcode=$?
exit $retcode

+ 110
- 0
variables.tf Vedi File

@@ -0,0 +1,110 @@
variable "ARM_SUBSCRIPTION_ID" {
type = string
}
variable "ARM_CLIENT_ID" {
type = string
}
variable "ARM_CLIENT_SECRET" {
type = string
}
variable "ARM_TENANT_ID" {
type = string
}
variable "resource_groups" {
type = map
default = {}
description = "Resources group definition"
}
variable "storage_accounts" {
type = map
default = {}
description = "Storage accounts denition"
}
variable "virtual_networks" {
type = list
default = []
description = "Virtual network definition list"
}
variable "ssh_pubkey" {
type = string
default = ""
description = "Public ssh key to connect on machine"
}
variable "route_tables" {
type = list
default = []
description = "Route table definition list"
}
variable "subnets_associations" {
type = list
default = []
description = "Subnets association list"
}
variable "network_security_groups" {
type = list
default = []
description = "Network security groups definition list"
}
variable "virtual_machines" {
type = list
default = []
description = "Virtual machines definition list"
}
variable "load_balancers" {
type = map
default = {}
description = "Load balancers definition list"
}
variable "workspaces" {
type = list
default = []
description = "Log Analytic Workspace definition list"
}
variable "solutions" {
type = list(string)
default = []
}
variable "vms_to_alert" {
type = list
default = []
description = "List of Virtual machines to alert"
}
variable "action_groups" {
type = list
default = []
description = "Action Group definition list"
}
variable "alerts" {
type = list
default = []
description = "Alerts definition list"
}
variable "tags" {
type = map
default = {}
description = "Tags definition"
}
variable "rg_name" {
type = string
default = ""
description = "Resource Group for alerts"
}

Caricamento…
Annulla
Salva