Skip to content

Instantly share code, notes, and snippets.

@JonTheNiceGuy
Last active December 21, 2018 10:01
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save JonTheNiceGuy/d9033d092e845de8750d90fa62e6e333 to your computer and use it in GitHub Desktop.

Azure Build Environment

This build environment is as used in my test environments. There will be several files, as this gist will be used in my blog post!

Any content here is released under a CC-0 license, please make use of it as you can!

---
- hosts: localhost
vars:
location: "{{ project_location|default('uksouth') }}"
prefix: "{% if lookup('env', 'ANSIBLE_PREFIX') != '' %}{{ lookup('env', 'ANSIBLE_PREFIX') }}{% else %}{{ project_prefix|default(ansible_date_time.epoch|hash('md5')|truncate(8, true, '')) }}{% endif %}"
breakglass_pw: "{% if lookup('env', 'BREAKGLASS') != '' %}{{ lookup('env', 'BREAKGLASS') }}{% else %}{{ project_breakglass|default(ansible_date_time.epoch|hash('md5')|truncate(8, true, '') + '_Azure') }}{% endif %}"
tasks:
- debug: var=prefix
- debug: var=breakglass_pw
- name: "Create Resource Group"
azure_rm_resourcegroup:
name: "{{ prefix }}"
location: "{{ location }}"
# Yes, this is not good practice, but it's just for a POV/POC
- name: "Create Any-Any Allow Security Group"
azure_rm_securitygroup:
resource_group: "{{ prefix }}"
name: "{{ prefix }}AnyAnyAllow"
rules:
- name: AllowAllInbound
protocol: "*"
destination_port_range: "*"
access: Allow
priority: 100
direction: Inbound
- name: AllowAllOutbound
protocol: "*"
destination_port_range: "*"
access: Allow
priority: 100
direction: Outbound
- name: "Create Storage Account"
azure_rm_storageaccount:
resource_group: "{{ prefix }}"
name: "{{ prefix }}storage"
account_type: Standard_LRS
- name: "Create VNET"
azure_rm_virtualnetwork:
resource_group: "{{ prefix }}"
name: "{{ prefix }}network01"
address_prefixes_cidr: "10.0.0.0/8"
- name: "Schedule UDR Creation"
azure_rm_routetable:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.value.name }}_udr"
with_dict: "{{ network }}"
loop_control:
label: "{{ prefix }}{{ item.value.name }}"
when: item.value.gateway is defined
async: 1000
poll: 0
register: sleeper
- name: "Check UDRs Created"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Subnet Creation"
azure_rm_subnet:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.value.name }}"
address_prefix: "{{ item.value.prefix }}.0/24"
virtual_network: "{{ prefix }}network01"
route_table: "{% if item.value.gateway is defined %}{{ prefix }}{{ item.value.name }}_udr{% else %}{{ omit }}{% endif %}"
with_dict: "{{ network }}"
loop_control:
label: "{{ prefix }}{{ item.value.name }}"
async: 1000
poll: 0
register: sleeper
- name: "Check Subnet Created"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Route Creation"
azure_rm_route:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.value.name }}"
address_prefix: "0.0.0.0/0"
route_table_name: "{{ prefix }}{{ item.value.name }}_udr"
next_hop_type: virtual_appliance
next_hop_ip_address: "{{ item.value.gateway }}"
with_dict: "{{ network }}"
loop_control:
label: "{{ prefix }}{{ item.value.name }}"
when: item.value.gateway is defined
async: 1000
poll: 0
register: sleeper
- name: "Check Routes Created"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Public IP creation"
azure_rm_publicipaddress:
resource_group: "{{ prefix }}"
allocation_method: Static
name: "{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}pubip"
with_subelements:
- "{{ appliances }}"
- ports
when: item.1.public is not defined or (item.1.public is defined and item.1.public == 'true')
loop_control:
label: "{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}pubip"
async: 1000
poll: 0
register: sleeper
- name: "Check Public IPs Created"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Network Interface Creation"
azure_rm_networkinterface:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}"
virtual_network: "{{ prefix }}network01"
subnet: "{{ prefix }}{{ item.1.subnet.name }}"
public_ip_name: "{{ prefix }}pubip01"
security_group: "{{ prefix }}AnyAnyAllow"
ip_configurations:
- name: "{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}"
public_ip_address_name: "{%- if item.1.public is not defined or (item.1.public is defined and item.1.public == 'true') %}{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}pubip{% else -%}{%- endif -%}"
primary: yes
with_subelements:
- "{{ appliances }}"
- ports
loop_control:
label: "{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}"
async: 1000
poll: 0
register: sleeper
- name: "Check Network Interfaces Created"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Virtual Machine Creation - Priority 0 (or 'All')"
azure_rm_virtualmachine:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.value.name }}"
vm_size: "{{ item.value.size }}"
storage_account: "{{ prefix }}storage"
storage_container: "{{ prefix }}{{ item.value.name }}os"
storage_blob: "{{ prefix }}{{ item.value.name }}os.vhd"
admin_username: breakglass
admin_password: "{{ breakglass_pw }}"
network_interfaces: "[{%- for nw in item.value.ports -%}'{{ prefix }}{{ item.value.name }}port{{ nw.subnet.name }}'{%- if not loop.last -%}, {%- endif -%} {%- endfor -%}]"
custom_data: "{% if item.value.provision_script is defined and item.value.provision_script != ''%}{% include(item.value.provision_script) %}{% elif item.value.image.provision_script is defined and item.value.image.provision_script != '' %}{% include(item.value.image.provision_script) %}{% else %}{{ omit }}{% endif %}"
image:
publisher: "{{ item.value.image.publisher }}"
offer: "{{ item.value.image.offer }}"
sku: "{{ item.value.image.sku }}"
version: "{{ item.value.image.version }}"
plan: "{% if item.value.image.plan is not defined %}{{ omit }}{% else %}{'name': '{{ item.value.image.sku }}','publisher': '{{ item.value.image.publisher }}','product': '{{ item.value.image.offer }}'}{% endif %}"
with_dict: "{{ appliances }}"
when: item.value.priority | default(0) == 0
loop_control:
label: "{{ prefix }}{{ item.value.name }}"
async: 1000
poll: 0
register: sleeper
- name: "Check Virtual Machines Created - Priority 0"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Virtual Machine Creation - Priority 1"
azure_rm_virtualmachine:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.value.name }}"
vm_size: "{{ item.value.size }}"
storage_account: "{{ prefix }}storage"
storage_container: "{{ prefix }}{{ item.value.name }}os"
storage_blob: "{{ prefix }}{{ item.value.name }}os.vhd"
admin_username: breakglass
admin_password: "{{ breakglass_pw }}"
network_interfaces: "[{%- for nw in item.value.ports -%}'{{ prefix }}{{ item.value.name }}port{{ nw.subnet.name }}'{%- if not loop.last -%}, {%- endif -%} {%- endfor -%}]"
custom_data: "{% if item.value.provision_script is defined and item.value.provision_script != ''%}{% include(item.value.provision_script) %}{% elif item.value.image.provision_script is defined and item.value.image.provision_script != '' %}{% include(item.value.image.provision_script) %}{% else %}{{ omit }}{% endif %}"
image:
publisher: "{{ item.value.image.publisher }}"
offer: "{{ item.value.image.offer }}"
sku: "{{ item.value.image.sku }}"
version: "{{ item.value.image.version }}"
plan: "{% if item.value.image.plan is not defined %}{{ omit }}{% else %}{'name': '{{ item.value.image.sku }}','publisher': '{{ item.value.image.publisher }}','product': '{{ item.value.image.offer }}'}{% endif %}"
with_dict: "{{ appliances }}"
when: item.value.priority | default(0) == 1
loop_control:
label: "{{ prefix }}{{ item.value.name }}"
async: 1000
poll: 0
register: sleeper
- name: "Check Virtual Machines Created - Priority 1"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Virtual Machine Creation - Priority 2"
azure_rm_virtualmachine:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.value.name }}"
vm_size: "{{ item.value.size }}"
storage_account: "{{ prefix }}storage"
storage_container: "{{ prefix }}{{ item.value.name }}os"
storage_blob: "{{ prefix }}{{ item.value.name }}os.vhd"
admin_username: breakglass
admin_password: "{{ breakglass_pw }}"
network_interfaces: "[{%- for nw in item.value.ports -%}'{{ prefix }}{{ item.value.name }}port{{ nw.subnet.name }}'{%- if not loop.last -%}, {%- endif -%} {%- endfor -%}]"
custom_data: "{% if item.value.provision_script is defined and item.value.provision_script != ''%}{% include(item.value.provision_script) %}{% elif item.value.image.provision_script is defined and item.value.image.provision_script != '' %}{% include(item.value.image.provision_script) %}{% else %}{{ omit }}{% endif %}"
image:
publisher: "{{ item.value.image.publisher }}"
offer: "{{ item.value.image.offer }}"
sku: "{{ item.value.image.sku }}"
version: "{{ item.value.image.version }}"
plan: "{% if item.value.image.plan is not defined %}{{ omit }}{% else %}{'name': '{{ item.value.image.sku }}','publisher': '{{ item.value.image.publisher }}','product': '{{ item.value.image.offer }}'}{% endif %}"
with_dict: "{{ appliances }}"
when: item.value.priority | default(0) == 2
loop_control:
label: "{{ prefix }}{{ item.value.name }}"
async: 1000
poll: 0
register: sleeper
- name: "Check Virtual Machines Created - Priority 2"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- debug: var=breakglass_pw
---
project_prefix: env01
project_breakglass: "My$uper$ecretPassw0rd"
project_location: uksouth
image:
ubuntu1804:
offer: UbuntuServer
publisher: Canonical
sku: '18.04-LTS'
version: latest
provision_script: userdata/ubuntu.j2
fortigate603_payg:
offer: fortinet_fortigate-vm_v5
publisher: fortinet
sku: 'fortinet_fg-vm_payg'
version: 6.0.3
plan: yes
provision_script: userdata/fortigate.j2
network:
wan:
name: wan
prefix: 10.10.10
protected:
name: protected
prefix: 10.10.20
gateway: 10.10.20.4
appliances:
fw01:
name: fw01
image: "{{ image.fortigate603_payg }}"
size: Standard_F1
priority: 1
ports:
- subnet: "{{ network.wan }}"
- subnet: "{{ network.protected }}"
private_ip: "{{ network.wan.prefix }}.4"
public: false
default_allow_policy:
- source: port2
destination: port1
nat: yes
vm01:
name: vm01
image: "{{ image.ubuntu1804 }}"
size: Standard_B1s
priority: 2
ports:
- subnet: "{{ network.protected }}"
private_ip: "{{ network.protected.prefix }}.5"
public: false
vm02:
name: vm02
image: "{{ image.ubuntu1804 }}"
size: Standard_B1s
priority: 0
ports:
- subnet: "{{ network.wan }}"
private_ip: "{{ network.wan.prefix }}.250"
public: false
#cloud-config
{# ################## #}
{# # Default Policy # #}
{# ################## #}
{% if item.value.default_allow_policy is defined %}
config firewall policy
{% for path in item.value.default_allow_policy %}
edit {{ loop.index }}
set name "Allow {{ path.source }} to {{ path.destination }}"
set srcintf "{{ path.source }}"
set dstintf "{{ path.destination }}"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
{% if path.nat is defined and path.nat %}
set nat enable
{% endif %}
next
{% endfor %}
end
config log setting
set fwpolicy-implicit-log enable
end
{% endif %}
{# ###################### #}
{# # Central Management # #}
{# ###################### #}
{% if management is defined and management.fortimanager is defined and (item.value.ha is not defined or (item.value.ha is defined and item.value.ha.primary is defined and item.value.ha.primary)) %}
config system central-management
set type fortimanager
set fmg {{ management.fortimanager }}
end
{% endif %}
{% if management is defined and management.fortianalyzer is defined and (item.value.ha is not defined or (item.value.ha is defined and item.value.ha.primary is defined and item.value.ha.primary)) %}
config log fortianalyzer setting
set status enable
set server "{{ management.fortianalyzer }}"
set upload-option realtime
set reliable enable
end
{% endif %}
{% if management is defined and management.syslog is defined and (item.value.ha is not defined or (item.value.ha is defined and item.value.ha.primary is defined and item.value.ha.primary)) %}
config log syslogd setting
set status enable
set server "{{ management.syslog }}"
end
{% endif %}
#cloud-config
package_update: true
package_upgrade: true
vars:
location: "{{ project_location|default('uksouth') }}"
prefix: |
{%- if lookup('env', 'ANSIBLE_PREFIX') != '' -%}
{{ lookup('env', 'ANSIBLE_PREFIX') }}
{%- else -%}
{{ project_prefix|default(ansible_date_time.epoch|hash('md5')|truncate(8, true, '')) }}
{%- endif %}"
breakglass_pw: |
{%- if lookup('env', 'BREAKGLASS') != '' -%}
{{ lookup('env', 'BREAKGLASS') }}
{%- else -%}
{{ project_breakglass|default(ansible_date_time.epoch|hash('md5')|truncate(8, true, '') + '_Azure') }}
{%- endif -%}
tasks:
- debug: var=prefix
- debug: var=breakglass_pw
- name: "Create Resource Group"
azure_rm_resourcegroup:
name: "{{ prefix }}"
location: "{{ location }}"
# Yes, this is not good practice, but it's just for a POV/POC
- name: "Create Any-Any Allow Security Group"
azure_rm_securitygroup:
resource_group: "{{ prefix }}"
name: "{{ prefix }}AnyAnyAllow"
rules:
- name: AllowAllInbound
protocol: "*"
destination_port_range: "*"
access: Allow
priority: 100
direction: Inbound
- name: AllowAllOutbound
protocol: "*"
destination_port_range: "*"
access: Allow
priority: 100
direction: Outbound
- name: "Create Storage Account"
azure_rm_storageaccount:
resource_group: "{{ prefix }}"
name: "{{ prefix }}storage"
account_type: Standard_LRS
- name: "Create VNET"
azure_rm_virtualnetwork:
resource_group: "{{ prefix }}"
name: "{{ prefix }}network01"
address_prefixes_cidr: "10.0.0.0/8"
- name: "Schedule UDR Creation"
azure_rm_routetable:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.value.name }}_udr"
with_dict: "{{ network }}"
loop_control:
label: "{{ prefix }}{{ item.value.name }}"
when: item.value.gateway is defined
async: 1000
poll: 0
register: sleeper
- name: "Check UDRs Created"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Subnet Creation"
azure_rm_subnet:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.value.name }}"
address_prefix: "{{ item.value.prefix }}.0/24"
virtual_network: "{{ prefix }}network01"
route_table: |
{%- if item.value.gateway is defined -%}
{{ prefix }}{{ item.value.name }}_udr
{%- else -%}
{{ omit }}{%- endif -%}
with_dict: "{{ network }}"
loop_control:
label: "{{ prefix }}{{ item.value.name }}"
async: 1000
poll: 0
register: sleeper
- name: "Check Subnet Created"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Route Creation"
azure_rm_route:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.value.name }}"
address_prefix: "0.0.0.0/0"
route_table_name: "{{ prefix }}{{ item.value.name }}_udr"
next_hop_type: virtual_appliance
next_hop_ip_address: "{{ item.value.gateway }}"
with_dict: "{{ network }}"
loop_control:
label: "{{ prefix }}{{ item.value.name }}"
when: item.value.gateway is defined
async: 1000
poll: 0
register: sleeper
- name: "Check Routes Created"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Public IP creation"
azure_rm_publicipaddress:
resource_group: "{{ prefix }}"
allocation_method: Static
name: "{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}pubip"
with_subelements:
- "{{ appliances }}"
- ports
when: item.1.public is not defined or (item.1.public is defined and item.1.public == 'true')
loop_control:
label: "{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}pubip"
async: 1000
poll: 0
register: sleeper
- name: "Check Public IPs Created"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Network Interface Creation"
azure_rm_networkinterface:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}"
virtual_network: "{{ prefix }}network01"
subnet: "{{ prefix }}{{ item.1.subnet.name }}"
public_ip_name: "{{ prefix }}pubip01"
security_group: "{{ prefix }}AnyAnyAllow"
ip_configurations:
- name: "{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}"
public_ip_address_name: |
{%- if item.1.public is not defined or (item.1.public is defined and item.1.public == 'true') -%}
{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}pubip
{%- else -%}{%- endif -%}"
primary: yes
with_subelements:
- "{{ appliances }}"
- ports
loop_control:
label: "{{ prefix }}{{ item.0.name }}port{{ item.1.subnet.name }}"
async: 1000
poll: 0
register: sleeper
- name: "Check Network Interfaces Created"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
- name: "Schedule Virtual Machine Creation - Priority 0 (or 'All')"
azure_rm_virtualmachine:
resource_group: "{{ prefix }}"
name: "{{ prefix }}{{ item.value.name }}"
vm_size: "{{ item.value.size }}"
storage_account: "{{ prefix }}storage"
storage_container: "{{ prefix }}{{ item.value.name }}os"
storage_blob: "{{ prefix }}{{ item.value.name }}os.vhd"
admin_username: breakglass
admin_password: "{{ breakglass_pw }}"
network_interfaces: |
[
{%- for nw in item.value.ports -%}
'{{ prefix }}{{ item.value.name }}port{{ nw.subnet.name }}'
{%- if not loop.last -%}, {%- endif -%}
{%- endfor -%}
]
custom_data: |
{%- if item.value.provision_script is defined and item.value.provision_script != '' -%}
{%- include(item.value.provision_script) -%}
{%- elif item.value.image.provision_script is defined and item.value.image.provision_script != '' -%}
{%- include(item.value.image.provision_script) -%}
{%- else -%}
{{ omit }}
{%- endif -%}
image:
publisher: "{{ item.value.image.publisher }}"
offer: "{{ item.value.image.offer }}"
sku: "{{ item.value.image.sku }}"
version: "{{ item.value.image.version }}"
plan: |
{%- if item.value.image.plan is not defined -%}{{ omit }}{%- else -%}
{'name': '{{ item.value.image.sku }}',
'publisher': '{{ item.value.image.publisher }}',
'product': '{{ item.value.image.offer }}'
}
{%- endif -%}
with_dict: "{{ appliances }}"
when: item.value.priority | default(0) == 0
loop_control:
label: "{{ prefix }}{{ item.value.name }}"
async: 1000
poll: 0
register: sleeper
- name: "Check Virtual Machines Created - Priority 0"
async_status:
jid: "{{ item.ansible_job_id }}"
register: sleeper_status
until: sleeper_status.finished
retries: 500
delay: 4
with_items: "{{ sleeper.results }}"
when: item.ansible_job_id is defined
loop_control:
label: "{{ item._ansible_item_label }}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment