├── .gitattributes
├── .gitignore
├── .gitlab-ci.yml
├── .pre-commit-config.yaml
├── .talismanrc
├── .terraform.lock.hcl
├── .tflint.hcl
├── CHANGELOG.md
├── LICENSE.txt
├── README.md
├── TERMS_OF_USE.txt
├── TROUBLE.md
├── analytics
├── analytics.tf
└── variables.tf
├── azure.tf
├── cleanup.sh
├── cloud-libs-notes.sh
├── demo.sh
├── demo_app
├── app.tf
└── variables.tf
├── dockerfile
├── firewall.tf
├── gitleaks.sh
├── hashicorp.asc
├── jumpboxes
├── DisableInternetExplorer-ESC.ps1
├── linux.tf
├── variables.tf
└── windows.tf
├── main.tf
├── makefile
├── network.tf
├── one_tier
└── firewall
│ ├── bigip.tf
│ ├── ilb.tf
│ ├── outputs.tf
│ └── variables.tf
├── outputs.tf
├── prepare
├── setupAzureGovVars_local.sh
├── setupAzureGovVars_vault.sh
└── setupAzureVars.sh
├── providers.tf
├── requirements.txt
├── templates
├── ips-cloud-init.yaml
├── onboard.tpl
├── telemetry_dashboard.omsview
└── ts.json
├── three_tier
├── firewall
│ ├── bigip.tf
│ ├── outputs.tf
│ └── variables.tf
├── ips
│ ├── ips.tf
│ └── variables.tf
└── waf
│ ├── bigip.tf
│ ├── outputs.tf
│ └── variables.tf
└── variables.tf
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # custom
2 | admin.auto.tfvars
3 | .envVarsHelper.sh
4 | vm_as3_data.json
5 | vm01_do_data.json
6 | vm02_do_data.json
7 | onboard.sh
8 | # Local .terraform directories
9 | **/.terraform/*
10 |
11 | # .tfstate files
12 | *.tfstate
13 | *.tfstate.*
14 | .terraform.lock.hcl
15 |
16 | # Crash log files
17 | crash.log
18 |
19 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most
20 | # .tfvars files are managed as part of configuration and so should be included in
21 | # version control.
22 | #
23 | # example.tfvars
24 |
25 | # Ignore override files as they are usually used to override resources locally and so
26 | # are not checked in
27 | override.tf
28 | override.tf.json
29 | *_override.tf
30 | *_override.tf.json
31 |
32 | # Include override files you do wish to add to version control using negated pattern
33 | #
34 | # !example_override.tf
35 |
36 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
37 | # example: *tfplan*
38 |
39 | *_data.json
40 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | default:
2 | image:
3 | name: hashicorp/terraform
4 | entrypoint: [""]
5 |
6 | before_script:
7 | - rm -rf .terraform
8 | - terraform --version
9 | - terraform init
10 |
11 | stages:
12 | - validate
13 | - plan
14 | - apply
15 | - destroy
16 |
17 | validate:
18 | stage: validate
19 | script:
20 | - terraform validate
21 |
22 | plan:
23 | stage: plan
24 | script:
25 | - terraform plan --out plan
26 | artifacts:
27 | paths:
28 | - plan
29 |
30 | apply:
31 | stage: apply
32 | environment:
33 | name: production
34 | script:
35 | - terraform apply --auto-approve plan
36 | - terraform state list
37 | when: manual
38 | allow_failure: false
39 | artifacts:
40 | paths:
41 | - terraform.tfstate
42 |
43 | destroy:
44 | stage: destroy
45 | environment:
46 | name: production
47 | script:
48 | - terraform destroy --auto-approve
49 | when: manual
50 | only:
51 | - main
52 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | default_language_version:
3 | python: python3.8
4 | repos:
5 | - repo: https://github.com/antonbabenko/pre-commit-terraform
6 | rev: v1.48.0
7 | hooks:
8 | - id: terraform_fmt
9 | #- id: terraform_validate
10 | - id: terraform_tflint
11 | - id: terraform_docs
12 | args: ['--args=--required=false', '--args=--sort=false']
13 | #- id: terraform_tfsec
14 | - repo: https://github.com/pre-commit/pre-commit-hooks
15 | rev: v3.4.0
16 | hooks:
17 | - id: check-executables-have-shebangs
18 | - id: check-case-conflict
19 | - id: check-merge-conflict
20 | - id: detect-private-key
21 | - id: detect-aws-credentials
22 | - id: end-of-file-fixer
23 | #- id: sort-simple-yaml
24 | - id: check-yaml
25 | args: ['./templates/ips-cloud-init.yaml']
26 | #- id: check-json
27 | - id: trailing-whitespace
28 | - repo: https://github.com/frnmst/md-toc
29 | rev: 7.1.0
30 | hooks:
31 | - id: md-toc
32 | - repo: https://github.com/thoughtworks/talisman
33 | rev: v1.11.0
34 | hooks:
35 | - id: talisman-commit
36 |
--------------------------------------------------------------------------------
/.talismanrc:
--------------------------------------------------------------------------------
1 | fileignoreconfig:
2 | - filename: releases/v1.0.0/gen_env.py
3 | checksum: bb4864de7bde210cfc0c8f878d955f15f60954f48aa04cc40a2221432d0249c8
4 | - filename: terraform.tfstate.backup
5 | checksum: ea58aa4892e5b512a283694edbb63576f903239db49db93a43381b607e1371ae
6 | - filename: releases/v2.6.1/scripts/verifyHash
7 | checksum: 0e0ae811decd15b4c5449e7b953d178fb1893b768bad740b5c30891623fab9f9
8 | - filename: releases/v1.0.0/roles/f5-azure-scca/files/azuredeploy.json
9 | checksum: 72fdbe241c91b57ef9603ed356a6378b2acc8e9a1f9e9e1094d61766057997d0
10 | - filename: releases/v1.0.0/roles/f5-azure-scca-internal-setup/files/basic-asm-apache.xml
11 | checksum: 2efc1f44d9f95df614842982407362b1f5c35060e2108026275ca1d167641218
12 | - filename: releases/v1.0.0/roles/f5-azure-scca-internal/files/azuredeploy.json
13 | checksum: 429c57d621e3d9bae9101a820921c62ecbe484aca7e655b8422f6e366f1aeb8e
14 | - filename: releases/v1.0.0/roles/f5-azure-scca-external/files/azuredeploy.json
15 | checksum: 1da439240cad8af2ad7935ddcd11b511a0abbd5303e9c96a3737227d68f912d6
16 | - filename: releases/v2.6.1/scripts/mcinstallCloudLibs.b64
17 | checksum: 8eb83bfea54ec39959060b2fe91aae5ef3db52ff3d893cc0e4e574a90fcaa0a0
18 | - filename: releases/v2.6.1/3NIC_3Tier_HA/bigiq/azureDeploy.json
19 | checksum: f96b4e7c9ad049a5a923476eb02e9e765c2f8d73f27ca8558462720dd227035c
20 | - filename: releases/v2.6.1/3NIC_1Tier_HA/payg/azureDeploy.json
21 | checksum: 7849ca1630ca9e2a375c9a01cf7385d830f3f0449fe14921038b7306392030a4
22 | - filename: releases/v2.6.1/3NIC_1Tier_HA/bigiq/azureDeploy.json
23 | checksum: a87686116cf62d2c55bcdbec5239689977783605a249672a0a940a70e2c2fb1e
24 | - filename: releases/v2.6.1/3NIC_3Tier_HA/byol/azureDeploy.json
25 | checksum: 493412d7d13713beedf81493d70c2387e49caeea6887cd11b6d8bbfcd8177d94
26 | - filename: releases/v2.6.1/3NIC_1Tier_HA/byol/azureDeploy.json
27 | checksum: bacc9e0c8b843199838328d6020abd5a8cdbcadddea433598ede8bd581888a65
28 | - filename: releases/v2.6.1/3NIC_3Tier_HA/payg/azureDeploy.json
29 | checksum: 17746802719e00c792c2812330ffd8fd4ce21e9f3bcd5a642fdb1857bcdf22f4
30 | - filename: releases/v1.0.0/roles/f5-azure-scca-internal-setup/vars/main.yml
31 | checksum: 2738b86693fe4e631c2db2257337655fbb88180be6b329c8de4f469f7b3b23ab
32 | - filename: releases/v2.6.1/scripts/Disable-ieESC.ps1
33 | checksum: 5720913d54c69ce773fefdfaef62392b8b2419c4a29a4ba0d7b28ec9b9673ad0
34 | - filename: releases/v1.0.0/roles/f5-azure-scca/vars/main.yml
35 | checksum: 49418879206e6dc724f4555a53e5458f349dc45f72da70935d7c19fa49697569
36 | - filename: releases/v1.0.0/roles/f5-azure-scca-internal-setup/tasks/main.yml
37 | checksum: babe890bc3bf90ea733fb3f5f14e8ab52056a2f9722a0c8213e0c536197717f7
38 | - filename: releases/v2.6.1/scripts/atc_install.sh
39 | checksum: 9917a97b7cac13276756f2680e5c5d3315cd3ccf5d5fe2ff0c51f9d648afb0a1
40 | - filename: releases/v2.6.1/scripts/deploy_app.sh
41 | checksum: 1412c87a6310d5f7a82bf50c6eaa23543410c3d6b5d4c7b39a875cd7ae576498
42 | - filename: releases/v1.0.0/roles/f5-azure-scca-internal-setup/files/f5.policy_creator.tmpl
43 | checksum: bca3d52bc89a82a29002cfd73701e9666676ee00ec8d3bc81d412a82e044c6bf
44 | - filename: releases/v1.0.0/doall.sh
45 | checksum: a110ddd9051d5a0e7817f77a87b97f2d3b4a77034b7373d5913c374d0fd86e7f
46 | - filename: releases/v1.0.0/run.sh
47 | checksum: 3c01c2703678ed97abe45b61ccbfca7828e3a689fd51086106e1bf636b52ad6f
48 | - filename: releases/v1.0.0/savevars.sh
49 | checksum: b1f33b1bee1b59f5595621020b5ecdecd4f91d36deaac0e113d5e568da87cc32
50 | - filename: releases/v1.0.0/roles/f5-azure-scca-external-setup/files/f5.cloud_logger.v1.0.0.tmpl
51 | checksum: 8155890106dcff99874b1e9865e5b935678c5770740cf7d03e2779d0526a48f4
52 | - filename: releases/v1.0.0/roles/f5-azure-scca-internal/vars/main.yml
53 | checksum: 279c2689e717279d2df90cdcc93faa3150804866e255d5fb14ab533fd942a6c2
54 | - filename: releases/v1.0.0/roles/f5-azure-scca-external/vars/main.yml
55 | checksum: 47cb4a6ec594ec42c3135d248a216bbd4bd4e2b59f1f990f7d804a3f1939cfb2
56 | - filename: releases/v1.0.0/roles/f5-azure-scca-internal-setup/files/f5.cloud_logger.v1.0.0.tmpl
57 | checksum: 660bd1a6dea6a421cacbdd3f0bd6169dc2be079a8c886ac2f1ba6216895b3da3
58 | - filename: releases/v1.0.0/library/bigip_static_route.py
59 | checksum: 1eb0b75837856b529dc296ae56507abf28a17dc04837ca2ddd05409ddc3cbf4e
60 | - filename: releases/v1.0.0/roles/f5-azure-scca-external-setup/tasks/main.yml
61 | checksum: 5d5c60b42694e2dddcf80d72539fbd2f4769b893fa7cd8365d8a6de5df2ac0be
62 | - filename: releases/v1.0.0/update-vip-udr.yaml
63 | checksum: 58870a90727e5a4bf251b94f6cb419de7a964d2fe3707652a724eccbd7be836e
64 | - filename: releases/v1.0.0/azure_rm.py
65 | checksum: d6a8344eaf8e17ddc9401301c10108e63a71fb90149f58e4aa74a02ac0bf972c
66 | - filename: releases/v1.0.0/roles/f5-azure-scca-external-setup/vars/main.yml
67 | checksum: f837aa0b170948147dfe03a21133677019943807b418fbac51cbf5898897a531
68 | - filename: releases/v1.0.0/revoke-license.yaml
69 | checksum: dc51a97be04532fde8a22a0b87f8ee62a324560b31247ffc2e21b2ca1b1f8396
70 | - filename: releases/v1.0.0/grab_vars.py
71 | checksum: ea9da279f79b6082f77c00819a8781233cc91d450a440f44a5c00fad48c78fa3
72 | - filename: releases/v1.0.0/roles/f5-azure-scca-internal-setup/files/f5.http.v1.2.0rc7.tmpl
73 | checksum: f7a9b764605c4280db5fa1daa4271ec4c64a9d250a61fe866aeacc8349deac2b
74 |
--------------------------------------------------------------------------------
/.terraform.lock.hcl:
--------------------------------------------------------------------------------
1 | # This file is maintained automatically by "terraform init".
2 | # Manual edits may be lost in future updates.
3 |
4 | provider "registry.terraform.io/hashicorp/azurerm" {
5 | version = "3.46.0"
6 | constraints = "3.46.0"
7 | hashes = [
8 | "h1:hCCSjeSMrt6/hS6byqecfDVHBgiwD3BCUy1YtJJl4So=",
9 | "zh:02327ad31c998d9d55bafd280a4b1bd3702b496e49f53fad30823712cc85368a",
10 | "zh:05882df6b5b59d23e2aa0c454caea84fcc35e435eb925e18293415260b4850c8",
11 | "zh:0c0d6309abcfa24f0775df9bff81cb8f63029fead66956316d7cfa837c231873",
12 | "zh:3607e8f5da720e053f7bada6b7c21b018ba25ccff8dade66bb64c2544214b400",
13 | "zh:5662a2910bda19242b7be6bd7582a514082309691c97ee97aa9cf45bbbf45af4",
14 | "zh:58d6de82cf26e2764f3d57d0e032b06cc97c90756044486b206d83cea53d3f7a",
15 | "zh:5ee2f224ac1185e44fc4a2d60deb5c4a162d0fda07516e0939520cb8dcbedaca",
16 | "zh:bbb6f9fd9cb6e8a79c9e1e3ce74647f743f60f3ea2c325b9aececf4a55ec0343",
17 | "zh:c9d923b415f411eb68dfd43fab1753087b4701caeceb94550df562ca417c6007",
18 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
19 | "zh:f6157b462ed33c27f101113b46463130d00de7f2731e05a371c922e5730a4b5e",
20 | "zh:f96be10c899c0e30870056ec9c2c5002ec2e4f07fe2a64e1b3135ec232ef6f1e",
21 | ]
22 | }
23 |
24 | provider "registry.terraform.io/hashicorp/http" {
25 | version = "2.1.0"
26 | constraints = "2.1.0"
27 | hashes = [
28 | "h1:HmUcHqc59VeHReHD2SEhnLVQPUKHKTipJ8Jxq67GiDU=",
29 | "zh:03d82dc0887d755b8406697b1d27506bc9f86f93b3e9b4d26e0679d96b802826",
30 | "zh:0704d02926393ddc0cfad0b87c3d51eafeeae5f9e27cc71e193c141079244a22",
31 | "zh:095ea350ea94973e043dad2394f10bca4a4bf41be775ba59d19961d39141d150",
32 | "zh:0b71ac44e87d6964ace82979fc3cbb09eb876ed8f954449481bcaa969ba29cb7",
33 | "zh:0e255a170db598bd1142c396cefc59712ad6d4e1b0e08a840356a371e7b73bc4",
34 | "zh:67c8091cfad226218c472c04881edf236db8f2dc149dc5ada878a1cd3c1de171",
35 | "zh:75df05e25d14b5101d4bc6624ac4a01bb17af0263c9e8a740e739f8938b86ee3",
36 | "zh:b4e36b2c4f33fdc44bf55fa1c9bb6864b5b77822f444bd56f0be7e9476674d0e",
37 | "zh:b9b36b01d2ec4771838743517bc5f24ea27976634987c6d5529ac4223e44365d",
38 | "zh:ca264a916e42e221fddb98d640148b12e42116046454b39ede99a77fc52f59f4",
39 | "zh:fe373b2fb2cc94777a91ecd7ac5372e699748c455f44f6ea27e494de9e5e6f92",
40 | ]
41 | }
42 |
43 | provider "registry.terraform.io/hashicorp/local" {
44 | version = "2.3.0"
45 | hashes = [
46 | "h1:+l9ZTDGmGdwnuYI5ftUjwP8UgoLw4f4V9xoCzal4LW0=",
47 | "zh:1f1920b3f78c31c6b69cdfe1e016a959667c0e2d01934e1a084b94d5a02cd9d2",
48 | "zh:550a3cdae0ddb350942624e7b2e8b31d28bc15c20511553432413b1f38f4b214",
49 | "zh:68d1d9ccbfce2ce56b28a23b22833a5369d4c719d6d75d50e101a8a8dbe33b9b",
50 | "zh:6ae3ad6d865a906920c313ec2f413d080efe32c230aca711fd106b4cb9022ced",
51 | "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
52 | "zh:a0f413d50f54124057ae3dcd9353a797b84e91dc34bcf85c34a06f8aef1f9b12",
53 | "zh:a2ac6d4088ceddcd73d88505e18b8226a6e008bff967b9e2d04254ef71b4ac6b",
54 | "zh:a851010672e5218bdd4c4ea1822706c9025ef813a03da716d647dd6f8e2cffb0",
55 | "zh:aa797561755041ef2fad99ee9ffc12b5e724e246bb019b21d7409afc2ece3232",
56 | "zh:c6afa960a20d776f54bb1fc260cd13ead17280ebd87f05b9abcaa841ed29d289",
57 | "zh:df0975e86b30bb89717b8c8d6d4690b21db66de06e79e6d6cfda769f3304afe6",
58 | "zh:f0d3cc3da72135efdbe8f4cfbfb0f2f7174827887990a5545e6db1981f0d3a7c",
59 | ]
60 | }
61 |
62 | provider "registry.terraform.io/hashicorp/random" {
63 | version = "3.4.3"
64 | hashes = [
65 | "h1:xZGZf18JjMS06pFa4NErzANI98qi59SEcBsOcS2P2yQ=",
66 | "zh:41c53ba47085d8261590990f8633c8906696fa0a3c4b384ff6a7ecbf84339752",
67 | "zh:59d98081c4475f2ad77d881c4412c5129c56214892f490adf11c7e7a5a47de9b",
68 | "zh:686ad1ee40b812b9e016317e7f34c0d63ef837e084dea4a1f578f64a6314ad53",
69 | "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
70 | "zh:84103eae7251384c0d995f5a257c72b0096605048f757b749b7b62107a5dccb3",
71 | "zh:8ee974b110adb78c7cd18aae82b2729e5124d8f115d484215fd5199451053de5",
72 | "zh:9dd4561e3c847e45de603f17fa0c01ae14cae8c4b7b4e6423c9ef3904b308dda",
73 | "zh:bb07bb3c2c0296beba0beec629ebc6474c70732387477a65966483b5efabdbc6",
74 | "zh:e891339e96c9e5a888727b45b2e1bb3fcbdfe0fd7c5b4396e4695459b38c8cb1",
75 | "zh:ea4739860c24dfeaac6c100b2a2e357106a89d18751f7693f3c31ecf6a996f8d",
76 | "zh:f0c76ac303fd0ab59146c39bc121c5d7d86f878e9a69294e29444d4c653786f8",
77 | "zh:f143a9a5af42b38fed328a161279906759ff39ac428ebcfe55606e05e1518b93",
78 | ]
79 | }
80 |
81 | provider "registry.terraform.io/hashicorp/template" {
82 | version = "2.2.0"
83 | hashes = [
84 | "h1:94qn780bi1qjrbC3uQtjJh3Wkfwd5+tTtJHOb7KTg9w=",
85 | "zh:01702196f0a0492ec07917db7aaa595843d8f171dc195f4c988d2ffca2a06386",
86 | "zh:09aae3da826ba3d7df69efeb25d146a1de0d03e951d35019a0f80e4f58c89b53",
87 | "zh:09ba83c0625b6fe0a954da6fbd0c355ac0b7f07f86c91a2a97849140fea49603",
88 | "zh:0e3a6c8e16f17f19010accd0844187d524580d9fdb0731f675ffcf4afba03d16",
89 | "zh:45f2c594b6f2f34ea663704cc72048b212fe7d16fb4cfd959365fa997228a776",
90 | "zh:77ea3e5a0446784d77114b5e851c970a3dde1e08fa6de38210b8385d7605d451",
91 | "zh:8a154388f3708e3df5a69122a23bdfaf760a523788a5081976b3d5616f7d30ae",
92 | "zh:992843002f2db5a11e626b3fc23dc0c87ad3729b3b3cff08e32ffb3df97edbde",
93 | "zh:ad906f4cebd3ec5e43d5cd6dc8f4c5c9cc3b33d2243c89c5fc18f97f7277b51d",
94 | "zh:c979425ddb256511137ecd093e23283234da0154b7fa8b21c2687182d9aea8b2",
95 | ]
96 | }
97 |
--------------------------------------------------------------------------------
/.tflint.hcl:
--------------------------------------------------------------------------------
1 | plugin "azurerm" {
2 | enabled = true
3 | }
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | ## 3.0.0
6 |
7 | - converted everything to terraform, added all outstanding features.
8 |
9 | ## [2.6.1] - 2020-03-10
10 |
11 | ### Changed
12 |
13 | - 3 Tier: Changed DeclarationURL to Tier 1 and Tier 3 Declaration URLs to allow seperate AS3 declarations for each tier.
14 | - Adjusted outputs to proper PIP FQDN output
15 | - Extensive Changes to Microsoft.Compute/virtualMachines/extensions commandToExecute to help optimize time and clean up order of operations.
16 | - Updated BYOL template AS3 release, and moved everything to b64 scripts
17 | - removed SACAv1 Deploy button
18 | - added deploy buttons for payg and bigiq
19 |
20 | ### Added
21 |
22 | - PAYG template options
23 | - Tier 1 & 3 Module Parameters
24 |
25 | ## [2.5] - 2020-03-02
26 |
27 | ### Fixed
28 |
29 | - Resolved issue with Accelerated Networking Logic
30 |
31 | ### Changed
32 |
33 | - Rewrote and updated templates closer to F5 *supported* 7.0 templates.
34 | - Restricted templates to 14.1.2 and 15.0.1
35 |
36 | ### Added
37 |
38 | - Created several AS3 options; PAYG, BYOL, and Baseline.
39 | - Added parameter to select module provisioning
40 |
41 | ## [2.2] - 2019-08-06
42 |
43 | ### Changed
44 |
45 | - Made STIG a bool option in Parameters
46 | - Changed image to 14.1.00300
47 |
48 | ## [2.1] - 2019-07-10
49 |
50 | ### Added
51 |
52 | - AV Sets added to all VMs.
53 | - Managed Disks on all VMs.
54 | - Enabled HA Ports on ILB.
55 | - Added UDR for Default Route from VDMS Subnet.
56 |
57 | ### Updated
58 |
59 | - Updated Public IP(s) to Standard SKU.
60 | - Updated ALB to Standard SKU.
61 | - Updated ILB to Standard SKU.
62 | - Updated verifyHash
63 | - Updated
64 |
65 | ### Removed
66 |
67 | - PUA Option removed due to SKU.
68 |
69 | ## [2.0.2] - 2019-03-13
70 |
71 | ### Added
72 |
73 | - Preloaded DOD Root CA Bundle v5.5.
74 | - Added PUA Option.
75 |
76 | ## [2.0.1] - 2019-03-13
77 |
78 | ### Added
79 |
80 | - CHANGELOG created.
81 |
82 | ### Removed
83 |
84 | - Unused variables.
85 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2015, F5 Networks, Inc.
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
5 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # F5 & Azure Secure Cloud Computing Architecture
2 |
3 |
4 |
5 | - [F5 & Azure Secure Cloud Computing Architecture](#f5--azure-secure-cloud-computing-architecture)
6 | - [Introduction](#introduction)
7 | - [Prerequisites](#prerequisites)
8 | - [Important configuration notes](#important-configuration-notes)
9 | - [PAYG versus BYOL Settings](#payg-versus-byol-settings)
10 | - [Variables](#variables)
11 | - [Requirements](#requirements)
12 | - [Providers](#providers)
13 | - [Inputs](#inputs)
14 | - [Outputs](#outputs)
15 | - [Deployment](#deployment)
16 | - [Docker](#docker)
17 | - [Destruction](#destruction)
18 | - [Docker](#docker-1)
19 | - [Development](#development)
20 |
21 |
22 |
23 | ## Introduction
24 |
25 | Moving to the Cloud can be tough. The Department of Defense (DoD) has requirements to protect the Defense Information System Networks (DISN) and DoD Information Networks (DoDIN), even for workloads residing in a Cloud Service Provider (CSP). Per the SCCA Functional Requirements Document, the purpose of SCCA is to provide a barrier of protection between the DISN and commercial cloud services used by the DoD.
26 |
27 | “It specifically addresses attacks originating from mission applications that reside within the Cloud Service Environment (CSE) upon both the DISN infrastructure and neighboring tenants in a multi-tenant environment. It provides a consistent CSP independent level of security that enables the use of commercially available Cloud Service Offerings (CSO) for hosting DoD mission applications operating at all DoD Information System Impact Levels (i.e. 2, 4, 5, & 6).” * [https://dl.dod.cyber.mil/wp-content/uploads/cloud/pdf/SCCA_FRD_v2-9.pdf](https://dl.dod.cyber.mil/wp-content/uploads/cloud/pdf/SCCA_FRD_v2-9.pdf)
28 |
29 | This solution uses Terraform to launch a Single Tiered or Three Tier deployment of three NIC cloud-focused BIG-IP VE cluster(s) (Active/Standby) in Microsoft Azure. This is the standard cloud design where the BIG-IP VE instance is running with three interfaces, where both management and data plane traffic is segregated.
30 |
31 | The BIG-IP VEs have the following features / modules enabled:
32 |
33 | - [Local / Global Availability](https://f5.com/products/big-ip/local-traffic-manager-ltm)
34 |
35 | - [Firewall](https://www.f5.com/products/security/advanced-firewall-manager)
36 | - Firewall with Intrusion Protection and IP Intelligence only available with BYOL deployments today.
37 |
38 | - [Web Application Firewall](https://www.f5.com/products/security/advanced-waf)
39 |
40 | ## Prerequisites
41 |
42 | - **Important**: When you configure the admin password for the BIG-IP VE in the template, you cannot use the character **#**. Additionally, there are a number of other special characters that you should avoid using for F5 product user accounts. See [K2873](https://support.f5.com/csp/article/K2873) for details.
43 | - This template requires a service principal, one will be created in the provided script at ./prepare/setupAzureGovVars_local.sh.
44 | - **Important** For gov cloud deployments its important to run this script to prepare your environment, whether local or Azure Cloud CLI based. There are extra env variables that ned to be passed by TF to Gov Cloud Regions.
45 | - This deployment will be using the Terraform Azurerm provider to build out all the neccessary Azure objects. Therefore, Azure CLI is required. for installation, please follow this [Microsoft link](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-apt?view=azure-cli-latest)
46 | - If this is the first time to deploy the F5 image, the subscription used in this deployment needs to be enabled to programatically deploy. For more information, please refer to [Configure Programatic Deployment](https://azure.microsoft.com/en-us/blog/working-with-marketplace-images-on-azure-resource-manager/)
47 | - You need to set your region and log in to azure ahead of time, the scripts will map your authenitcation credentials and create a service principle, so you will not need to hardcode any credentials in the files.
48 |
49 | ## Important configuration notes
50 |
51 | - All variables are configured in variables.tf
52 | - **MOST** STIG / SRG configurations settings have been addressed in the Declarative Onboarding and Application Services templates used in this example.
53 | - An Example application is optionally deployed with this template. The example appliation includes several apps running in docker on the host:
54 | - Juiceshop on port 3000
55 | - F5 Demo app by Eric Chen on ports 80 and 443
56 | - rsyslogd with PimpMyLogs on port 808
57 | - **Note** Juiceshop and PimpMyLogs URLS are part of the terraform output when deployed.
58 | - All Configuration should happen at the root level; auto.tfvars or variables.tf.
59 |
60 | ## PAYG versus BYOL Settings
61 |
62 | - For PAYG deployments the variables image_name and product need to be configured accordingly, default values are set for PAYG.
63 | - Example: image_name = f5-bigip-virtual-edition-1g-best-hourly and product = f5-big-ip-best
64 |
65 | - For BYOL deployments the variables image_name, product, and licenses need to be configured accordingly.
66 | - Example: image_name = f5-big-all-2slot-byol, product = f5-big-ip-byol, and licenses = appropriate licenses.
67 | ## Variables
68 |
69 |
70 | ## Requirements
71 |
72 | | Name | Version |
73 | |------|---------|
74 | | terraform | ~> 0.13 |
75 |
76 | ## Providers
77 |
78 | | Name | Version |
79 | |------|---------|
80 | | azurerm | n/a |
81 |
82 | ## Inputs
83 |
84 | | Name | Description | Type | Default |
85 | |------|-------------|------|---------|
86 | | projectPrefix | REQUIRED: Prefix to prepend to all objects created, minus Windows Jumpbox | `string` | `"ccbad9e7"` |
87 | | adminUserName | REQUIRED: Admin Username for All systems | `string` | `"xadmin"` |
88 | | adminPassword | REQUIRED: Admin Password for all systems | `string` | `"pleaseUseVault123!!"` |
89 | | location | REQUIRED: Azure Region: usgovvirginia, usgovarizona, etc. For a list of available locations for your subscription use `az account list-locations -o table` | `string` | `"usgovvirginia"` |
90 | | region | Azure Region: US Gov Virginia, US Gov Arizona, etc | `string` | `"US Gov Virginia"` |
91 | | deploymentType | REQUIRED: This determines the type of deployment; one tier versus three tier: one\_tier, three\_tier | `string` | `"three_tier"` |
92 | | deployDemoApp | OPTIONAL: Deploy Demo Application with Stack. Recommended to show functionality. Options: deploy, anything else. | `string` | `"deploy"` |
93 | | sshPublicKey | OPTIONAL: ssh public key for instances | `string` | `""` |
94 | | sshPublicKeyPath | OPTIONAL: ssh public key path for instances | `string` | `"/mykey.pub"` |
95 | | cidr | REQUIRED: VNET Network CIDR | `string` | `"10.90.0.0/16"` |
96 | | subnets | REQUIRED: Subnet CIDRs | `map(string)` |
{
"application": "10.90.10.0/24",
"external": "10.90.1.0/24",
"inspect_ext": "10.90.4.0/24",
"inspect_int": "10.90.5.0/24",
"internal": "10.90.2.0/24",
"management": "10.90.0.0/24",
"vdms": "10.90.3.0/24",
"waf_ext": "10.90.6.0/24",
"waf_int": "10.90.7.0/24"
}
|
97 | | f5\_mgmt | F5 BIG-IP Management IPs. These must be in the management subnet. | `map(string)` | {
"f5vm01mgmt": "10.90.0.4",
"f5vm02mgmt": "10.90.0.5",
"f5vm03mgmt": "10.90.0.6",
"f5vm04mgmt": "10.90.0.7"
}
|
98 | | f5\_t1\_ext | Tier 1 BIG-IP External IPs. These must be in the external subnet. | `map(string)` | {
"f5vm01ext": "10.90.1.4",
"f5vm01ext_sec": "10.90.1.11",
"f5vm02ext": "10.90.1.5",
"f5vm02ext_sec": "10.90.1.12"
}
|
99 | | f5\_t1\_int | Tier 1 BIG-IP Internal IPs. These must be in the internal subnet. | `map(string)` | {
"f5vm01int": "10.90.2.4",
"f5vm01int_sec": "10.90.2.11",
"f5vm02int": "10.90.2.5",
"f5vm02int_sec": "10.90.2.12"
}
|
100 | | f5\_t3\_ext | Tier 3 BIG-IP External IPs. These must be in the waf external subnet. | `map(string)` | {
"f5vm03ext": "10.90.6.4",
"f5vm03ext_sec": "10.90.6.11",
"f5vm04ext": "10.90.6.5",
"f5vm04ext_sec": "10.90.6.12"
}
|
101 | | f5\_t3\_int | Tier 3 BIG-IP Internal IPs. These must be in the waf internal subnet. | `map(string)` | {
"f5vm03int": "10.90.7.4",
"f5vm03int_sec": "10.90.7.11",
"f5vm04int": "10.90.7.5",
"f5vm04int_sec": "10.90.7.12"
}
|
102 | | internalILBIPs | REQUIRED: Used by One and Three Tier. Azure internal load balancer ips, these are used for ingress and egress. | `map(string)` | `{}` |
103 | | ilb01ip | REQUIRED: Used by One and Three Tier. Azure internal load balancer ip, this is used as egress, must be in internal subnet. | `string` | `"10.90.2.10"` |
104 | | ilb02ip | REQUIRED: Used by Three Tier only. Azure waf external load balancer ip, this is used as egress, must be in waf\_ext subnet. | `string` | `"10.90.6.10"` |
105 | | ilb03ip | REQUIRED: Used by Three Tier only. Azure waf external load balancer ip, this is used as ingress, must be in waf\_ext subnet. | `string` | `"10.90.6.13"` |
106 | | ilb04ip | REQUIRED: Used by Three Tier only. Azure waf external load balancer ip, this is used as ingress, must be in inspect\_external subnet. | `string` | `"10.90.4.13"` |
107 | | app01ip | OPTIONAL: Example Application used by all use-cases to demonstrate functionality of deploymeny, must reside in the application subnet. | `string` | `"10.90.10.101"` |
108 | | ips01ext | Example IPS private ips | `string` | `"10.90.4.4"` |
109 | | ips01int | n/a | `string` | `"10.90.5.4"` |
110 | | ips01mgmt | n/a | `string` | `"10.90.0.8"` |
111 | | winjumpip | REQUIRED: Used by all use-cases for RDP/Windows Jumpbox, must reside in VDMS subnet. | `string` | `"10.90.3.98"` |
112 | | linuxjumpip | REQUIRED: Used by all use-cases for SSH/Linux Jumpbox, must reside in VDMS subnet. | `string` | `"10.90.3.99"` |
113 | | instanceType | BIGIP Instance Type, DS5\_v2 is a solid baseline for BEST | `string` | `"Standard_DS5_v2"` |
114 | | jumpinstanceType | Be careful which instance type selected, jump boxes currently use Premium\_LRS managed disks | `string` | `"Standard_B2s"` |
115 | | appInstanceType | Demo Application Instance Size | `string` | `"Standard_DS3_v2"` |
116 | | image\_name | REQUIRED: BIG-IP Image Name. 'az vm image list --output table --publisher f5-networks --location [region] --offer f5-big-ip --all' Default f5-bigip-virtual-edition-1g-best-hourly is PAYG Image. For BYOL use f5-big-all-2slot-byol | `string` | `"f5-bigip-virtual-edition-1g-best-hourly"` |
117 | | product | REQUIRED: BYOL = f5-big-ip-byol, PAYG = f5-big-ip-best | `string` | `"f5-big-ip-best"` |
118 | | bigip\_version | REQUIRED: BIG-IP Version. Note: verify available versions before using as images can change. | `string` | `"14.1.400000"` |
119 | | licenses | BIGIP Setup Licenses are only needed when using BYOL images | `map(string)` | {
"license1": "",
"license2": "",
"license3": "",
"license4": ""
}
|
120 | | hosts | n/a | `map(string)` | {
"host1": "f5vm01",
"host2": "f5vm02",
"host3": "f5vm03",
"host4": "f5vm04"
}
|
121 | | dns\_server | REQUIRED: Default is set to Azure DNS. | `string` | `"168.63.129.16"` |
122 | | asm\_policy | REQUIRED: ASM Policy. Examples: https://github.com/f5devcentral/f5-asm-policy-templates. Default: OWASP Ready Autotuning | `string` | `"https://raw.githubusercontent.com/f5devcentral/f5-asm-policy-templates/master/owasp_ready_template/owasp-auto-tune-v1.1.xml"` |
123 | | ntp\_server | n/a | `string` | `"time.nist.gov"` |
124 | | timezone | n/a | `string` | `"UTC"` |
125 | | onboard\_log | n/a | `string` | `"/var/log/startup-script.log"` |
126 | | tags | Environment tags for objects | `map(string)` | {
"application": "f5app",
"costcenter": "f5costcenter",
"environment": "f5env",
"group": "f5group",
"owner": "f5owner",
"purpose": "public"
}
|
127 |
128 | ## Outputs
129 |
130 | | Name | Description |
131 | |------|-------------|
132 | | DemoApplication\_443 | Public IP for applications. Https for example app, RDP for Windows Jumpbox, SSH for Linux Jumpbox |
133 | | rSyslogdHttp\_8080 | Public IP for applications. Https for example app, RDP for Windows Jumpbox, SSH for Linux Jumpbox |
134 | | tier\_one | One Tier Outputs: VM IDs, VM Mgmt IPs, VM External Private IPs |
135 | | tier\_three | Three Tier Outputs: VM IDs, VM Mgmt IPs, VM External Private IPs |
136 |
137 |
138 |
139 | ## Deployment
140 |
141 | For deployment you can do the traditional terraform commands or use the provided scripts.
142 |
143 | ```bash
144 | terraform init
145 | terraform plan
146 | terraform apply
147 | ```
148 |
149 | OR
150 |
151 | ```bash
152 | ./demo.sh
153 | ```
154 |
155 | ### Docker
156 | There is also a dockerfile provided, use make [options] to build as needed.
157 |
158 | ```bash
159 | make build
160 | make shell || make azure || make gov
161 | ```
162 |
163 | ## Destruction
164 |
165 | For destruction / tear down you can do the trafitional terraform commands or use the provided scripts.
166 |
167 | ```bash
168 | terraform destroy
169 | ```
170 |
171 | OR
172 |
173 | ```bash
174 | ./cleanup.sh
175 | ```
176 |
177 | ### Docker
178 |
179 | ```bash
180 | make destroy || make revolution
181 | ```
182 |
183 | ## Development
184 |
185 | Outline any requirements to setup a development environment if someone would like to contribute. You may also link to another file for this information.
186 |
187 | ```bash
188 | # test pre commit manually
189 | pre-commit run -a -v
190 | ```
191 |
--------------------------------------------------------------------------------
/TERMS_OF_USE.txt:
--------------------------------------------------------------------------------
1 | THIS LICENSE AGREEMENT IS ENTERED INTO BETWEEN THE SUBMITTING PARTY AND F5 NETWORKS, INC. AND THE SUBMITTING PARTY AGREES TO BE BOUND BY THE TERMS OF THIS AGREEMENT BY SUBMITTING, POSTING, DOWNLOADING, COPYING, MODIFYING, INPUTTING, INSTALLATION, UPLOAD OR OTHER USE OF F5 MATERIALS AND THE SUBMISSIONS. IF YOU DO NOT AGREE TO THE FOREGOING, DO NOT POST THE SUBISSIONS OR USE THE F5 MATERIALS.
2 | (1) F5 does not claim ownership of the materials you provide to F5 (including feedback and suggestions) or post, upload, input or submit to any F5 GitHub repository (collectively "Submissions"). However, by posting, uploading, inputting, providing or submitting your Submission you grant F5, its affiliated companies and necessary sub-licensees a full, complete, irrevocable copyright license to use your Submission including, without limitation, the rights to: copy, distribute, transmit, publicly display, publicly perform, reproduce, edit, translate and reformat your Submission; and to publish your name in connection with your Submission. In addition, you agree that your submission will be subject to the terms of the MIT License (https://github.com/f5devcentral/f5-postman-collections/LICENSE.txt).
3 | (2) By posting, uploading, inputting, providing or submitting your Submission you warrant and represent that you own, are approved by your employer, or otherwise control all of the rights to your Submission as described including, without limitation, all the rights necessary for you to provide, post, upload, input or submit the Submissions.
4 | (3) Infringement Indemnification. Submitting party will defend and indemnify F5 against a claim that any information, design, specification, instruction, software, data, or material furnished by the submitting party under this license infringes a trademark, copyright, or patent. F5 will notify the submitting party promptly of such claim and will give sole control of defense and all related settlement negotiations to submitting party. F5 will provide reasonable assistance, information, and authority necessary to perform these obligations. Reasonable out-of-pocket expenses incurred by F5 for providing such assistance will be reimbursed by the submitting party.
5 | (4) THE MATERIALS AND SERVICES MADE AVAILABLE AT AND THROUGH THIS SITE ARE PROVIDED BY F5 ON AN "AS IS" BASIS. F5 MAKES NO REPRESENTATIONS, WARRANTIES OR GUARANTIES OF ANY KIND, EXPRESS OR IMPLIED, AS TO THE OPERATION OF THIS SITE, ITS CONTENT, OR ANY PRODUCTS OR SERVICES DESCRIBED OR OFFERED BY THIS SITE. TO THE FULL EXTENT PERMISSIBLE BY APPLICABLE LAW, F5 DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY, INCLUDING MERCHANTABILITY OF COMPUTER PROGRAMS AND INFORMATIONAL CONTENT, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, TITLE, OR THAT THE SITE CONTENT IS RELIABLE, ACCURATE, OR TIMELY. F5 WILL NOT BE LIABLE FOR ANY DAMAGES OF ANY KIND ARISING FROM THE USE OF THIS SITE, INCLUDING, BUT NOT LIMITED TO DIRECT, INDIRECT, INCIDENTAL, PUNITIVE, SPECIAL, CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF USE, DATA OR PROFITS, ARISING OUT OF OR IN ANY WAY CONNECTED WITH THE USE OR PERFORMANCE OF THE WEB SITE, WITH THE DELAY OR INABILITY TO USE THE WEB SITE OR RELATED SERVICES, THE PROVISION OF OR FAILURE TO PROVIDE SERVICES, OR FOR ANY INFORMATION, SOFTWARE, PRODUCTS, SERVICES AND RELATED GRAPHICS OBTAINED THROUGH THE WEB SITE, OR OTHERWISE ARISING OUT OF THE USE OF THE WEB SITE, WHETHER BASED ON CONTRACT, TORT, NEGLIGENCE, STRICT LIABILITY OR OTHERWISE, EVEN IF F5 OR ANY OF ITS SUPPLIERS HAS BEEN ADVISED OF THE POSSIBILITY OF DAMAGES. BECAUSE SOME STATES/JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU. WHILE THIS SITE MAY PROVIDE LINKS TO THIRD PARTY SITES, F5 DOES NOT CONTROL OR ENDORSE ANY THIRD PARTY SITE AND DISCLAIMS ANY RESPONSIBILITY FOR ITS FUNCTIONALITY OR CONTENT. THESE DISCLAIMERS AND LIMITATIONS ARE MADE IN ADDITION TO THOSE MADE IN AND APPLICABLE TO VARIOUS PAGES OR SECTIONS OF THIS SITE.
6 |
--------------------------------------------------------------------------------
/TROUBLE.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/f5devcentral/f5-azure-saca/ebb56b4d72a641592d785600f6e5ac64eae06c75/TROUBLE.md
--------------------------------------------------------------------------------
/analytics/analytics.tf:
--------------------------------------------------------------------------------
1 | # Create Log Analytic Workspace
2 | resource "azurerm_log_analytics_workspace" "law" {
3 | name = "${var.prefix}-law"
4 | sku = "PerNode"
5 | retention_in_days = 300
6 | resource_group_name = var.resourceGroup.name
7 | location = var.location
8 | }
9 |
10 | data "template_file" "ts_json" {
11 | template = file("./templates/ts.json")
12 |
13 | vars = {
14 | region = var.location
15 | law_id = azurerm_log_analytics_workspace.law.workspace_id
16 | law_primkey = azurerm_log_analytics_workspace.law.primary_shared_key
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/analytics/variables.tf:
--------------------------------------------------------------------------------
1 |
2 | variable prefix {}
3 | variable resourceGroup {}
4 | variable location {}
5 | variable region {}
6 | variable securityGroup {
7 | default = "none"
8 | }
9 |
10 | variable subnet {
11 | default = "none"
12 | }
13 |
14 | variable adminUserName {}
15 | variable adminPassword {}
16 |
17 | # TAGS
18 | variable tags {}
19 |
--------------------------------------------------------------------------------
/azure.tf:
--------------------------------------------------------------------------------
1 | # Create a Resource Group for the new Virtual Machines
2 | resource "azurerm_resource_group" "main" {
3 | name = "${var.projectPrefix}_rg"
4 | location = var.location
5 | }
6 |
7 |
8 | # Create Availability Set
9 | resource "azurerm_availability_set" "avset" {
10 | name = "${var.projectPrefix}-avset"
11 | location = azurerm_resource_group.main.location
12 | resource_group_name = azurerm_resource_group.main.name
13 | platform_fault_domain_count = 2
14 | platform_update_domain_count = 2
15 | managed = true
16 | }
17 |
18 | # Create Availability Set 2 only for 3 tier tho
19 | resource "azurerm_availability_set" "avset2" {
20 | count = var.deploymentType == "three_tier" ? 1 : 0
21 | name = "${var.projectPrefix}-avset-2"
22 | location = azurerm_resource_group.main.location
23 | resource_group_name = azurerm_resource_group.main.name
24 | platform_fault_domain_count = 2
25 | platform_update_domain_count = 2
26 | managed = true
27 | }
28 |
29 | # Create Azure LB
30 | resource "azurerm_lb" "lb" {
31 | name = "${var.projectPrefix}-alb"
32 | location = azurerm_resource_group.main.location
33 | resource_group_name = azurerm_resource_group.main.name
34 | sku = "Standard"
35 |
36 | frontend_ip_configuration {
37 | name = "Public-LoadBalancerFrontEnd"
38 | public_ip_address_id = azurerm_public_ip.lbpip.id
39 | }
40 | }
41 |
42 | resource "azurerm_lb_backend_address_pool" "backend_pool" {
43 | name = "IngressBackendPool"
44 | #resource_group_name = azurerm_resource_group.main.name
45 | loadbalancer_id = azurerm_lb.lb.id
46 | }
47 |
48 | resource "azurerm_lb_backend_address_pool" "management_pool" {
49 | name = "EgressManagementPool"
50 | #resource_group_name = azurerm_resource_group.main.name
51 | loadbalancer_id = azurerm_lb.lb.id
52 | }
53 |
54 | resource "azurerm_lb_backend_address_pool" "primary_pool" {
55 | name = "EgressPrimaryPool"
56 | #resource_group_name = azurerm_resource_group.main.name
57 | loadbalancer_id = azurerm_lb.lb.id
58 | }
59 |
60 | resource "azurerm_lb_probe" "https_probe" {
61 | #resource_group_name = azurerm_resource_group.main.name
62 | loadbalancer_id = azurerm_lb.lb.id
63 | name = "443Probe"
64 | protocol = "Tcp"
65 | port = 443
66 | interval_in_seconds = 5
67 | number_of_probes = 2
68 | }
69 |
70 | resource "azurerm_lb_probe" "http_probe" {
71 | #resource_group_name = azurerm_resource_group.main.name
72 | loadbalancer_id = azurerm_lb.lb.id
73 | name = "8080Probe"
74 | protocol = "Tcp"
75 | port = 8080
76 | interval_in_seconds = 5
77 | number_of_probes = 2
78 | }
79 |
80 | resource "azurerm_lb_probe" "ssh_probe" {
81 | #resource_group_name = azurerm_resource_group.main.name
82 | loadbalancer_id = azurerm_lb.lb.id
83 | name = "sshProbe"
84 | protocol = "Tcp"
85 | port = 22
86 | interval_in_seconds = 5
87 | number_of_probes = 2
88 | }
89 |
90 | resource "azurerm_lb_probe" "rdp_probe" {
91 | #resource_group_name = azurerm_resource_group.main.name
92 | loadbalancer_id = azurerm_lb.lb.id
93 | name = "rdpProbe"
94 | protocol = "Tcp"
95 | port = 3389
96 | interval_in_seconds = 5
97 | number_of_probes = 2
98 | }
99 |
100 | resource "azurerm_lb_rule" "https_rule" {
101 | name = "HTTPS_Rule"
102 | #resource_group_name = azurerm_resource_group.main.name
103 | loadbalancer_id = azurerm_lb.lb.id
104 | protocol = "Tcp"
105 | frontend_port = 443
106 | backend_port = 443
107 | frontend_ip_configuration_name = "Public-LoadBalancerFrontEnd"
108 | enable_floating_ip = false
109 | disable_outbound_snat = true
110 | backend_address_pool_ids = [azurerm_lb_backend_address_pool.backend_pool.id]
111 | #backend_address_pool_id = azurerm_lb_backend_address_pool.backend_pool.id
112 | idle_timeout_in_minutes = 5
113 | probe_id = azurerm_lb_probe.https_probe.id
114 | depends_on = [azurerm_lb_probe.https_probe]
115 | }
116 |
117 | resource "azurerm_lb_rule" "http_rule" {
118 | name = "HTTPRule"
119 | #resource_group_name = azurerm_resource_group.main.name
120 | loadbalancer_id = azurerm_lb.lb.id
121 | protocol = "Tcp"
122 | frontend_port = 8080
123 | backend_port = 8080
124 | frontend_ip_configuration_name = "Public-LoadBalancerFrontEnd"
125 | enable_floating_ip = false
126 | disable_outbound_snat = true
127 | backend_address_pool_ids = [azurerm_lb_backend_address_pool.backend_pool.id]
128 | #backend_address_pool_id = azurerm_lb_backend_address_pool.backend_pool.id
129 | idle_timeout_in_minutes = 5
130 | probe_id = azurerm_lb_probe.http_probe.id
131 | depends_on = [azurerm_lb_probe.http_probe]
132 | }
133 |
134 | resource "azurerm_lb_rule" "ssh_rule" {
135 | name = "SSH_Rule"
136 | #resource_group_name = azurerm_resource_group.main.name
137 | loadbalancer_id = azurerm_lb.lb.id
138 | protocol = "Tcp"
139 | frontend_port = 22
140 | backend_port = 22
141 | frontend_ip_configuration_name = "Public-LoadBalancerFrontEnd"
142 | enable_floating_ip = false
143 | disable_outbound_snat = true
144 | backend_address_pool_ids = [azurerm_lb_backend_address_pool.backend_pool.id]
145 | #backend_address_pool_id = azurerm_lb_backend_address_pool.backend_pool.id
146 | idle_timeout_in_minutes = 5
147 | probe_id = azurerm_lb_probe.ssh_probe.id
148 | depends_on = [azurerm_lb_probe.ssh_probe]
149 | }
150 | resource "azurerm_lb_rule" "rdp_rule" {
151 | name = "RDP_Rule"
152 | #resource_group_name = azurerm_resource_group.main.name
153 | loadbalancer_id = azurerm_lb.lb.id
154 | protocol = "Tcp"
155 | frontend_port = 3389
156 | backend_port = 3389
157 | frontend_ip_configuration_name = "Public-LoadBalancerFrontEnd"
158 | enable_floating_ip = false
159 | disable_outbound_snat = true
160 | backend_address_pool_ids = [azurerm_lb_backend_address_pool.backend_pool.id]
161 | #backend_address_pool_id = azurerm_lb_backend_address_pool.backend_pool.id
162 | idle_timeout_in_minutes = 5
163 | probe_id = azurerm_lb_probe.rdp_probe.id
164 | depends_on = [azurerm_lb_probe.rdp_probe]
165 | }
166 |
167 | resource "azurerm_lb_outbound_rule" "egress_rule" {
168 | name = "egress_rule"
169 | #resource_group_name = azurerm_resource_group.main.name
170 | loadbalancer_id = azurerm_lb.lb.id
171 | protocol = "All"
172 | backend_address_pool_id = azurerm_lb_backend_address_pool.primary_pool.id
173 | allocated_outbound_ports = "9136"
174 | enable_tcp_reset = true
175 | frontend_ip_configuration {
176 | name = "Public-LoadBalancerFrontEnd"
177 | }
178 | }
179 |
180 | # Create the ILB for South LB and Egress
181 | resource "azurerm_lb" "internalLoadBalancer" {
182 | count = var.deploymentType == "three_tier" ? 1 : 0
183 | name = "${var.projectPrefix}-internal-loadbalancer"
184 | location = var.location
185 | resource_group_name = azurerm_resource_group.main.name
186 | sku = "Standard"
187 |
188 | frontend_ip_configuration {
189 | name = "Internal_LoadBalancerFrontEnd"
190 | subnet_id = azurerm_subnet.internal.id
191 | private_ip_address = var.ilb01ip
192 | private_ip_address_allocation = "Static"
193 | private_ip_address_version = "IPv4"
194 | }
195 |
196 | frontend_ip_configuration {
197 | name = "IDS_LoadBalancerFrontEnd"
198 | subnet_id = azurerm_subnet.inspect_external[0].id
199 | private_ip_address = var.ilb04ip
200 | private_ip_address_allocation = "Static"
201 | private_ip_address_version = "IPv4"
202 | }
203 |
204 | frontend_ip_configuration {
205 | name = "waf_ext_LoadBalancerFrontEnd_Egress"
206 | subnet_id = azurerm_subnet.waf_external[0].id
207 | private_ip_address = var.ilb02ip
208 | private_ip_address_allocation = "Static"
209 | private_ip_address_version = "IPv4"
210 | }
211 |
212 | frontend_ip_configuration {
213 | name = "waf_ext_LoadBalancerFrontEnd_Ingress"
214 | subnet_id = azurerm_subnet.waf_external[0].id
215 | private_ip_address = var.ilb03ip
216 | private_ip_address_allocation = "Static"
217 | private_ip_address_version = "IPv4"
218 | }
219 | }
220 |
221 | # Create the LB Pool for Internal Egress
222 | resource "azurerm_lb_backend_address_pool" "internal_backend_pool" {
223 | count = var.deploymentType == "three_tier" ? 1 : 0
224 | name = "internal_egress_pool"
225 | #resource_group_name = azurerm_resource_group.main.name
226 | loadbalancer_id = azurerm_lb.internalLoadBalancer[0].id
227 | }
228 |
229 | # Create the LB Pool for Inspect Ingress
230 | resource "azurerm_lb_backend_address_pool" "ips_backend_pool" {
231 | count = var.deploymentType == "three_tier" ? 1 : 0
232 | name = "ips_ingress_pool"
233 | #resource_group_name = azurerm_resource_group.main.name
234 | loadbalancer_id = azurerm_lb.internalLoadBalancer[0].id
235 | }
236 |
237 | # Create the LB Pool for WAF Ingress
238 | resource "azurerm_lb_backend_address_pool" "waf_ingress_pool" {
239 | count = var.deploymentType == "three_tier" ? 1 : 0
240 | name = "waf_ingress_pool"
241 | #resource_group_name = azurerm_resource_group.main.name
242 | loadbalancer_id = azurerm_lb.internalLoadBalancer[0].id
243 | }
244 | # Create the LB Pool for WAF Egress
245 | resource "azurerm_lb_backend_address_pool" "waf_egress_pool" {
246 | count = var.deploymentType == "three_tier" ? 1 : 0
247 | name = "waf_egress_pool"
248 | #resource_group_name = azurerm_resource_group.main.name
249 | loadbalancer_id = azurerm_lb.internalLoadBalancer[0].id
250 | }
251 |
252 | resource "azurerm_lb_probe" "internal_Tcp_probe" {
253 | count = var.deploymentType == "three_tier" ? 1 : 0
254 | #resource_group_name = azurerm_resource_group.main.name
255 | loadbalancer_id = azurerm_lb.internalLoadBalancer[0].id
256 | name = "${var.projectPrefix}-internal-Tcp-probe"
257 | protocol = "Tcp"
258 | port = 34568
259 | interval_in_seconds = 5
260 | number_of_probes = 2
261 | }
262 |
263 | resource "azurerm_lb_probe" "waf_probe" {
264 | count = var.deploymentType == "three_tier" ? 1 : 0
265 | #resource_group_name = azurerm_resource_group.main.name
266 | loadbalancer_id = azurerm_lb.internalLoadBalancer[0].id
267 | name = "${var.projectPrefix}-waf-Tcp-probe"
268 | protocol = "Tcp"
269 | port = 8080
270 | interval_in_seconds = 5
271 | number_of_probes = 2
272 | }
273 |
274 | resource "azurerm_lb_rule" "internal_all_rule" {
275 | count = var.deploymentType == "three_tier" ? 1 : 0
276 | name = "internal-all-protocol-ilb-egress"
277 | #resource_group_name = azurerm_resource_group.main.name
278 | loadbalancer_id = azurerm_lb.internalLoadBalancer[0].id
279 | protocol = "All"
280 | frontend_port = 0
281 | backend_port = 0
282 | load_distribution = "SourceIPProtocol"
283 | frontend_ip_configuration_name = "Internal_LoadBalancerFrontEnd"
284 | enable_floating_ip = true
285 | backend_address_pool_ids = [azurerm_lb_backend_address_pool.internal_backend_pool[0].id]
286 | #backend_address_pool_id = azurerm_lb_backend_address_pool.internal_backend_pool[0].id
287 | idle_timeout_in_minutes = 5
288 | probe_id = azurerm_lb_probe.internal_Tcp_probe[0].id
289 | depends_on = [azurerm_lb_probe.internal_Tcp_probe[0]]
290 | }
291 |
292 | resource "azurerm_lb_rule" "waf_ext_all_rule" {
293 | count = var.deploymentType == "three_tier" ? 1 : 0
294 | name = "waf-ext-all-protocol-ilb-egress"
295 | #resource_group_name = azurerm_resource_group.main.name
296 | loadbalancer_id = azurerm_lb.internalLoadBalancer[0].id
297 | protocol = "All"
298 | frontend_port = 0
299 | backend_port = 0
300 | load_distribution = "SourceIPProtocol"
301 | frontend_ip_configuration_name = "waf_ext_LoadBalancerFrontEnd_Egress"
302 | enable_floating_ip = true
303 | backend_address_pool_ids = [azurerm_lb_backend_address_pool.waf_egress_pool[0].id]
304 | #backend_address_pool_id = azurerm_lb_backend_address_pool.waf_egress_pool[0].id
305 | idle_timeout_in_minutes = 5
306 | probe_id = azurerm_lb_probe.internal_Tcp_probe[0].id
307 | depends_on = [azurerm_lb_probe.internal_Tcp_probe[0]]
308 | }
309 |
310 | resource "azurerm_lb_rule" "waf_ext_ingress_rule" {
311 | count = var.deploymentType == "three_tier" ? 1 : 0
312 | name = "waf-ext-all-protocol-ilb-ingress"
313 | #resource_group_name = azurerm_resource_group.main.name
314 | loadbalancer_id = azurerm_lb.internalLoadBalancer[0].id
315 | protocol = "All"
316 | frontend_port = 0
317 | backend_port = 0
318 | load_distribution = "SourceIPProtocol"
319 | frontend_ip_configuration_name = "waf_ext_LoadBalancerFrontEnd_Ingress"
320 | enable_floating_ip = true
321 | backend_address_pool_ids = [azurerm_lb_backend_address_pool.waf_ingress_pool[0].id]
322 | #backend_address_pool_id = azurerm_lb_backend_address_pool.waf_ingress_pool[0].id
323 | idle_timeout_in_minutes = 5
324 | probe_id = azurerm_lb_probe.waf_probe[0].id
325 | depends_on = [azurerm_lb_probe.waf_probe[0]]
326 | }
327 |
--------------------------------------------------------------------------------
/cleanup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo "destroying demo"
3 | read -r -p "Are you sure? [y/N] " response
4 | if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]
5 | then
6 | terraform destroy --auto-approve
7 | while [ $? -ne 0 ]; do
8 | terraform destroy --auto-approve
9 | done
10 | else
11 | echo "canceling"
12 | fi
13 |
--------------------------------------------------------------------------------
/demo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 | start=$SECONDS
4 | terraform init
5 | terraform fmt
6 | terraform validate
7 | terraform plan
8 | # apply
9 | read -p "Press enter to continue"
10 | terraform apply --auto-approve
11 | duration=$(( SECONDS - start ))
12 | echo "Operation took $duration seconds"
13 |
--------------------------------------------------------------------------------
/demo_app/app.tf:
--------------------------------------------------------------------------------
1 | # network interface for app vm
2 | resource azurerm_network_interface app01-nic {
3 | name = "${var.prefix}-app01-nic"
4 | location = var.resourceGroup.location
5 | resource_group_name = var.resourceGroup.name
6 |
7 | ip_configuration {
8 | name = "primary"
9 | subnet_id = var.subnet.id
10 | private_ip_address_allocation = "Static"
11 | private_ip_address = var.app01ip
12 | primary = true
13 | }
14 |
15 | tags = var.tags
16 | }
17 |
18 | resource azurerm_network_interface_security_group_association app-nsg {
19 | network_interface_id = azurerm_network_interface.app01-nic.id
20 | network_security_group_id = var.securityGroup.id
21 | }
22 |
23 | # app01-VM
24 | resource azurerm_virtual_machine app01-vm {
25 | count = 1
26 | name = "${var.prefix}-app01-vm"
27 | location = var.resourceGroup.location
28 | resource_group_name = var.resourceGroup.name
29 |
30 | network_interface_ids = [azurerm_network_interface.app01-nic.id]
31 | vm_size = var.instanceType
32 |
33 | storage_os_disk {
34 | name = "${var.prefix}-appOsDisk"
35 | caching = "ReadWrite"
36 | create_option = "FromImage"
37 | managed_disk_type = "Premium_LRS"
38 | }
39 |
40 | storage_image_reference {
41 | publisher = "Canonical"
42 | offer = "UbuntuServer"
43 | sku = "16.04.0-LTS"
44 | version = "latest"
45 | }
46 |
47 | os_profile {
48 | computer_name = "app01"
49 | admin_username = var.adminUserName
50 | admin_password = var.adminPassword
51 | custom_data = <<-EOF
52 | #!/bin/bash
53 | apt-get update -y;
54 | apt-get install -y docker.io;
55 | # demo app
56 | docker run -d -p 443:443 -p 80:80 --restart unless-stopped -e F5DEMO_APP=website -e F5DEMO_NODENAME='F5 Azure' -e F5DEMO_COLOR=ffd734 -e F5DEMO_NODENAME_SSL='F5 Azure (SSL)' -e F5DEMO_COLOR_SSL=a0bf37 chen23/f5-demo-app:ssl;
57 | # juice shop
58 | docker run -d --restart always -p 3000:3000 bkimminich/juice-shop
59 | # rsyslogd with PimpMyLogs
60 | docker run -d -e SYSLOG_USERNAME=${var.adminUserName} -e SYSLOG_PASSWORD=${var.adminPassword} -p 8080:80 -p 514:514/udp pbertera/syslogserver
61 | EOF
62 | }
63 |
64 | os_profile_linux_config {
65 | disable_password_authentication = false
66 | }
67 |
68 | tags = var.tags
69 | }
70 |
--------------------------------------------------------------------------------
/demo_app/variables.tf:
--------------------------------------------------------------------------------
1 |
2 | variable prefix {}
3 | variable resourceGroup {}
4 | variable location {}
5 | variable region {}
6 | variable securityGroup {
7 | default = "none"
8 | }
9 |
10 | variable subnet {}
11 |
12 | variable app01ip {}
13 | variable adminUserName {}
14 | variable adminPassword {}
15 |
16 | variable instanceType {}
17 |
18 | # TAGS
19 | variable tags {}
20 |
21 | variable timezone {}
22 |
--------------------------------------------------------------------------------
/dockerfile:
--------------------------------------------------------------------------------
1 | # Setup build arguments with default versions
2 | ARG TERRAFORM_VERSION=0.14.5
3 | ARG AZURE_CLI_VERSION=latest
4 |
5 | # Download Terraform binary
6 | FROM debian:stretch-20190506-slim as terraform
7 | ENV DEBIAN_FRONTEND="noninteractive"
8 | ARG TERRAFORM_VERSION
9 | RUN apt-get update
10 | RUN apt-get install -y apt-utils
11 | RUN apt-get install -y curl
12 | RUN apt-get install -y unzip
13 | RUN apt-get install -y gnupg
14 | RUN curl -Os https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_SHA256SUMS
15 | RUN curl -Os https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip
16 | RUN curl -Os https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_SHA256SUMS.sig
17 | COPY hashicorp.asc hashicorp.asc
18 | RUN gpg --import hashicorp.asc
19 | RUN gpg --verify terraform_${TERRAFORM_VERSION}_SHA256SUMS.sig terraform_${TERRAFORM_VERSION}_SHA256SUMS
20 | RUN grep terraform_${TERRAFORM_VERSION}_linux_amd64.zip terraform_${TERRAFORM_VERSION}_SHA256SUMS | sha256sum -c -
21 | RUN unzip -j terraform_${TERRAFORM_VERSION}_linux_amd64.zip
22 |
23 | # Build final image
24 | FROM debian:stretch-20190506-slim
25 | RUN apt-get update \
26 | && apt-get install -y --no-install-recommends \
27 | ca-certificates \
28 | python3=3.5.3-1 \
29 | curl \
30 | jq \
31 | && apt-get clean \
32 | && rm -rf /var/lib/apt/lists/* \
33 | && ln -s /usr/bin/python3 /usr/bin/python \
34 | && curl -sL https://aka.ms/InstallAzureCLIDeb | bash
35 | COPY --from=terraform /terraform /usr/local/bin/terraform
36 | WORKDIR /workspace
37 | CMD ["bash"]
38 |
--------------------------------------------------------------------------------
/firewall.tf:
--------------------------------------------------------------------------------
1 | # Create a Network Security Group with some rules
2 | resource azurerm_network_security_group main {
3 | name = "${var.projectPrefix}-nsg"
4 | location = azurerm_resource_group.main.location
5 | resource_group_name = azurerm_resource_group.main.name
6 |
7 | security_rule {
8 | name = "allow_SSH"
9 | description = "Allow SSH access"
10 | priority = 100
11 | direction = "Inbound"
12 | access = "Allow"
13 | protocol = "Tcp"
14 | source_port_range = "*"
15 | destination_port_range = "22"
16 | source_address_prefix = "*"
17 | destination_address_prefix = "*"
18 | }
19 |
20 | security_rule {
21 | name = "allow_HTTP"
22 | description = "Allow HTTP access"
23 | priority = 110
24 | direction = "Inbound"
25 | access = "Allow"
26 | protocol = "Tcp"
27 | source_port_range = "*"
28 | destination_port_range = "8080"
29 | source_address_prefix = "*"
30 | destination_address_prefix = "*"
31 | }
32 |
33 | security_rule {
34 | name = "allow_HTTPS"
35 | description = "Allow HTTPS access"
36 | priority = 120
37 | direction = "Inbound"
38 | access = "Allow"
39 | protocol = "Tcp"
40 | source_port_range = "*"
41 | destination_port_range = "443"
42 | source_address_prefix = "*"
43 | destination_address_prefix = "*"
44 | }
45 |
46 | security_rule {
47 | name = "allow_RDP"
48 | description = "Allow RDP access"
49 | priority = 130
50 | direction = "Inbound"
51 | access = "Allow"
52 | protocol = "Tcp"
53 | source_port_range = "*"
54 | destination_port_range = "3389"
55 | source_address_prefix = "*"
56 | destination_address_prefix = "*"
57 | }
58 |
59 | security_rule {
60 | name = "allow_APP_HTTPS"
61 | description = "Allow HTTPS access"
62 | priority = 140
63 | direction = "Inbound"
64 | access = "Allow"
65 | protocol = "Tcp"
66 | source_port_range = "*"
67 | destination_port_range = "8443"
68 | source_address_prefix = "*"
69 | destination_address_prefix = "*"
70 | }
71 |
72 | tags = var.tags
73 | }
74 |
--------------------------------------------------------------------------------
/gitleaks.sh:
--------------------------------------------------------------------------------
1 | docker run --rm --name=gitleaks -v $(pwd):/code/ zricethezav/gitleaks -v --repo-path=/code/
2 |
--------------------------------------------------------------------------------
/hashicorp.asc:
--------------------------------------------------------------------------------
1 | -----BEGIN PGP PUBLIC KEY BLOCK-----
2 | Version: GnuPG v1
3 |
4 | mQENBFMORM0BCADBRyKO1MhCirazOSVwcfTr1xUxjPvfxD3hjUwHtjsOy/bT6p9f
5 | W2mRPfwnq2JB5As+paL3UGDsSRDnK9KAxQb0NNF4+eVhr/EJ18s3wwXXDMjpIifq
6 | fIm2WyH3G+aRLTLPIpscUNKDyxFOUbsmgXAmJ46Re1fn8uKxKRHbfa39aeuEYWFA
7 | 3drdL1WoUngvED7f+RnKBK2G6ZEpO+LDovQk19xGjiMTtPJrjMjZJ3QXqPvx5wca
8 | KSZLr4lMTuoTI/ZXyZy5bD4tShiZz6KcyX27cD70q2iRcEZ0poLKHyEIDAi3TM5k
9 | SwbbWBFd5RNPOR0qzrb/0p9ksKK48IIfH2FvABEBAAG0K0hhc2hpQ29ycCBTZWN1
10 | cml0eSA8c2VjdXJpdHlAaGFzaGljb3JwLmNvbT6JATgEEwECACIFAlMORM0CGwMG
11 | CwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEFGFLYc0j/xMyWIIAIPhcVqiQ59n
12 | Jc07gjUX0SWBJAxEG1lKxfzS4Xp+57h2xxTpdotGQ1fZwsihaIqow337YHQI3q0i
13 | SqV534Ms+j/tU7X8sq11xFJIeEVG8PASRCwmryUwghFKPlHETQ8jJ+Y8+1asRydi
14 | psP3B/5Mjhqv/uOK+Vy3zAyIpyDOMtIpOVfjSpCplVRdtSTFWBu9Em7j5I2HMn1w
15 | sJZnJgXKpybpibGiiTtmnFLOwibmprSu04rsnP4ncdC2XRD4wIjoyA+4PKgX3sCO
16 | klEzKryWYBmLkJOMDdo52LttP3279s7XrkLEE7ia0fXa2c12EQ0f0DQ1tGUvyVEW
17 | WmJVccm5bq25AQ0EUw5EzQEIANaPUY04/g7AmYkOMjaCZ6iTp9hB5Rsj/4ee/ln9
18 | wArzRO9+3eejLWh53FoN1rO+su7tiXJA5YAzVy6tuolrqjM8DBztPxdLBbEi4V+j
19 | 2tK0dATdBQBHEh3OJApO2UBtcjaZBT31zrG9K55D+CrcgIVEHAKY8Cb4kLBkb5wM
20 | skn+DrASKU0BNIV1qRsxfiUdQHZfSqtp004nrql1lbFMLFEuiY8FZrkkQ9qduixo
21 | mTT6f34/oiY+Jam3zCK7RDN/OjuWheIPGj/Qbx9JuNiwgX6yRj7OE1tjUx6d8g9y
22 | 0H1fmLJbb3WZZbuuGFnK6qrE3bGeY8+AWaJAZ37wpWh1p0cAEQEAAYkBHwQYAQIA
23 | CQUCUw5EzQIbDAAKCRBRhS2HNI/8TJntCAClU7TOO/X053eKF1jqNW4A1qpxctVc
24 | z8eTcY8Om5O4f6a/rfxfNFKn9Qyja/OG1xWNobETy7MiMXYjaa8uUx5iFy6kMVaP
25 | 0BXJ59NLZjMARGw6lVTYDTIvzqqqwLxgliSDfSnqUhubGwvykANPO+93BBx89MRG
26 | unNoYGXtPlhNFrAsB1VR8+EyKLv2HQtGCPSFBhrjuzH3gxGibNDDdFQLxxuJWepJ
27 | EK1UbTS4ms0NgZ2Uknqn1WRU1Ki7rE4sTy68iZtWpKQXZEJa0IGnuI2sSINGcXCJ
28 | oEIgXTMyCILo34Fa/C6VCm2WBgz9zZO8/rHIiQm1J5zqz0DrDwKBUM9C
29 | =LYpS
30 | -----END PGP PUBLIC KEY BLOCK-----
31 |
--------------------------------------------------------------------------------
/jumpboxes/DisableInternetExplorer-ESC.ps1:
--------------------------------------------------------------------------------
1 | function Disable-InternetExplorerESC {
2 | $AdminKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
3 | $UserKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
4 | Set-ItemProperty -Path $AdminKey -Name "IsInstalled" -Value 0
5 | Set-ItemProperty -Path $UserKey -Name "IsInstalled" -Value 0
6 | Stop-Process -Name Explorer
7 | }
8 | Disable-InternetExplorerESC
9 |
--------------------------------------------------------------------------------
/jumpboxes/linux.tf:
--------------------------------------------------------------------------------
1 | # linuxJump
2 | resource azurerm_network_interface linuxJump-ext-nic {
3 | name = "${var.prefix}-linuxJump-ext-nic"
4 | location = var.resourceGroup.location
5 | resource_group_name = var.resourceGroup.name
6 | #network_security_group_id = var.securityGroup.id
7 |
8 | ip_configuration {
9 | name = "primary"
10 | subnet_id = var.subnet.id
11 | private_ip_address_allocation = "Static"
12 | private_ip_address = var.linuxjumpip
13 | primary = true
14 | }
15 |
16 | tags = var.tags
17 | }
18 |
19 | resource "azurerm_network_interface_security_group_association" "linuxJump-ext-nsg" {
20 | network_interface_id = azurerm_network_interface.linuxJump-ext-nic.id
21 | network_security_group_id = var.securityGroup.id
22 | }
23 |
24 | resource azurerm_virtual_machine linuxJump {
25 | name = "${var.prefix}-linuxJump"
26 | location = var.resourceGroup.location
27 | resource_group_name = var.resourceGroup.name
28 |
29 | network_interface_ids = [azurerm_network_interface.linuxJump-ext-nic.id]
30 | vm_size = var.instanceType
31 |
32 | storage_os_disk {
33 | name = "${var.prefix}-linuxJumpOsDisk"
34 | caching = "ReadWrite"
35 | create_option = "FromImage"
36 | managed_disk_type = "Premium_LRS"
37 | }
38 |
39 | storage_image_reference {
40 | publisher = "Canonical"
41 | offer = "UbuntuServer"
42 | sku = "16.04.0-LTS"
43 | version = "latest"
44 | }
45 |
46 | os_profile {
47 | computer_name = "linuxJump"
48 | admin_username = var.adminUserName
49 | admin_password = var.adminPassword
50 | custom_data = <<-EOF
51 | #!/bin/bash
52 | apt-get update -y;
53 | apt-get install -y docker.io;
54 | # demo app
55 | docker run -d -p 80:80 --net=host --restart unless-stopped -e F5DEMO_APP=website -e F5DEMO_NODENAME='F5 Azure' -e F5DEMO_COLOR=ffd734 -e F5DEMO_NODENAME_SSL='F5 Azure (SSL)' -e F5DEMO_COLOR_SSL=a0bf37 chen23/f5-demo-app:ssl;
56 | # juice shop
57 | docker run -d --restart always -p 3000:3000 bkimminich/juice-shop
58 | EOF
59 | }
60 |
61 | os_profile_linux_config {
62 | disable_password_authentication = false
63 | }
64 |
65 | tags = var.tags
66 | }
67 |
--------------------------------------------------------------------------------
/jumpboxes/variables.tf:
--------------------------------------------------------------------------------
1 | # Instance Type
2 |
3 | variable instanceType {}
4 |
5 | # winjump
6 | variable winjumpip {}
7 |
8 | # linuxjump
9 | variable linuxjumpip {}
10 |
11 | variable timezone { default = "UTC" }
12 |
13 | # cloud
14 | variable location {}
15 | variable region {}
16 | variable prefix {}
17 | variable resourceGroup {}
18 | variable securityGroup { default = "none" }
19 |
20 | # network
21 | variable subnet {}
22 |
23 | # creds
24 | variable adminUserName {}
25 | variable adminPassword {}
26 | variable sshPublicKey {}
27 |
28 | # TAGS
29 | variable tags {}
30 |
--------------------------------------------------------------------------------
/jumpboxes/windows.tf:
--------------------------------------------------------------------------------
1 | resource azurerm_network_interface winjump-ext-nic {
2 | name = "${var.prefix}-winjump-ext-nic"
3 | location = var.resourceGroup.location
4 | resource_group_name = var.resourceGroup.name
5 |
6 | ip_configuration {
7 | name = "primary"
8 | subnet_id = var.subnet.id
9 | private_ip_address_allocation = "Static"
10 | private_ip_address = var.winjumpip
11 | primary = true
12 | }
13 |
14 | tags = var.tags
15 | }
16 |
17 | resource "azurerm_network_interface_security_group_association" "winjump-ext-nsg" {
18 | network_interface_id = azurerm_network_interface.winjump-ext-nic.id
19 | network_security_group_id = var.securityGroup.id
20 | }
21 |
22 | resource azurerm_virtual_machine winJump {
23 | name = "${var.prefix}-winJump"
24 | resource_group_name = var.resourceGroup.name
25 | location = var.resourceGroup.location
26 | vm_size = var.instanceType
27 | network_interface_ids = [azurerm_network_interface.winjump-ext-nic.id] #Front-End Network
28 |
29 | os_profile_windows_config {
30 | provision_vm_agent = true
31 | timezone = var.timezone
32 | }
33 |
34 | storage_image_reference {
35 | publisher = "MicrosoftWindowsServer"
36 | offer = "WindowsServer"
37 | sku = "2016-Datacenter"
38 | version = "latest"
39 | }
40 |
41 | storage_os_disk {
42 | name = "${var.prefix}-winJump-os"
43 | caching = "ReadWrite"
44 | create_option = "FromImage"
45 | os_type = "Windows"
46 | }
47 |
48 | os_profile {
49 | computer_name = "winJump"
50 | admin_username = var.adminUserName
51 | admin_password = var.adminPassword
52 | custom_data = filebase64("./jumpboxes/DisableInternetExplorer-ESC.ps1")
53 | }
54 |
55 | tags = var.tags
56 | }
57 |
58 | resource azurerm_virtual_machine_extension winJump-run-startup-cmd {
59 | name = "${var.prefix}-winJump-run-startup-cmd"
60 | depends_on = [azurerm_virtual_machine.winJump]
61 | virtual_machine_id = azurerm_virtual_machine.winJump.id
62 | publisher = "Microsoft.Compute"
63 | type = "CustomScriptExtension"
64 | type_handler_version = "1.9"
65 | auto_upgrade_minor_version = true
66 |
67 | protected_settings = <> ./startup.b64 && cat ./startup.b64 | base64 -d >> ./startup-temp.sh && sed -e 's/\r$//' ./startup-temp.sh > ./startup-script.sh && chmod +x ./startup-script.sh && rm ./startup.b64 && bash ./startup-script.sh 1"
469 | }
470 | SETTINGS
471 |
472 | tags = var.tags
473 | }
474 |
475 | resource "azurerm_virtual_machine_extension" "f5vm02-run-startup-cmd" {
476 | name = "${var.prefix}-f5vm02-run-startup-cmd"
477 | depends_on = [azurerm_virtual_machine.f5vm01, azurerm_virtual_machine.f5vm02, azurerm_network_interface_backend_address_pool_association.mpool_assc_vm01, azurerm_network_interface_backend_address_pool_association.mpool_assc_vm02]
478 | virtual_machine_id = azurerm_virtual_machine.f5vm02.id
479 | publisher = "Microsoft.Azure.Extensions"
480 | type = "CustomScript"
481 | type_handler_version = "2.0"
482 | auto_upgrade_minor_version = true
483 |
484 | settings = <> ./startup.b64 && cat ./startup.b64 | base64 -d >> ./startup-temp.sh && sed -e 's/\r$//g' ./startup-temp.sh > ./startup-script.sh && chmod +x ./startup-script.sh && rm ./startup.b64 && bash ./startup-script.sh 2"
488 | }
489 | SETTINGS
490 |
491 | tags = var.tags
492 | }
493 |
494 |
495 | # Debug Template Outputs
496 | resource "local_file" "vm01_do_file" {
497 | content = data.template_file.vm01_do_json.rendered
498 | filename = "${path.module}/vm01_do_data.json"
499 | }
500 |
501 | resource "local_file" "vm02_do_file" {
502 | content = data.template_file.vm02_do_json.rendered
503 | filename = "${path.module}/vm02_do_data.json"
504 | }
505 |
506 | resource "local_file" "vm_as3_file" {
507 | content = data.template_file.as3_json.rendered
508 | filename = "${path.module}/vm_as3_data.json"
509 | }
510 |
511 | resource "local_file" "onboard_file" {
512 | content = data.template_file.vm_onboard.rendered
513 | filename = "${path.module}/onboard.sh"
514 | }
515 |
--------------------------------------------------------------------------------
/one_tier/firewall/ilb.tf:
--------------------------------------------------------------------------------
1 | # Create the ILB for South LB and Egress
2 | resource "azurerm_lb" "internalLoadBalancer" {
3 | name = "${var.prefix}-internalloadbalancer"
4 | location = var.location
5 | resource_group_name = var.resourceGroup.name
6 | sku = "Standard"
7 |
8 | frontend_ip_configuration {
9 | name = "internalLoadBalancerFrontEnd"
10 | subnet_id = var.subnetInternal.id
11 | private_ip_address = var.ilb01ip
12 | private_ip_address_allocation = "Static"
13 | private_ip_address_version = "IPv4"
14 | }
15 | }
16 |
17 | # Create the LB Pool for ILB
18 | resource "azurerm_lb_backend_address_pool" "internal_backend_pool" {
19 | name = "InternalBackendPool1"
20 | #resource_group_name = var.resourceGroup.name
21 | loadbalancer_id = azurerm_lb.internalLoadBalancer.id
22 | }
23 |
24 | # attach interfaces to backend pool
25 | resource "azurerm_network_interface_backend_address_pool_association" "int_bpool_assc_vm01" {
26 | network_interface_id = azurerm_network_interface.vm01-int-nic.id
27 | ip_configuration_name = "secondary"
28 | backend_address_pool_id = azurerm_lb_backend_address_pool.internal_backend_pool.id
29 | }
30 |
31 | resource "azurerm_network_interface_backend_address_pool_association" "int_bpool_assc_vm02" {
32 | network_interface_id = azurerm_network_interface.vm02-int-nic.id
33 | ip_configuration_name = "secondary"
34 | backend_address_pool_id = azurerm_lb_backend_address_pool.internal_backend_pool.id
35 | }
36 |
37 | resource "azurerm_lb_probe" "internal_tcp_probe" {
38 | #resource_group_name = var.resourceGroup.name
39 | loadbalancer_id = azurerm_lb.internalLoadBalancer.id
40 | name = "${var.prefix}-internal-tcp-probe"
41 | protocol = "Tcp"
42 | port = 34568
43 | interval_in_seconds = 5
44 | number_of_probes = 2
45 | }
46 |
47 | resource "azurerm_lb_rule" "internal_all_rule" {
48 | name = "all-protocol-ilb"
49 | #resource_group_name = var.resourceGroup.name
50 | loadbalancer_id = azurerm_lb.internalLoadBalancer.id
51 | protocol = "All"
52 | frontend_port = 0
53 | backend_port = 0
54 | load_distribution = "SourceIPProtocol"
55 | frontend_ip_configuration_name = "internalLoadBalancerFrontEnd"
56 | enable_floating_ip = true
57 | backend_address_pool_ids = [azurerm_lb_backend_address_pool.internal_backend_pool.id]
58 | #backend_address_pool_id = azurerm_lb_backend_address_pool.internal_backend_pool.id
59 | idle_timeout_in_minutes = 5
60 | probe_id = azurerm_lb_probe.internal_tcp_probe.id
61 | depends_on = [azurerm_lb_probe.internal_tcp_probe]
62 | }
63 |
--------------------------------------------------------------------------------
/one_tier/firewall/outputs.tf:
--------------------------------------------------------------------------------
1 | # data azurerm_public_ip f5vmpip01 {
2 | # name = azurerm_public_ip.f5vmpip01.name
3 | # resource_group_name = var.resourceGroup.name
4 | # depends_on = [azurerm_public_ip.f5vmpip01, azurerm_virtual_machine.f5vm01]
5 | # }
6 | # data azurerm_public_ip f5vmpip02 {
7 | # name = azurerm_public_ip.f5vmpip02.name
8 | # resource_group_name = var.resourceGroup.name
9 | # depends_on = [azurerm_public_ip.f5vmpip02, azurerm_virtual_machine.f5vm02]
10 | # }
11 |
12 |
13 | output f5vm01_id { value = azurerm_virtual_machine.f5vm01.id }
14 | output f5vm01_mgmt_private_ip { value = azurerm_network_interface.vm01-mgmt-nic.private_ip_address }
15 | #output f5vm01_mgmt_public_ip { value = data.azurerm_public_ip.f5vmpip01.ip_address }
16 | output f5vm01_ext_private_ip { value = azurerm_network_interface.vm01-ext-nic.private_ip_address }
17 |
18 | output f5vm02_id { value = azurerm_virtual_machine.f5vm02.id }
19 | output f5vm02_mgmt_private_ip { value = azurerm_network_interface.vm02-mgmt-nic.private_ip_address }
20 | #output f5vm02_mgmt_public_ip { value = data.azurerm_public_ip.f5vmpip02.ip_address }
21 | output f5vm02_ext_private_ip { value = azurerm_network_interface.vm02-ext-nic.private_ip_address }
22 |
--------------------------------------------------------------------------------
/one_tier/firewall/variables.tf:
--------------------------------------------------------------------------------
1 | variable resourceGroup {}
2 | # admin credentials
3 | variable adminUserName {}
4 | variable adminPassword {}
5 | variable sshPublicKey {}
6 | # cloud info
7 | variable location {}
8 | variable region {}
9 | variable securityGroup {
10 | default = "none"
11 | }
12 | variable availabilitySet {}
13 | variable availabilitySet2 {}
14 |
15 | variable subnets {}
16 |
17 | variable prefix {}
18 | # bigip network
19 | variable subnetMgmt {}
20 | variable subnetExternal {}
21 | variable subnetInternal {}
22 | variable backendPool {}
23 | variable managementPool {}
24 | variable primaryPool {}
25 |
26 | variable app01ip {}
27 |
28 | variable ilb01ip {}
29 |
30 | variable f5_mgmt {}
31 | variable f5_t1_ext {}
32 | variable f5_t1_int {}
33 |
34 | # winjump
35 | variable winjumpip {}
36 |
37 | # linuxjump
38 | variable linuxjumpip {}
39 |
40 | # device
41 | variable instanceType {}
42 |
43 |
44 | # BIGIP Image
45 | variable image_name {}
46 | variable product {}
47 | variable bigip_version {}
48 |
49 | variable cidr {}
50 |
51 | # BIGIP Setup
52 | variable licenses {
53 | type = map(string)
54 | default = {
55 | "license1" = ""
56 | "license2" = ""
57 | "license3" = ""
58 | "license4" = ""
59 | }
60 | }
61 | variable hosts {}
62 | variable dns_server {}
63 | variable ntp_server {}
64 | variable timezone {}
65 | variable onboard_log { default = "/var/log/startup-script.log" }
66 | variable asm_policy {}
67 |
68 | # TAGS
69 | variable tags {}
70 |
--------------------------------------------------------------------------------
/outputs.tf:
--------------------------------------------------------------------------------
1 | ## OUTPUTS ###
2 |
3 | # output sg_id {
4 | # value = azurerm_network_security_group.main.id
5 | # description = "Network Security Group ID"
6 | # }
7 | # output sg_name {
8 | # value = azurerm_network_security_group.main.name
9 | # description = "Network Security Group Name"
10 | # }
11 |
12 | output DemoApplication_443 {
13 | value = "https://${azurerm_public_ip.lbpip.ip_address}"
14 | description = "Public IP for applications. Https for example app, RDP for Windows Jumpbox, SSH for Linux Jumpbox"
15 | }
16 | output rSyslogdHttp_8080 {
17 | value = "http://${azurerm_public_ip.lbpip.ip_address}:8080"
18 | description = "Public IP for applications. Https for example app, RDP for Windows Jumpbox, SSH for Linux Jumpbox"
19 | }
20 |
21 | locals {
22 | one_tier = var.deploymentType == "one_tier" ? try({
23 | #f5vm01_id = try(module.firewall_one[0].f5vm01_id, "none")
24 | f5vm01_mgmt_private_ip = try(module.firewall_one[0].f5vm01_mgmt_private_ip, "none")
25 | f5vm01_mgmt_public_ip = "https://${try(module.firewall_one[0].f5vm01_mgmt_public_ip, "none")}"
26 | f5vm01_ext_private_ip = try(module.firewall_one[0].f5vm01_ext_private_ip, "none")
27 | #
28 | #f5vm02_id = try(module.firewall_one[0].f5vm02_id, "none")
29 | f5vm02_mgmt_private_ip = try(module.firewall_one[0].f5vm02_mgmt_private_ip, "none")
30 | f5vm02_mgmt_public_ip = "https://${try(module.firewall_one[0].f5vm02_mgmt_public_ip, "none")}"
31 | f5vm02_ext_private_ip = try(module.firewall_one[0].f5vm02_ext_private_ip, "none")
32 | }) : { none = "none" }
33 | three_tier = var.deploymentType == "three_tier" ? try(
34 | {
35 | #f5vm01_id = try(module.firewall_three[0].f5vm01_id, "none")
36 | f5vm01_mgmt_private_ip = try(module.firewall_three[0].f5vm01_mgmt_private_ip, "none")
37 | f5vm01_mgmt_public_ip = "https://${try(module.firewall_three[0].f5vm01_mgmt_public_ip, "none")}"
38 | f5vm01_ext_private_ip = try(module.waf_three[0].f5vm01_ext_private_ip, "none")
39 | #
40 | #f5vm02_id = try(module.firewall_three[0].f5vm02_id, "none")
41 | f5vm02_mgmt_private_ip = try(module.firewall_three[0].f5vm02_mgmt_private_ip, "none")
42 | f5vm02_mgmt_public_ip = "https://${try(module.firewall_three[0].f5vm02_mgmt_public_ip, "none")}"
43 | f5vm02_ext_private_ip = try(module.waf_three[0].f5vm02_ext_private_ip, "none")
44 | #
45 | #f5vm03_id = try(module.waf_three[0].f5vm03_id, "none")
46 | f5vm03_mgmt_private_ip = try(module.waf_three[0].f5vm03_mgmt_private_ip, "none")
47 | f5vm03_mgmt_public_ip = "https://${try(module.waf_three[0].f5vm03_mgmt_public_ip, "none")}"
48 | f5vm03_ext_private_ip = try(module.waf_three[0].f5vm03_ext_private_ip, "none")
49 | #
50 | #f5vm04_id = try(module.waf_three[0].f5vm04_id, "none")
51 | f5vm04_mgmt_private_ip = try(module.waf_three[0].f5vm04_mgmt_private_ip, "none")
52 | f5vm04_mgmt_public_ip = "https://${try(module.waf_three[0].f5vm04_mgmt_public_ip, "none")}"
53 | f5vm04_ext_private_ip = try(module.waf_three[0].f5vm04_ext_private_ip, "none")
54 |
55 | #"${try(odule.waf_three[0].f5vm04_mgmt_public_ip , "none")}"
56 | }) : { none = "none" }
57 | }
58 |
59 | # single tier
60 | output tier_one {
61 | value = local.one_tier
62 | description = "One Tier Outputs: VM IDs, VM Mgmt IPs, VM External Private IPs"
63 | }
64 | # three tier
65 | output tier_three {
66 | value = local.three_tier
67 | description = "Three Tier Outputs: VM IDs, VM Mgmt IPs, VM External Private IPs"
68 | }
69 |
--------------------------------------------------------------------------------
/prepare/setupAzureGovVars_local.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #Need to check OS / Platform
4 | osName=`uname -s`
5 | case $osName in
6 | Linux*) export machine="Linux" ;;
7 | Darwin*) export machine="Mac" ;;
8 | *) export machine="UNKNOWN:$osName" ;;
9 | esac
10 |
11 | echo $machine
12 |
13 | if [[ "$machine" == "Mac" ]]; then
14 | echo "OSX Detected, need to Install / Update Brew and jq..."
15 | #Need to update brew and make sure jq is installed to process json
16 | echo "updating & upgrading brew..."
17 | brew update || brew update
18 | brew upgrade
19 |
20 | if brew ls --versions jq > /dev/null; then
21 | # The package is installed
22 | echo "jq installed proceeding..."
23 | else
24 | echo "installing jq..."
25 | brew install jq
26 | fi
27 | elif [[ "$machine" == "Linux" ]]; then
28 | if [ -f /etc/redhat-release ]; then
29 | yum -y update
30 | yum -y install jq
31 | fi
32 | if [ -f /etc/lsb-release ]; then
33 | apt-get --assume-yes update
34 | apt-get --assume-yes install jq
35 | fi
36 | fi
37 |
38 | #Map Subscription
39 | export ARM_SUBSCRIPTION_ID=`az account show | jq -r '.id'`
40 |
41 | #Create ServicePrincipal for ClientID and Secret
42 | spn=`az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/$ARM_SUBSCRIPTION_ID" --name http://sccaServicePrincipalName`
43 |
44 | echo "Setting environment variables for Terraform"
45 | export ARM_CLIENT_ID=`echo $spn | jq -r '.appId'`
46 | echo $spn | jq -r '.appId'
47 | export ARM_CLIENT_SECRET=`echo $spn | jq -r '.password'`
48 | echo $spn | jq -r '.password'
49 | export ARM_TENANT_ID=`az account show | jq -r '.tenantId'`
50 | az account show | jq -r '.tenantId'
51 |
52 | # Not needed for public, required for usgovernment, german, china
53 | #export ARM_ENVIRONMENT=`az account show | jq -r '.environmentName'`
54 | export ARM_ENVIRONMENT="usgovernment"
55 |
56 | # Accept terms for programatic deployment of images
57 | az vm image terms accept --offer f5-big-ip-byol --publisher f5-networks --plan f5-big-ip-byol
58 | az vm image terms accept --offer f5-big-ip-best --publisher f5-networks --plan f5-big-ip-best
59 |
--------------------------------------------------------------------------------
/prepare/setupAzureGovVars_vault.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Change these variables according to your needs
4 | RESOURCE_GROUP_NAME=tfstate
5 | STORAGE_ACCOUNT_NAME=tfstate$RANDOM
6 | CONTAINER_NAME=tfstate
7 | VAULT_NAME=sccaKeyVault$RANDOM
8 | SECRET_NAME=sccaSecret
9 |
10 | #Map Subscription
11 | export ARM_SUBSCRIPTION_ID=`az account show | jq -r '.id'`
12 |
13 | #Create ServicePrincipal for ClientID and Secret
14 | spn=`az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/$ARM_SUBSCRIPTION_ID" --name http://sccaServicePrincipalName`
15 |
16 | # Create resource group
17 | az group create --name $RESOURCE_GROUP_NAME --location usgovvirginia
18 |
19 | # Create storage account
20 | az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --sku Standard_LRS --encryption-services blob
21 |
22 | # Get storage account key
23 | ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query [0].value -o tsv)
24 |
25 | # Create blob container
26 | az storage container create --name $CONTAINER_NAME --account-name $STORAGE_ACCOUNT_NAME --account-key $ACCOUNT_KEY
27 |
28 | # Create Azure KeyVault
29 | az keyvault create -g $RESOURCE_GROUP_NAME --name $VAULT_NAME
30 |
31 | # Set Azure KeyVault Secret value to storage account key
32 | az keyvault secret set --vault-name $VAULT_NAME --name $SECRET_NAME --value $ACCOUNT_KEY
33 |
34 | echo "Setting environment variables for Terraform"
35 | export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID
36 | export ARM_CLIENT_ID=`echo $spn | jq -r '.appId'`
37 | export ARM_CLIENT_SECRET=`echo $spn | jq -r '.password'`
38 | export ARM_TENANT_ID=`az account show | jq -r '.tenantId'`
39 | export ARM_ACCESS_KEY=$(az keyvault secret show --name $SECRET_NAME --vault-name $VAULT_NAME --query value -o tsv)
40 |
41 | # Not needed for public, required for usgovernment, german, china
42 | #export ARM_ENVIRONMENT=`az account show | jq -r '.environmentName'`
43 | export ARM_ENVIRONMENT="usgovernment"
44 |
--------------------------------------------------------------------------------
/prepare/setupAzureVars.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #Need to check OS / Platform
4 | osName=`uname -s`
5 | case $osName in
6 | Linux*) export machine=Linux;;
7 | Darwin*) export machine=Mac;;
8 | *) export machine="UNKNOWN:$osName"
9 | esac
10 |
11 | if [ $machine == "Mac" ]; then
12 | echo "OSX Detected, need to Install / Update Brew and jq..."
13 | #Need to update brew and make sure jq is installed to process json
14 | echo "updating & upgrading brew..."
15 | brew update || brew update
16 | brew upgrade
17 |
18 | if brew ls --versions jq > /dev/null; then
19 | # The package is installed
20 | echo "jq installed proceeding..."
21 | else
22 | echo "installing jq..."
23 | brew install jq
24 | fi
25 | elif [ $machine == "Linux" ]; then
26 | if [ -f /etc/redhat-release ]; then
27 | yum -y update
28 | yum -y install jq
29 | fi
30 | if [ -f /etc/lsb-release ]; then
31 | apt-get --assume-yes update
32 | apt-get --assume-yes install jq
33 | fi
34 | fi
35 |
36 | az cloud set --name AzureUSGovernment
37 |
38 | az login --use-device-code
39 |
40 | #Create ServicePrincipal for ClientID and Secret
41 | spn=`az ad sp create-for-rbac --name scaServicePrincipalName`
42 |
43 | echo "Setting environment variables for Terraform"
44 | export ARM_SUBSCRIPTION_ID=`az account show | jq -r '.id'`
45 | export ARM_CLIENT_ID=`echo $spn | jq -r '.appId'`
46 | export ARM_CLIENT_SECRET=`echo $spn | jq -r '.password'`
47 | export ARM_TENANT_ID=`az account show | jq -r '.tenantId'`
48 |
49 | # Not needed for public, required for usgovernment, german, china
50 | export ARM_ENVIRONMENT=`az account show | jq -r '.environmentName'`
51 |
--------------------------------------------------------------------------------
/providers.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_providers {
3 | azurerm = {
4 | source = "hashicorp/azurerm"
5 | version = "3.46.0"
6 | }
7 | http = {
8 | source = "hashicorp/http"
9 | version = "2.1.0"
10 | }
11 | }
12 | }
13 |
14 | provider "azurerm" {
15 | # Configuration options
16 | features {
17 | resource_group {
18 | prevent_deletion_if_contains_resources = false
19 | }
20 | }
21 | }
22 |
23 |
24 | provider "http" {}
25 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Sphinx<2.0
2 | git+git://github.com/f5devcentral/f5-sphinx-theme@master#egg=f5_sphinx_theme
3 | recommonmark
4 | sphinxcontrib-googleanalytics
5 | sphinxcontrib-addmetahtml
6 | sphinxcontrib-nwdiag
7 | sphinxcontrib-blockdiag
8 |
--------------------------------------------------------------------------------
/templates/ips-cloud-init.yaml:
--------------------------------------------------------------------------------
1 | #cloud-config
2 |
3 | write_files:
4 | - path: /etc/rsyslog.d/10-rsyslog.conf
5 | content: |
6 | *.* @${log_destination}:514
7 | - path: /etc/networkd-dispatcher/routable.d/10-ifup-hooks
8 | content: |
9 | #!/bin/sh
10 | # ifconfig $IFACE 0.0.0.0 up
11 | # ip link set $IFACE promisc on
12 | sudo iptables -I FORWARD -i eth1 -o eth2 -j NFQUEUE --queue-num=4
13 | sudo iptables -I FORWARD -i eth2 -o eth1 -j NFQUEUE --queue-num=4
14 | exit 0
15 | - path: /etc/networkd-dispatcher/routable.d/50-postup-hooks
16 | content: |
17 | #!/bin/sh
18 | if [ $IFACE != "eth0"]
19 | ethtool -K $IFACE gro off lro off
20 | fi
21 | exit 0
22 | - path: /etc/networkd-dispatcher/dormant.d/promisc_bridge
23 | content: |
24 | #!/bin/sh
25 | set -e
26 | if [ $IFACE != "eth0"]
27 | ip link set eth1 up promisc on
28 | ip link set eth2 up promisc on
29 | fi
30 | exit 0
31 | - path: /etc/networkd-dispatcher/off.d/50-ifdown-hooks
32 | content: |
33 | #!/bin/sh
34 | ip link set $IFACE promisc off
35 | ifconfig $IFACE down
36 | exit 0
37 | - path: /lib/systemd/system/snort.service
38 | content: |
39 | [Unit]
40 | Description=Snort NIDS Daemon
41 | After=syslog.target network.target
42 | [Service]
43 | Type=simple
44 | ExecStart=/usr/sbin/snort -D -c /etc/snort/snort.conf -Q
45 | [Install]
46 | WantedBy=multi-user.target
47 |
48 | apt:
49 | primary:
50 | - arches: [default]
51 | search_dns: True
52 | package_upgrade: true
53 | packages:
54 | - build-essential
55 | - bridge-utils
56 | - libpcap-dev
57 | - libpcre3-dev
58 | - libdumbnet-dev
59 | - bison
60 | - flex
61 | - zlib1g-dev
62 | - liblzma-dev
63 | - openssl
64 | - libssl-dev
65 | - ethtool
66 | - autoconf
67 | - libtool
68 | - libtool-bin
69 | - pkg-config
70 | - gcc
71 | - zlib1g-dev
72 | - libluajit-5.1-dev
73 | - libnghttp2-dev
74 | - libdnet
75 | - git
76 | - libcrypt-ssleay-perl
77 | - liblwp-useragent-determined-perl
78 | - libnetfilter-queue-dev
79 |
80 | runcmd:
81 | - sudo chmod +x /etc/networkd-dispatcher/routable.d/10-ifup-hooks
82 | - sudo chmod +x /etc/networkd-dispatcher/routable.d/50-postup-hooks
83 | - sudo chmod +x /etc/networkd-dispatcher/dormant.d/promisc_bridge
84 | - sudo chmod +x /etc/networkd-dispatcher/off.d/50-ifdown-hooks
85 | - sudo echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
86 | - sudo apt autoremove -y
87 | - sudo mkdir -p /etc/snort/rules
88 | - sudo chmod -R 5775 /etc/snort
89 | - sudo mkdir /var/log/snort
90 | - sudo chmod -R 5775 /var/log/snort
91 | - sudo mkdir -p /home/root/snort_src
92 | - cd /home/root/snort_src
93 | - [wget, "https://www.snort.org/downloads/snort/daq-2.0.7.tar.gz"]
94 | - [wget, "https://www.snort.org/downloads/archive/snort/snort-2.9.16.1.tar.gz"]
95 | - [wget, "https://www.snort.org/downloads/community/community-rules.tar.gz"]
96 | - git clone https://github.com/John-Lin/docker-snort.git
97 | - tar -xvzf daq-2.0.7.tar.gz
98 | - tar -xvzf snort-2.9.16.1.tar.gz
99 | - tar -xvzf community-rules.tar.gz
100 | - cd /home/root/snort_src/daq-2.0.7
101 | - autoreconf -f -i
102 | - ./configure
103 | - make
104 | - sudo make install
105 | - cd /home/root/snort_src/snort-2.9.16.1
106 | - autoreconf -f -i
107 | - ./configure --enable-sourcefire
108 | - make
109 | - sudo make install
110 | - sudo ldconfig
111 | - sudo ln -s /usr/local/bin/snort /usr/sbin/snort
112 | - sudo mkdir -p /usr/local/lib/snort_dynamicrules
113 | - sudo cp /home/root/snort_src/snort-2.9.16.1/etc/* /etc/snort/
114 | - sudo touch /etc/snort/rules/white_list.rules /etc/snort/rules/black_list.rules
115 | - sudo cp /home/root/snort_src/docker-snort/snortrules-snapshot-2972/rules/* /etc/snort/rules
116 | - sudo echo "config policy_mode:inline" >> /etc/snort/snort.conf
117 | - sudo sed -i 's/..\/rules/\/etc\/snort\/rules/g' /etc/snort/snort.conf
118 | - "sudo sed -i 's/# config daq: /config daq: nfq/g' /etc/snort/snort.conf"
119 | - "sudo sed -i 's/# config daq_mode: /config daq_mode: inline/g' /etc/snort/snort.conf"
120 | - "sudo sed -i 's/# config daq_var: /config daq_var: queue=4/g' /etc/snort/snort.conf"
121 | - sudo echo 'alert icmp any any -> $HOME_NET any (msg:"ICMP test detected"; GID:1; sid:10000001; rev:001; classtype:icmp-event;)' >> /home/root/local.rules
122 | - sudo rm -rf /etc/snort/rules/local.rules
123 | - sudo cp /home/root/local.rules /etc/snort/rules/local.rules
124 | - sudo sysctl -p
125 | - sudo route add -net ${wafSubnetPrefix} netmask ${internalMask} gw ${wafGateway}
126 | - sudo route add -net ${internalSubnetPrefix} netmask ${wafMask} gw ${internalGateway}
127 | - sudo iptables -I FORWARD -i eth1 -o eth2 -j NFQUEUE --queue-num=4
128 | - sudo iptables -I FORWARD -i eth2 -o eth1 -j NFQUEUE --queue-num=4
129 | - sudo systemctl enable snort
130 | - sudo systemctl start snort
131 | #- sudo snort -D -c /etc/snort/snort.conf -Q
132 |
133 | final_message: "The system is finally up, after $UPTIME seconds"
134 |
--------------------------------------------------------------------------------
/templates/onboard.tpl:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # vars
4 | #
5 | # get device id for do
6 | deviceId=$1
7 | #
8 | admin_username='${uname}'
9 | admin_password='${upassword}'
10 | CREDS="$admin_username:$admin_password"
11 | LOG_FILE=${onboard_log}
12 | # constants
13 | mgmt_port=`tmsh list sys httpd ssl-port | grep ssl-port | sed 's/ssl-port //;s/ //g'`
14 | authUrl="/mgmt/shared/authn/login"
15 | rpmInstallUrl="/mgmt/shared/iapp/package-management-tasks"
16 | rpmFilePath="/var/config/rest/downloads"
17 | local_host="http://localhost:8100"
18 | # do
19 | doUrl="/mgmt/shared/declarative-onboarding"
20 | doCheckUrl="/mgmt/shared/declarative-onboarding/info"
21 | doTaskUrl="/mgmt/shared/declarative-onboarding/task"
22 | # as3
23 | as3Url="/mgmt/shared/appsvcs/declare"
24 | as3CheckUrl="/mgmt/shared/appsvcs/info"
25 | as3TaskUrl="/mgmt/shared/appsvcs/task/"
26 | # ts
27 | tsUrl="/mgmt/shared/telemetry/declare"
28 | tsCheckUrl="/mgmt/shared/telemetry/info"
29 | # cloud failover ext
30 | cfUrl="/mgmt/shared/cloud-failover/declare"
31 | cfCheckUrl="/mgmt/shared/cloud-failover/info"
32 | # fast
33 | fastCheckUrl="/mgmt/shared/fast/info"
34 | # declaration content
35 | cat > /config/do1.json < /config/do2.json < /config/as3.json <>$LOG_FILE
56 | else
57 | #if file exists, exit as only want to run once
58 | exit
59 | fi
60 |
61 | exec 1>$LOG_FILE 2>&1
62 |
63 | startTime=$(date +%s)
64 | echo "start device ID:$deviceId date: $(date)"
65 | function timer () {
66 | echo "Time Elapsed: $(( ${1} / 3600 ))h $(( (${1} / 60) % 60 ))m $(( ${1} % 60 ))s"
67 | }
68 | waitMcpd () {
69 | checks=0
70 | while [[ "$checks" -lt 120 ]]; do
71 | tmsh -a show sys mcp-state field-fmt | grep -q running
72 | if [ $? == 0 ]; then
73 | echo "[INFO: mcpd ready]"
74 | break
75 | fi
76 | echo "[WARN: mcpd not ready yet]"
77 | let checks=checks+1
78 | sleep 10
79 | done
80 | }
81 | waitActive () {
82 | checks=0
83 | while [[ "$checks" -lt 30 ]]; do
84 | tmsh -a show sys ready | grep -q no
85 | if [ $? == 1 ]; then
86 | echo "[INFO: system ready]"
87 | break
88 | fi
89 | echo "[WARN: system not ready yet count: $checks]"
90 | tmsh -a show sys ready | grep no
91 | let checks=checks+1
92 | sleep 10
93 | done
94 | }
95 | # CHECK TO SEE NETWORK IS READY
96 | count=0
97 | while true
98 | do
99 | STATUS=$(curl -s -k -I example.com | grep HTTP)
100 | if [[ $STATUS == *"200"* ]]; then
101 | echo "[INFO: internet access check passed]"
102 | break
103 | elif [ $count -le 6 ]; then
104 | echo "Status code: $STATUS Not done yet..."
105 | count=$[$count+1]
106 | else
107 | echo "[WARN: GIVE UP...]"
108 | break
109 | fi
110 | sleep 10
111 | done
112 | # download latest atc tools
113 | toolsList=$(cat -</dev/null 2>&1 <<<"$code"; then
413 | echo "Parsed JSON successfully and got something other than false/null count: $taskCount"
414 | status=$(curl -s -u $CREDS $local_host$doTaskUrl/$task | jq -r .result.status)
415 | sleep 1
416 | echo "status: $status code: $code"
417 | # 200,202,422,400,404,500,422
418 | echo "DO: $task response:$code status:$status"
419 | sleep 1
420 | #FINISHED,STARTED,RUNNING,ROLLING_BACK,FAILED,ERROR,NULL
421 | case $status in
422 | FINISHED)
423 | # finished
424 | echo " $task status: $status "
425 | # bigstart start dhclient
426 | break 2
427 | ;;
428 | STARTED)
429 | # started
430 | echo " $filename status: $status "
431 | sleep 30
432 | ;;
433 | RUNNING)
434 | # running
435 | echo "DO Status: $status task: $task Not done yet...count:$taskCount"
436 | # wait for active-online-state
437 | waitMcpd
438 | if [[ "$taskCount" -le 5 ]]; then
439 | sleep 60
440 | fi
441 | waitActive
442 | #sleep 120
443 | taskCount=$[$taskCount+1]
444 | ;;
445 | FAILED)
446 | # failed
447 | error=$(curl -s -u $CREDS $local_host$doTaskUrl/$task | jq -r .result.status)
448 | echo "failed $task, $error"
449 | #count=$[$count+1]
450 | break
451 | ;;
452 | ERROR)
453 | # error
454 | error=$(curl -s -u $CREDS $local_host$doTaskUrl/$task | jq -r .result.status)
455 | echo "Error $task, $error"
456 | #count=$[$count+1]
457 | break
458 | ;;
459 | ROLLING_BACK)
460 | # Rolling back
461 | echo "Rolling back failed status: $status task: $task"
462 | break
463 | ;;
464 | OK)
465 | # complete no change
466 | echo "Complete no change status: $status task: $task"
467 | break 2
468 | ;;
469 | *)
470 | # other
471 | echo "other: $status"
472 | echo "other task: $task count: $taskCount"
473 | debug=$(curl -s -u $CREDS $local_host$doTaskUrl/$task)
474 | echo "other debug: $debug"
475 | case $debug in
476 | *not*registered*)
477 | # restnoded response DO api is unresponsive
478 | echo "DO endpoint not avaliable waiting..."
479 | sleep 30
480 | ;;
481 | *resterrorresponse*)
482 | # restnoded response DO api is unresponsive
483 | echo "DO endpoint not avaliable waiting..."
484 | sleep 30
485 | ;;
486 | *start-limit*)
487 | # dhclient issue hit
488 | echo " do dhclient starting issue hit start another task"
489 | break
490 | ;;
491 | esac
492 | sleep 30
493 | taskCount=$[$taskCount+1]
494 | ;;
495 | esac
496 | else
497 | echo "Failed to parse JSON, or got false/null"
498 | echo "DO status code: $code"
499 | debug=$(curl -s -u $CREDS $local_host$doTaskUrl/$task)
500 | echo "debug DO code: $debug"
501 | count=$[$count+1]
502 | fi
503 | done
504 | done
505 | }
506 | # mgmt
507 | echo "set management"
508 | echo -e "create cli transaction;
509 | modify sys global-settings mgmt-dhcp disabled;
510 | submit cli transaction" | tmsh -q
511 | tmsh save /sys config
512 | # get as3 values
513 | externalVip=$(curl -sf --retry 20 -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface?api-version=2017-08-01" | jq -r '.[1].ipv4.ipAddress[1].privateIpAddress')
514 |
515 | # end get values
516 |
517 | # run DO
518 | echo "----run do----"
519 | count=0
520 | while [ $count -le 4 ]
521 | do
522 | doStatus=$(checkDO)
523 | echo "DO check status: $doStatus"
524 | if [ $deviceId == 1 ] && [[ "$doStatus" = *"online"* ]]; then
525 | echo "running do for id:$deviceId"
526 | bigstart stop dhclient
527 | runDO do1.json
528 | if [ "$?" == 0 ]; then
529 | echo "done with do"
530 | bigstart start dhclient
531 | results=$(restcurl -u $CREDS -X GET $doTaskUrl | jq '.[] | .id, .result')
532 | echo "do results: $results"
533 | break
534 | fi
535 | elif [ $deviceId == 2 ] && [[ "$doStatus" = *"online"* ]]; then
536 | echo "running do for id:$deviceId"
537 | bigstart stop dhclient
538 | runDO do2.json
539 | if [ "$?" == 0 ]; then
540 | echo "done with do"
541 | bigstart start dhclient
542 | results=$(restcurl -u $CREDS -X GET $doTaskUrl | jq '.[] | .id, .result')
543 | echo "do results: $results"
544 | break
545 | fi
546 | elif [ $count -le 2 ]; then
547 | echo "DeviceID: $deviceId Status code: $doStatus DO not ready yet..."
548 | count=$[$count+1]
549 | sleep 30
550 | else
551 | echo "DO not online status: $doStatus"
552 | break
553 | fi
554 | done
555 | function runAS3 () {
556 | count=0
557 | while [ $count -le 4 ]
558 | do
559 | # wait for do to finish
560 | waitActive
561 | # make task
562 | task=$(curl -s -u $CREDS -H "Content-Type: Application/json" -H 'Expect:' -X POST $local_host$as3Url?async=true -d @/config/as3.json | jq -r .id)
563 | echo "===== starting as3 task: $task ====="
564 | sleep 1
565 | count=$[$count+1]
566 | # check task code
567 | taskCount=0
568 | while [ $taskCount -le 3 ]
569 | do
570 | as3CodeType=$(curl -s -u $CREDS -X GET $local_host$as3TaskUrl/$task | jq -r type )
571 | if [[ "$as3CodeType" == "object" ]]; then
572 | code=$(curl -s -u $CREDS -X GET $local_host$as3TaskUrl/$task | jq -r .)
573 | tenants=$(curl -s -u $CREDS -X GET $local_host$as3TaskUrl/$task | jq -r .results[].tenant)
574 | echo "object: $code"
575 | elif [ "$as3CodeType" == "array" ]; then
576 | echo "array $code check task, breaking"
577 | break
578 | else
579 | echo "unknown type:$as3CodeType"
580 | fi
581 | sleep 1
582 | if jq -e . >/dev/null 2>&1 <<<"$code"; then
583 | echo "Parsed JSON successfully and got something other than false/null"
584 | status=$(curl -s -u $CREDS $local_host$as3TaskUrl/$task | jq -r .items[].results[].message)
585 | case $status in
586 | *progress)
587 | # in progress
588 | echo -e "Running: $task status: $status tenants: $tenants count: $taskCount "
589 | sleep 120
590 | taskCount=$[$taskCount+1]
591 | ;;
592 | *Error*)
593 | # error
594 | echo -e "Error Task: $task status: $status tenants: $tenants "
595 | if [[ "$status" = *"progress"* ]]; then
596 | sleep 180
597 | break
598 | else
599 | break
600 | fi
601 | ;;
602 | *failed*)
603 | # failed
604 | echo -e "failed: $task status: $status tenants: $tenants "
605 | break
606 | ;;
607 | *success*)
608 | # successful!
609 | echo -e "success: $task status: $status tenants: $tenants "
610 | break 3
611 | ;;
612 | no*change)
613 | # finished
614 | echo -e "no change: $task status: $status tenants: $tenants "
615 | break 4
616 | ;;
617 | *)
618 | # other
619 | echo "status: $status"
620 | debug=$(curl -s -u $CREDS $local_host$as3TaskUrl/$task)
621 | echo "debug: $debug"
622 | error=$(curl -s -u $CREDS $local_host$as3TaskUrl/$task | jq -r '.results[].message')
623 | echo "Other: $task, $error"
624 | break
625 | ;;
626 | esac
627 | else
628 | echo "Failed to parse JSON, or got false/null"
629 | echo "AS3 status code: $code"
630 | debug=$(curl -s -u $CREDS $local_host$doTaskUrl/$task)
631 | echo "debug AS3 code: $debug"
632 | count=$[$count+1]
633 | fi
634 | done
635 | done
636 | }
637 |
638 | # modify as3
639 | #sdToken=$(echo "$token" | base64)
640 | sed -i "s/-external-virtual-address-/$externalVip/g" /config/as3.json
641 | #sed -i "s/-sd-sa-token-b64-/$token/g" /config/as3.json
642 | # end modify as3
643 |
644 | # metadata route
645 | echo -e 'create cli transaction;
646 | modify sys db config.allow.rfc3927 value enable;
647 | create sys management-route metadata-route network 169.254.169.254/32 gateway ${mgmtGateway};
648 | submit cli transaction' | tmsh -q
649 | tmsh save /sys config
650 | # add management route with metric 0 for the win
651 | route add -net default gw ${mgmtGateway} netmask 0.0.0.0 dev mgmt metric 0
652 | # run as3
653 | count=0
654 | while [ $count -le 4 ]
655 | do
656 | as3Status=$(checkAS3)
657 | echo "AS3 check status: $as3Status"
658 | if [[ "$as3Status" == *"online"* ]]; then
659 | if [ $deviceId == 1 ]; then
660 | echo "running as3"
661 | runAS3
662 | echo "done with as3"
663 | results=$(restcurl -u $CREDS $as3TaskUrl | jq '.items[] | .id, .results')
664 | echo "as3 results: $results"
665 | break
666 | else
667 | echo "Not posting as3 device $deviceid not primary"
668 | break
669 | fi
670 | elif [ $count -le 2 ]; then
671 | echo "Status code: $as3Status As3 not ready yet..."
672 | count=$[$count+1]
673 | else
674 | echo "As3 API Status $as3Status"
675 | break
676 | fi
677 | done
678 | #
679 | #
680 | # cleanup
681 | ## remove declarations
682 | # rm -f /config/do1.json
683 | # rm -f /config/do2.json
684 | # rm -f /config/as3.json
685 | ## disable/replace default admin account
686 | # echo -e "create cli transaction;
687 | # modify /sys db systemauth.primaryadminuser value $admin_username;
688 | # submit cli transaction" | tmsh -q
689 | tmsh save sys config
690 | echo "timestamp end: $(date)"
691 | echo "setup complete $(timer "$(($(date +%s) - $startTime))")"
692 | exit
693 |
--------------------------------------------------------------------------------
/templates/telemetry_dashboard.omsview:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "location": {
6 | "type": "string",
7 | "defaultValue": ""
8 | },
9 | "resourcegroup": {
10 | "type": "string",
11 | "defaultValue": ""
12 | },
13 | "subscriptionId": {
14 | "type": "string",
15 | "defaultValue": ""
16 | },
17 | "workspace": {
18 | "type": "string",
19 | "defaultValue": ""
20 | },
21 | "workspaceapiversion": {
22 | "type": "string",
23 | "defaultValue": ""
24 | }
25 | },
26 | "resources": [
27 | {
28 | "apiVersion": "[parameters('workspaceapiversion')]",
29 | "name": "[parameters('workspace')]",
30 | "type": "Microsoft.OperationalInsights/workspaces",
31 | "location": "[parameters('location')]",
32 | "id": "[Concat('/subscriptions/', parameters('subscriptionId'), '/resourceGroups/', parameters('resourcegroup'), '/providers/Microsoft.OperationalInsights/workspaces/', parameters('workspace'))]",
33 | "resources": [
34 | {
35 | "apiVersion": "2015-11-01-preview",
36 | "name": "Devices",
37 | "type": "views",
38 | "location": "[parameters('location')]",
39 | "id": "[Concat('/subscriptions/', parameters('subscriptionId'), '/resourceGroups/', parameters('resourcegroup'), '/providers/Microsoft.OperationalInsights/workspaces/', parameters('workspace'),'/views/Devices')]",
40 | "dependson": [
41 | "[Concat('/subscriptions/', parameters('subscriptionId'), '/resourceGroups/', parameters('resourcegroup'), '/providers/Microsoft.OperationalInsights/workspaces/', parameters('workspace'))]"
42 | ],
43 | "properties": {
44 | "Id": "Devices",
45 | "Name": "Devices",
46 | "Author": null,
47 | "Source": "Local",
48 | "Version": 2,
49 | "Dashboard": [
50 | {
51 | "Id": "LineChartCalloutStackedBuilderBlade",
52 | "Type": "Blade",
53 | "Version": 0,
54 | "Configuration": {
55 | "General": {
56 | "title": "Violations",
57 | "newGroup": false
58 | },
59 | "charts": [
60 | {
61 | "Header": {
62 | "Title": "ASM Violations over time",
63 | "Subtitle": ""
64 | },
65 | "LineChart": {
66 | "Query": "F5Telemetry_ASM_CL | where isnotempty(attack_type_s)",
67 | "yAxis": {
68 | "isLogarithmic": false,
69 | "units": {
70 | "baseUnitType": "",
71 | "baseUnit": "",
72 | "displayUnit": ""
73 | },
74 | "customLabel": ""
75 | },
76 | "NavigationSelect": {}
77 | }
78 | },
79 | {
80 | "Header": {
81 | "Title": "Requests over time",
82 | "Subtitle": ""
83 | },
84 | "LineChart": {
85 | "Query": "F5Telemetry_LTM_CL | where event_source_s == \"request_logging\"",
86 | "yAxis": {
87 | "isLogarithmic": false,
88 | "units": {
89 | "baseUnitType": "",
90 | "baseUnit": "",
91 | "displayUnit": ""
92 | },
93 | "customLabel": ""
94 | },
95 | "NavigationSelect": {}
96 | }
97 | },
98 | {
99 | "Header": {
100 | "Title": "Empty",
101 | "Subtitle": ""
102 | },
103 | "LineChart": {
104 | "Query": "",
105 | "yAxis": {
106 | "isLogarithmic": false,
107 | "units": {
108 | "baseUnitType": "",
109 | "baseUnit": "",
110 | "displayUnit": ""
111 | },
112 | "customLabel": ""
113 | },
114 | "NavigationSelect": {}
115 | }
116 | }
117 | ]
118 | }
119 | },
120 | {
121 | "Id": "NumberTileListBuilderBlade",
122 | "Type": "Blade",
123 | "Version": 0,
124 | "Configuration": {
125 | "General": {
126 | "title": "Source IP's triggering violations",
127 | "newGroup": false,
128 | "icon": "",
129 | "useIcon": false
130 | },
131 | "Tile": {
132 | "Query": "F5Telemetry_ASM_CL | where isnotempty(attack_type_s) | summarize AggregatedValue = count() by ip_client_s | count",
133 | "Legend": "Count of Unique Source IP's",
134 | "NavigationSelect": {}
135 | },
136 | "List": {
137 | "Query": "F5Telemetry_ASM_CL | where isnotempty(attack_type_s) | summarize AggregatedValue = count() by ip_client_s | sort by AggregatedValue desc",
138 | "HideGraph": false,
139 | "enableSparklines": false,
140 | "operation": "Summary",
141 | "ColumnsTitle": {
142 | "Name": "IP",
143 | "Value": "Count"
144 | },
145 | "Color": "#0072c6",
146 | "thresholds": {
147 | "isEnabled": false,
148 | "values": [
149 | {
150 | "name": "Normal",
151 | "threshold": "Default",
152 | "color": "#009e49",
153 | "isDefault": true
154 | },
155 | {
156 | "name": "Warning",
157 | "threshold": "60",
158 | "color": "#fcd116",
159 | "isDefault": false
160 | },
161 | {
162 | "name": "Error",
163 | "threshold": "90",
164 | "color": "#ba141a",
165 | "isDefault": false
166 | }
167 | ]
168 | },
169 | "NameDSVSeparator": "",
170 | "NavigationQuery": "search {selected item} | sort by TimeGenerated desc",
171 | "NavigationSelect": {
172 | "NavigationQuery": "search {selected item} | sort by TimeGenerated desc"
173 | }
174 | }
175 | }
176 | },
177 | {
178 | "Id": "NumberTileListBuilderBlade",
179 | "Type": "Blade",
180 | "Version": 0,
181 | "Configuration": {
182 | "General": {
183 | "title": "Attack Types",
184 | "newGroup": false,
185 | "icon": "",
186 | "useIcon": false
187 | },
188 | "Tile": {
189 | "Query": "F5Telemetry_ASM_CL | where isnotempty(attack_type_s) | summarize AggregatedValue = count() by attack_type_s | count",
190 | "Legend": "Count of attack types",
191 | "NavigationSelect": {}
192 | },
193 | "List": {
194 | "Query": "F5Telemetry_ASM_CL | where isnotempty(attack_type_s) | summarize AggregatedValue = count() by attack_type_s | sort by AggregatedValue desc",
195 | "HideGraph": false,
196 | "enableSparklines": false,
197 | "operation": "Summary",
198 | "ColumnsTitle": {
199 | "Name": "Computer",
200 | "Value": "Count"
201 | },
202 | "Color": "#0072c6",
203 | "thresholds": {
204 | "isEnabled": false,
205 | "values": [
206 | {
207 | "name": "Normal",
208 | "threshold": "Default",
209 | "color": "#009e49",
210 | "isDefault": true
211 | },
212 | {
213 | "name": "Warning",
214 | "threshold": "60",
215 | "color": "#fcd116",
216 | "isDefault": false
217 | },
218 | {
219 | "name": "Error",
220 | "threshold": "90",
221 | "color": "#ba141a",
222 | "isDefault": false
223 | }
224 | ]
225 | },
226 | "NameDSVSeparator": "",
227 | "NavigationQuery": "search {selected item} | sort by TimeGenerated desc",
228 | "NavigationSelect": {
229 | "NavigationQuery": "search {selected item} | sort by TimeGenerated desc"
230 | }
231 | }
232 | }
233 | },
234 | {
235 | "Id": "LineChartCalloutStackedBuilderBlade",
236 | "Type": "Blade",
237 | "Version": 0,
238 | "Configuration": {
239 | "General": {
240 | "title": "Device Info",
241 | "newGroup": false
242 | },
243 | "charts": [
244 | {
245 | "Header": {
246 | "Title": "CPU",
247 | "Subtitle": ""
248 | },
249 | "LineChart": {
250 | "Query": "F5Telemetry_system_CL | summarize AggregatedValue = avg(cpu_d) by hostname_s | sort by AggregatedValue desc",
251 | "yAxis": {
252 | "isLogarithmic": false,
253 | "units": {
254 | "baseUnitType": "",
255 | "baseUnit": "",
256 | "displayUnit": ""
257 | },
258 | "customLabel": ""
259 | },
260 | "NavigationSelect": {}
261 | }
262 | },
263 | {
264 | "Header": {
265 | "Title": "Memory",
266 | "Subtitle": ""
267 | },
268 | "LineChart": {
269 | "Query": "F5Telemetry_system_CL | summarize AggregatedValue = avg(memory_d) by hostname_s | sort by AggregatedValue desc",
270 | "yAxis": {
271 | "isLogarithmic": false,
272 | "units": {
273 | "baseUnitType": "",
274 | "baseUnit": "",
275 | "displayUnit": ""
276 | },
277 | "customLabel": ""
278 | },
279 | "NavigationSelect": {}
280 | }
281 | },
282 | {
283 | "Header": {
284 | "Title": "TMM Memory",
285 | "Subtitle": ""
286 | },
287 | "LineChart": {
288 | "Query": "F5Telemetry_system_CL | summarize AggregatedValue = avg(tmmMemory_d) by hostname_s | sort by AggregatedValue desc",
289 | "yAxis": {
290 | "isLogarithmic": false,
291 | "units": {
292 | "baseUnitType": "",
293 | "baseUnit": "",
294 | "displayUnit": ""
295 | },
296 | "customLabel": ""
297 | },
298 | "NavigationSelect": {}
299 | }
300 | }
301 | ]
302 | }
303 | }
304 | ],
305 | "Filters": [],
306 | "OverviewTile": {
307 | "Id": "SingleNumberBuilderTile",
308 | "Type": "OverviewTile",
309 | "Version": 2,
310 | "Configuration": {
311 | "Tile": {
312 | "Legend": "Count",
313 | "Query": "F5Telemetry_system_CL | summarize dcount(hostname_s) "
314 | },
315 | "Advanced": {
316 | "DataFlowVerification": {
317 | "Enabled": false,
318 | "Query": "search * | limit 1 | project TimeGenerated",
319 | "Message": ""
320 | }
321 | }
322 | }
323 | }
324 | }
325 | }
326 | ]
327 | }
328 | ]
329 | }
330 |
--------------------------------------------------------------------------------
/templates/ts.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Telemetry",
3 | "My_System": {
4 | "class": "Telemetry_System",
5 | "systemPoller": {
6 | "interval": 60
7 | }
8 | },
9 | "My_Listener": {
10 | "class": "Telemetry_Listener",
11 | "port": 6514
12 | },
13 | "My_Consumer": {
14 | "class": "Telemetry_Consumer",
15 | "type": "Azure_Log_Analytics",
16 | "workspaceId": "${law_id}",
17 | "passphrase": {
18 | "cipherText": "${law_primkey}"
19 | },
20 | "useManagedIdentity": false,
21 | "region": "${region}"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/three_tier/firewall/bigip.tf:
--------------------------------------------------------------------------------
1 | # # Create a Public IP for the Virtual Machines
2 | # resource azurerm_public_ip f5vmpip01 {
3 | # name = "${var.prefix}-vm01-mgmt-pip01-delete-me"
4 | # location = var.resourceGroup.location
5 | # resource_group_name = var.resourceGroup.name
6 | # allocation_method = "Static"
7 | # sku = "Standard"
8 |
9 | # tags = {
10 | # Name = "${var.prefix}-f5vm-public-ip"
11 | # }
12 | # }
13 | # resource azurerm_public_ip f5vmpip02 {
14 | # name = "${var.prefix}-vm02-mgmt-pip02-delete-me"
15 | # location = var.resourceGroup.location
16 | # resource_group_name = var.resourceGroup.name
17 | # allocation_method = "Static"
18 | # sku = "Standard"
19 |
20 | # tags = {
21 | # Name = "${var.prefix}-f5vm-public-ip"
22 | # }
23 | # }
24 |
25 | # Obtain Gateway IP for each Subnet
26 | locals {
27 | depends_on = [var.subnetMgmt.id, var.subnetExternal.id]
28 | mgmt_gw = cidrhost(var.subnets["management"], 1)
29 | ext_gw = cidrhost(var.subnets["external"], 1)
30 | int_gw = cidrhost(var.subnets["internal"], 1)
31 | }
32 |
33 | # Create the first network interface card for Management
34 | resource "azurerm_network_interface" "vm01-mgmt-nic" {
35 | name = "${var.prefix}-vm01-mgmt-nic"
36 | location = var.resourceGroup.location
37 | resource_group_name = var.resourceGroup.name
38 |
39 | ip_configuration {
40 | name = "primary"
41 | subnet_id = var.subnetMgmt.id
42 | private_ip_address_allocation = "Static"
43 | private_ip_address = var.f5_mgmt["f5vm01mgmt"]
44 | #public_ip_address_id = azurerm_public_ip.f5vmpip01.id
45 | }
46 |
47 | tags = var.tags
48 | }
49 |
50 | # Associate the Network Interface to the ManagementPool
51 | resource "azurerm_network_interface_backend_address_pool_association" "mpool_assc_vm01" {
52 | network_interface_id = azurerm_network_interface.vm01-mgmt-nic.id
53 | ip_configuration_name = "primary"
54 | #backend_address_pool_id = var.managementPool.id
55 | backend_address_pool_id = var.primaryPool.id
56 | }
57 | # Associate the Network Interface to the ManagementPool
58 | resource "azurerm_network_interface_backend_address_pool_association" "mpool_assc_vm02" {
59 | network_interface_id = azurerm_network_interface.vm02-mgmt-nic.id
60 | ip_configuration_name = "primary"
61 | #backend_address_pool_id = var.managementPool.id
62 | backend_address_pool_id = var.primaryPool.id
63 | }
64 |
65 | resource "azurerm_network_interface_security_group_association" "bigip01-mgmt-nsg" {
66 | network_interface_id = azurerm_network_interface.vm01-mgmt-nic.id
67 | network_security_group_id = var.securityGroup.id
68 | }
69 |
70 | resource "azurerm_network_interface" "vm02-mgmt-nic" {
71 | name = "${var.prefix}-vm02-mgmt-nic"
72 | location = var.resourceGroup.location
73 | resource_group_name = var.resourceGroup.name
74 |
75 | ip_configuration {
76 | name = "primary"
77 | subnet_id = var.subnetMgmt.id
78 | private_ip_address_allocation = "Static"
79 | private_ip_address = var.f5_mgmt["f5vm02mgmt"]
80 | #public_ip_address_id = azurerm_public_ip.f5vmpip02.id
81 | }
82 |
83 | tags = var.tags
84 | }
85 |
86 | resource "azurerm_network_interface_security_group_association" "bigip02-mgmt-nsg" {
87 | network_interface_id = azurerm_network_interface.vm02-mgmt-nic.id
88 | network_security_group_id = var.securityGroup.id
89 | }
90 |
91 | # Create the second network interface card for External
92 | resource "azurerm_network_interface" "vm01-ext-nic" {
93 | name = "${var.prefix}-vm01-ext-nic"
94 | location = var.resourceGroup.location
95 | resource_group_name = var.resourceGroup.name
96 | enable_ip_forwarding = true
97 | enable_accelerated_networking = var.bigip_version == "latest" ? true : false
98 |
99 | ip_configuration {
100 | name = "primary"
101 | subnet_id = var.subnetExternal.id
102 | private_ip_address_allocation = "Static"
103 | private_ip_address = var.f5_t1_ext["f5vm01ext"]
104 | primary = true
105 | }
106 |
107 | ip_configuration {
108 | name = "secondary"
109 | subnet_id = var.subnetExternal.id
110 | private_ip_address_allocation = "Static"
111 | private_ip_address = var.f5_t1_ext["f5vm01ext_sec"]
112 | }
113 |
114 | tags = {
115 | Name = "${var.prefix}-vm01-ext-int"
116 | environment = var.tags["environment"]
117 | owner = var.tags["owner"]
118 | group = var.tags["group"]
119 | costcenter = var.tags["costcenter"]
120 | application = var.tags["application"]
121 | f5_cloud_failover_label = "saca"
122 | f5_cloud_failover_nic_map = "external"
123 | }
124 | }
125 |
126 | resource "azurerm_network_interface_security_group_association" "bigip01-ext-nsg" {
127 | network_interface_id = azurerm_network_interface.vm01-ext-nic.id
128 | network_security_group_id = var.securityGroup.id
129 | }
130 |
131 | resource "azurerm_network_interface" "vm02-ext-nic" {
132 | name = "${var.prefix}-vm02-ext-nic"
133 | location = var.resourceGroup.location
134 | resource_group_name = var.resourceGroup.name
135 | enable_ip_forwarding = true
136 | enable_accelerated_networking = var.bigip_version == "latest" ? true : false
137 |
138 | ip_configuration {
139 | name = "primary"
140 | subnet_id = var.subnetExternal.id
141 | private_ip_address_allocation = "Static"
142 | private_ip_address = var.f5_t1_ext["f5vm02ext"]
143 | primary = true
144 | }
145 |
146 | ip_configuration {
147 | name = "secondary"
148 | subnet_id = var.subnetExternal.id
149 | private_ip_address_allocation = "Static"
150 | private_ip_address = var.f5_t1_ext["f5vm02ext_sec"]
151 | }
152 |
153 | tags = {
154 | Name = "${var.prefix}-vm01-ext-int"
155 | environment = var.tags["environment"]
156 | owner = var.tags["owner"]
157 | group = var.tags["group"]
158 | costcenter = var.tags["costcenter"]
159 | application = var.tags["application"]
160 | f5_cloud_failover_label = "saca"
161 | f5_cloud_failover_nic_map = "external"
162 | }
163 | }
164 |
165 | resource "azurerm_network_interface_security_group_association" "bigip02-ext-nsg" {
166 | network_interface_id = azurerm_network_interface.vm02-ext-nic.id
167 | network_security_group_id = var.securityGroup.id
168 | }
169 |
170 | # Create the third network interface card for Internal
171 | resource "azurerm_network_interface" "vm01-int-nic" {
172 | name = "${var.prefix}-vm01-int-nic"
173 | location = var.resourceGroup.location
174 | resource_group_name = var.resourceGroup.name
175 | enable_ip_forwarding = true
176 | enable_accelerated_networking = var.bigip_version == "latest" ? true : false
177 |
178 | ip_configuration {
179 | name = "primary"
180 | subnet_id = var.subnetInternal.id
181 | private_ip_address_allocation = "Static"
182 | private_ip_address = var.f5_t1_int["f5vm01int"]
183 | primary = true
184 | }
185 |
186 | ip_configuration {
187 | name = "secondary"
188 | subnet_id = var.subnetInternal.id
189 | private_ip_address_allocation = "Static"
190 | private_ip_address = var.f5_t1_int["f5vm01int_sec"]
191 | }
192 |
193 | tags = var.tags
194 | }
195 |
196 | resource "azurerm_network_interface_security_group_association" "bigip01-int-nsg" {
197 | network_interface_id = azurerm_network_interface.vm01-int-nic.id
198 | network_security_group_id = var.securityGroup.id
199 | }
200 |
201 | resource "azurerm_network_interface" "vm02-int-nic" {
202 | name = "${var.prefix}-vm02-int-nic"
203 | location = var.resourceGroup.location
204 | resource_group_name = var.resourceGroup.name
205 | enable_ip_forwarding = true
206 | enable_accelerated_networking = var.bigip_version == "latest" ? true : false
207 |
208 | ip_configuration {
209 | name = "primary"
210 | subnet_id = var.subnetInternal.id
211 | private_ip_address_allocation = "Static"
212 | private_ip_address = var.f5_t1_int["f5vm02int"]
213 | primary = true
214 | }
215 |
216 | ip_configuration {
217 | name = "secondary"
218 | subnet_id = var.subnetInternal.id
219 | private_ip_address_allocation = "Static"
220 | private_ip_address = var.f5_t1_int["f5vm02int_sec"]
221 | }
222 |
223 | tags = var.tags
224 | }
225 |
226 | resource "azurerm_network_interface_security_group_association" "bigip02-int-nsg" {
227 | network_interface_id = azurerm_network_interface.vm02-int-nic.id
228 | network_security_group_id = var.securityGroup.id
229 | }
230 |
231 | # Associate the External Network Interface to the BackendPool
232 | resource "azurerm_network_interface_backend_address_pool_association" "bpool_assc_vm01" {
233 | network_interface_id = azurerm_network_interface.vm01-ext-nic.id
234 | ip_configuration_name = "secondary"
235 | backend_address_pool_id = var.backendPool.id
236 | }
237 |
238 | resource "azurerm_network_interface_backend_address_pool_association" "bpool_assc_vm02" {
239 | network_interface_id = azurerm_network_interface.vm02-ext-nic.id
240 | ip_configuration_name = "secondary"
241 | backend_address_pool_id = var.backendPool.id
242 | }
243 |
244 | resource "azurerm_network_interface_backend_address_pool_association" "primary_pool_assc_vm01" {
245 | network_interface_id = azurerm_network_interface.vm01-ext-nic.id
246 | ip_configuration_name = "primary"
247 | backend_address_pool_id = var.primaryPool.id
248 | }
249 |
250 | resource "azurerm_network_interface_backend_address_pool_association" "primary_pool_assc_vm02" {
251 | network_interface_id = azurerm_network_interface.vm02-ext-nic.id
252 | ip_configuration_name = "primary"
253 | backend_address_pool_id = var.primaryPool.id
254 | }
255 |
256 | # attach interfaces to backend pool
257 | resource "azurerm_network_interface_backend_address_pool_association" "int_bpool_assc_vm01" {
258 | network_interface_id = azurerm_network_interface.vm01-int-nic.id
259 | ip_configuration_name = "secondary"
260 | backend_address_pool_id = var.internalBackPool.id
261 | }
262 |
263 | resource "azurerm_network_interface_backend_address_pool_association" "int_bpool_assc_vm02" {
264 | network_interface_id = azurerm_network_interface.vm02-int-nic.id
265 | ip_configuration_name = "secondary"
266 | backend_address_pool_id = var.internalBackPool.id
267 | }
268 |
269 | # Create F5 BIGIP VMs
270 | resource "azurerm_virtual_machine" "f5vm01" {
271 | name = "${var.prefix}-f5vm01"
272 | location = var.resourceGroup.location
273 | resource_group_name = var.resourceGroup.name
274 | primary_network_interface_id = azurerm_network_interface.vm01-mgmt-nic.id
275 | network_interface_ids = [azurerm_network_interface.vm01-mgmt-nic.id, azurerm_network_interface.vm01-ext-nic.id, azurerm_network_interface.vm01-int-nic.id]
276 | vm_size = var.instanceType
277 | availability_set_id = var.availabilitySet.id
278 |
279 | delete_os_disk_on_termination = true
280 | delete_data_disks_on_termination = true
281 |
282 | storage_image_reference {
283 | publisher = "f5-networks"
284 | offer = var.product
285 | sku = var.image_name
286 | version = var.bigip_version
287 | }
288 |
289 | storage_os_disk {
290 | name = "${var.prefix}-vm01-osdisk"
291 | caching = "ReadWrite"
292 | create_option = "FromImage"
293 | managed_disk_type = "Standard_LRS"
294 | }
295 |
296 | os_profile {
297 | computer_name = "${var.prefix}vm01"
298 | admin_username = var.adminUserName
299 | admin_password = var.adminPassword
300 | }
301 |
302 | os_profile_linux_config {
303 | disable_password_authentication = false
304 | }
305 |
306 | plan {
307 | name = var.image_name
308 | publisher = "f5-networks"
309 | product = var.product
310 | }
311 |
312 | tags = var.tags
313 | }
314 |
315 | resource "azurerm_virtual_machine" "f5vm02" {
316 | name = "${var.prefix}-f5vm02"
317 | location = var.resourceGroup.location
318 | resource_group_name = var.resourceGroup.name
319 | primary_network_interface_id = azurerm_network_interface.vm02-mgmt-nic.id
320 | network_interface_ids = [azurerm_network_interface.vm02-mgmt-nic.id, azurerm_network_interface.vm02-ext-nic.id, azurerm_network_interface.vm02-int-nic.id]
321 | vm_size = var.instanceType
322 | availability_set_id = var.availabilitySet.id
323 |
324 | delete_os_disk_on_termination = true
325 | delete_data_disks_on_termination = true
326 |
327 | storage_image_reference {
328 | publisher = "f5-networks"
329 | offer = var.product
330 | sku = var.image_name
331 | version = var.bigip_version
332 | }
333 |
334 | storage_os_disk {
335 | name = "${var.prefix}-vm02-osdisk"
336 | caching = "ReadWrite"
337 | create_option = "FromImage"
338 | managed_disk_type = "Standard_LRS"
339 | }
340 |
341 | os_profile {
342 | computer_name = "${var.prefix}vm02"
343 | admin_username = var.adminUserName
344 | admin_password = var.adminPassword
345 | }
346 |
347 | os_profile_linux_config {
348 | disable_password_authentication = false
349 | }
350 |
351 | plan {
352 | name = var.image_name
353 | publisher = "f5-networks"
354 | product = var.product
355 | }
356 |
357 | tags = var.tags
358 | }
359 |
360 | # Setup Onboarding scripts
361 | data "template_file" "vm_onboard" {
362 | template = file("./templates/onboard.tpl")
363 | vars = {
364 | uname = var.adminUserName
365 | upassword = var.adminPassword
366 | doVersion = "latest"
367 | as3Version = "latest"
368 | tsVersion = "latest"
369 | cfVersion = "latest"
370 | fastVersion = "1.0.0"
371 | doExternalDeclarationUrl = "https://example.domain.com/do.json"
372 | as3ExternalDeclarationUrl = "https://example.domain.com/as3.json"
373 | tsExternalDeclarationUrl = "https://example.domain.com/ts.json"
374 | cfExternalDeclarationUrl = "https://example.domain.com/cf.json"
375 | onboard_log = var.onboard_log
376 | mgmtGateway = local.mgmt_gw
377 | DO1_Document = data.template_file.vm01_do_json.rendered
378 | DO2_Document = data.template_file.vm02_do_json.rendered
379 | AS3_Document = data.template_file.as3_json.rendered
380 | }
381 | }
382 |
383 | # as3 uuid generation
384 | resource "random_uuid" "as3_uuid" {}
385 |
386 | data "http" "onboard" {
387 | url = "https://raw.githubusercontent.com/Mikej81/f5-bigip-hardening-DO/master/dist/terraform/latest/${var.licenses["license1"] != "" ? "byol" : "payg"}_cluster.json"
388 | }
389 |
390 | data "template_file" "vm01_do_json" {
391 | template = data.http.onboard.body
392 | vars = {
393 | host1 = var.hosts["host1"]
394 | host2 = var.hosts["host2"]
395 | local_host = var.hosts["host1"]
396 | external_selfip = "${var.f5_t1_ext["f5vm01ext"]}/${element(split("/", var.subnets["external"]), 1)}"
397 | internal_selfip = "${var.f5_t1_int["f5vm01int"]}/${element(split("/", var.subnets["internal"]), 1)}"
398 | log_localip = var.f5_t1_ext["f5vm01ext"]
399 | log_destination = var.app01ip
400 | vdmsSubnet = var.subnets["vdms"]
401 | appSubnet = var.subnets["application"]
402 | vnetSubnet = var.cidr
403 | remote_host = var.hosts["host2"]
404 | remote_selfip = var.f5_t1_ext["f5vm02ext"]
405 | externalGateway = local.ext_gw
406 | internalGateway = local.int_gw
407 | mgmtGateway = local.mgmt_gw
408 | dns_server = var.dns_server
409 | ntp_server = var.ntp_server
410 | timezone = var.timezone
411 | admin_user = var.adminUserName
412 | admin_password = var.adminPassword
413 | license = var.licenses["license1"] != "" ? var.licenses["license1"] : ""
414 | }
415 | }
416 |
417 | data "template_file" "vm02_do_json" {
418 | template = data.http.onboard.body
419 | vars = {
420 | host1 = var.hosts["host1"]
421 | host2 = var.hosts["host2"]
422 | local_host = var.hosts["host2"]
423 | external_selfip = "${var.f5_t1_ext["f5vm02ext"]}/${element(split("/", var.subnets["external"]), 1)}"
424 | internal_selfip = "${var.f5_t1_int["f5vm02int"]}/${element(split("/", var.subnets["internal"]), 1)}"
425 | log_localip = var.f5_t1_ext["f5vm02ext"]
426 | log_destination = var.app01ip
427 | vdmsSubnet = var.subnets["vdms"]
428 | appSubnet = var.subnets["application"]
429 | vnetSubnet = var.cidr
430 | remote_host = var.hosts["host1"]
431 | remote_selfip = var.f5_t1_ext["f5vm01ext"]
432 | externalGateway = local.ext_gw
433 | internalGateway = local.int_gw
434 | mgmtGateway = local.mgmt_gw
435 | dns_server = var.dns_server
436 | ntp_server = var.ntp_server
437 | timezone = var.timezone
438 | admin_user = var.adminUserName
439 | admin_password = var.adminPassword
440 | license = var.licenses["license2"] != "" ? var.licenses["license2"] : ""
441 | }
442 | }
443 |
444 | data "http" "appservice" {
445 | url = "https://raw.githubusercontent.com/Mikej81/f5-bigip-hardening-AS3/master/dist/terraform/latest/sccaSingleTier.json"
446 | }
447 |
448 | data "template_file" "as3_json" {
449 | template = data.http.appservice.body
450 | vars = {
451 | uuid = random_uuid.as3_uuid.result
452 | baseline_waf_policy = var.asm_policy
453 | exampleVipAddress = var.f5_t1_ext["f5vm01ext"]
454 | exampleVipSubnet = var.subnets["external"]
455 | ips_pool_addresses = var.ilb03ip
456 | rdp_pool_addresses = var.ilb03ip
457 | ssh_pool_addresses = var.ilb03ip
458 | app_pool_addresses = var.ilb03ip
459 | log_destination = var.ilb03ip
460 | example_vs_address = var.subnets["external"]
461 | mgmtVipAddress = var.f5_t1_ext["f5vm01ext_sec"]
462 | mgmtVipAddress2 = var.f5_t1_ext["f5vm02ext_sec"]
463 | transitVipAddress = var.f5_t1_int["f5vm01int_sec"]
464 | transitVipAddress2 = var.f5_t1_int["f5vm02int_sec"]
465 | }
466 | }
467 |
468 | # Run Startup Script
469 | resource "azurerm_virtual_machine_extension" "f5vm01-run-startup-cmd" {
470 | name = "${var.prefix}-f5vm01-run-startup-cmd"
471 | depends_on = [azurerm_virtual_machine.f5vm01, azurerm_network_interface_backend_address_pool_association.mpool_assc_vm01, azurerm_network_interface_backend_address_pool_association.mpool_assc_vm02]
472 | virtual_machine_id = azurerm_virtual_machine.f5vm01.id
473 | publisher = "Microsoft.Azure.Extensions"
474 | type = "CustomScript"
475 | type_handler_version = "2.0"
476 |
477 | settings = <> ./startup.b64 && cat ./startup.b64 | base64 -d >> ./startup-temp.sh && sed -e 's/\r$//' ./startup-temp.sh > ./startup-script.sh && chmod +x ./startup-script.sh && rm ./startup.b64 && bash ./startup-script.sh 1"
480 | }
481 | SETTINGS
482 |
483 | tags = var.tags
484 | }
485 |
486 | resource "azurerm_virtual_machine_extension" "f5vm02-run-startup-cmd" {
487 | name = "${var.prefix}-f5vm02-run-startup-cmd"
488 | depends_on = [azurerm_virtual_machine.f5vm01, azurerm_virtual_machine.f5vm02, azurerm_network_interface_backend_address_pool_association.mpool_assc_vm01, azurerm_network_interface_backend_address_pool_association.mpool_assc_vm02]
489 | virtual_machine_id = azurerm_virtual_machine.f5vm02.id
490 | publisher = "Microsoft.Azure.Extensions"
491 | type = "CustomScript"
492 | type_handler_version = "2.0"
493 |
494 | settings = <> ./startup.b64 && cat ./startup.b64 | base64 -d >> ./startup-temp.sh && sed -e 's/\r$//g' ./startup-temp.sh > ./startup-script.sh && chmod +x ./startup-script.sh && rm ./startup.b64 && bash ./startup-script.sh 2"
497 | }
498 | SETTINGS
499 |
500 | tags = var.tags
501 | }
502 |
503 |
504 | # Debug Template Outputs
505 | resource "local_file" "vm01_do_file" {
506 | content = data.template_file.vm01_do_json.rendered
507 | filename = "${path.module}/vm01_do_data.json"
508 | }
509 |
510 | resource "local_file" "vm02_do_file" {
511 | content = data.template_file.vm02_do_json.rendered
512 | filename = "${path.module}/vm02_do_data.json"
513 | }
514 |
515 | resource "local_file" "vm_as3_file" {
516 | content = data.template_file.as3_json.rendered
517 | filename = "${path.module}/vm_as3_data.json"
518 | }
519 |
520 | resource "local_file" "onboard_file" {
521 | content = data.template_file.vm_onboard.rendered
522 | filename = "${path.module}/onboard.sh"
523 | }
524 |
--------------------------------------------------------------------------------
/three_tier/firewall/outputs.tf:
--------------------------------------------------------------------------------
1 | # data azurerm_public_ip f5vmpip01 {
2 | # name = azurerm_public_ip.f5vmpip01.name
3 | # resource_group_name = var.resourceGroup.name
4 | # depends_on = [azurerm_public_ip.f5vmpip01, azurerm_virtual_machine.f5vm01]
5 | # }
6 | # data azurerm_public_ip f5vmpip02 {
7 | # name = azurerm_public_ip.f5vmpip02.name
8 | # resource_group_name = var.resourceGroup.name
9 | # depends_on = [azurerm_public_ip.f5vmpip02, azurerm_virtual_machine.f5vm02]
10 | # }
11 |
12 |
13 | output f5vm01_id { value = azurerm_virtual_machine.f5vm01.id }
14 | output f5vm01_mgmt_private_ip { value = azurerm_network_interface.vm01-mgmt-nic.private_ip_address }
15 | #output f5vm01_mgmt_public_ip { value = data.azurerm_public_ip.f5vmpip01.ip_address }
16 | output f5vm01_ext_private_ip { value = azurerm_network_interface.vm01-ext-nic.private_ip_address }
17 |
18 | output f5vm02_id { value = azurerm_virtual_machine.f5vm02.id }
19 | output f5vm02_mgmt_private_ip { value = azurerm_network_interface.vm02-mgmt-nic.private_ip_address }
20 | #output f5vm02_mgmt_public_ip { value = data.azurerm_public_ip.f5vmpip02.ip_address }
21 | output f5vm02_ext_private_ip { value = azurerm_network_interface.vm02-ext-nic.private_ip_address }
22 |
--------------------------------------------------------------------------------
/three_tier/firewall/variables.tf:
--------------------------------------------------------------------------------
1 | variable resourceGroup {}
2 | # admin credentials
3 | variable adminUserName {}
4 | variable adminPassword {}
5 | variable sshPublicKey {}
6 | # cloud info
7 | variable location {}
8 | variable region {}
9 | variable securityGroup {
10 | default = "none"
11 | }
12 | variable availabilitySet {}
13 | variable availabilitySet2 {}
14 |
15 | variable prefix {}
16 | # bigip network
17 | variable subnets {}
18 | variable subnetMgmt {}
19 | variable subnetExternal {}
20 | variable subnetInternal {}
21 | variable subnetWafExt {}
22 | variable subnetWafInt {}
23 | variable app01ip {}
24 |
25 | variable backendPool {}
26 | variable managementPool {}
27 | variable primaryPool {}
28 | variable internalBackPool {}
29 |
30 | variable f5_mgmt {}
31 | variable f5_t1_ext {}
32 | variable f5_t1_int {}
33 | variable f5_t3_ext {}
34 | variable f5_t3_int {}
35 |
36 | # winjump
37 | variable winjumpip {}
38 |
39 | # linuxjump
40 | variable linuxjumpip {}
41 |
42 | # device
43 | variable instanceType {}
44 |
45 |
46 | # BIGIP Image
47 | variable image_name {}
48 | variable product {}
49 | variable bigip_version {}
50 |
51 | variable cidr {}
52 |
53 | variable ilb01ip {}
54 | variable ilb02ip {}
55 | variable ilb03ip {}
56 |
57 | # BIGIP Setup
58 | variable licenses {
59 | type = map(string)
60 | default = {
61 | "license1" = ""
62 | "license2" = ""
63 | "license3" = ""
64 | "license4" = ""
65 | }
66 | }
67 |
68 | variable hosts {}
69 | variable dns_server {}
70 | variable ntp_server {}
71 | variable timezone {}
72 | variable onboard_log { default = "/var/log/startup-script.log" }
73 | variable asm_policy {}
74 |
75 | # TAGS
76 | variable tags {}
77 |
--------------------------------------------------------------------------------
/three_tier/ips/ips.tf:
--------------------------------------------------------------------------------
1 | resource "random_id" "randomId" {
2 | keepers = {
3 | # Generate a new ID only when a new resource group is defined
4 | resource_group = var.resourceGroup.name
5 | }
6 | byte_length = 8
7 | }
8 |
9 | # # Create a Public IP for the Virtual Machines
10 | # resource azurerm_public_ip ipspip01 {
11 | # name = "${var.prefix}-ips-mgmt-pip01-delete-me"
12 | # location = var.resourceGroup.location
13 | # resource_group_name = var.resourceGroup.name
14 | # allocation_method = "Static"
15 | # sku = "Standard"
16 |
17 | # tags = {
18 | # Name = "${var.prefix}-ips-public-ip"
19 | # }
20 | # }
21 |
22 | resource "azurerm_storage_account" "ips_storageaccount" {
23 | name = "diag${random_id.randomId.hex}"
24 | resource_group_name = var.resourceGroup.name
25 | location = var.resourceGroup.location
26 | account_replication_type = "LRS"
27 | account_tier = "Standard"
28 |
29 | tags = var.tags
30 | }
31 |
32 | resource "azurerm_network_interface" "ips01-mgmt-nic" {
33 | name = "${var.prefix}-ips01-mgmt-nic"
34 | location = var.resourceGroup.location
35 | resource_group_name = var.resourceGroup.name
36 |
37 | enable_accelerated_networking = true
38 | enable_ip_forwarding = true
39 |
40 | ip_configuration {
41 | name = "primary"
42 | subnet_id = var.subnetMgmt.id
43 | private_ip_address_allocation = "Static"
44 | private_ip_address = var.ips01mgmt
45 | primary = true
46 | #public_ip_address_id = azurerm_public_ip.ipspip01.id
47 | }
48 |
49 | tags = var.tags
50 | }
51 |
52 | resource "azurerm_network_interface_backend_address_pool_association" "mpool_assc_ips01" {
53 | network_interface_id = azurerm_network_interface.ips01-mgmt-nic.id
54 | ip_configuration_name = "primary"
55 | backend_address_pool_id = var.primaryPool.id
56 | }
57 |
58 | resource "azurerm_network_interface" "ips01-ext-nic" {
59 | name = "${var.prefix}-ips01-ext-nic"
60 | location = var.resourceGroup.location
61 | resource_group_name = var.resourceGroup.name
62 |
63 | enable_accelerated_networking = true
64 | enable_ip_forwarding = true
65 |
66 | ip_configuration {
67 | name = "primary"
68 | subnet_id = var.subnetInspectExt.id
69 | private_ip_address_allocation = "Static"
70 | private_ip_address = var.ips01ext
71 | primary = true
72 | }
73 |
74 | tags = var.tags
75 | }
76 |
77 | # internal network interface for ips vm
78 | resource "azurerm_network_interface" "ips01-int-nic" {
79 | name = "${var.prefix}-ips01-int-nic"
80 | location = var.resourceGroup.location
81 | resource_group_name = var.resourceGroup.name
82 |
83 | enable_accelerated_networking = true
84 | enable_ip_forwarding = true
85 |
86 | ip_configuration {
87 | name = "primary"
88 | subnet_id = var.subnetInspectInt.id
89 | private_ip_address_allocation = "Static"
90 | private_ip_address = var.ips01int
91 | primary = true
92 | }
93 |
94 | tags = var.tags
95 | }
96 |
97 | # Associate the External Network Interface to the BackendPool
98 | resource "azurerm_network_interface_backend_address_pool_association" "ips_pool_assc_ingress" {
99 | network_interface_id = azurerm_network_interface.ips01-ext-nic.id
100 | ip_configuration_name = "primary"
101 | backend_address_pool_id = var.ipsIngressPool.id
102 | }
103 |
104 | resource "azurerm_network_interface_backend_address_pool_association" "ips_pool_assc_egress" {
105 | network_interface_id = azurerm_network_interface.ips01-int-nic.id
106 | ip_configuration_name = "primary"
107 | backend_address_pool_id = var.ipsEgressPool.id
108 | }
109 |
110 | # network interface for ips vm
111 | resource "azurerm_network_interface_security_group_association" "ips-ext-nsg" {
112 | network_interface_id = azurerm_network_interface.ips01-ext-nic.id
113 | network_security_group_id = var.securityGroup.id
114 | }
115 | # network interface for ips vm
116 | resource "azurerm_network_interface_security_group_association" "ips-int-nsg" {
117 | network_interface_id = azurerm_network_interface.ips01-int-nic.id
118 | network_security_group_id = var.securityGroup.id
119 | }
120 | # network interface for ips vm
121 | resource "azurerm_network_interface_security_group_association" "ips-mgmt-nsg" {
122 | network_interface_id = azurerm_network_interface.ips01-mgmt-nic.id
123 | network_security_group_id = var.securityGroup.id
124 | }
125 |
126 | # set up proxy config
127 |
128 | # Obtain Gateway IP for each Subnet
129 | locals {
130 | depends_on = [var.subnetMgmt, var.internalSubnet, var.wafSubnet]
131 | mgmt_gw = cidrhost(var.subnets["management"], 1)
132 | int_gw = cidrhost(var.subnets["internal"], 1)
133 | int_mask = cidrnetmask(var.subnets["internal"])
134 | extInspectGw = cidrhost(var.subnets["inspect_ext"], 1)
135 | intInspectGw = cidrhost(var.subnets["inspect_int"], 1)
136 | waf_ext_gw = cidrhost(var.subnets["waf_ext"], 1)
137 | waf_ext_mask = cidrnetmask(var.subnets["waf_ext"])
138 | }
139 |
140 | data "template_file" "vm_onboard" {
141 | template = file("./templates/ips-cloud-init.yaml")
142 | vars = {
143 | #gateway = gateway
144 | internalSubnetPrefix = cidrhost(var.subnets["internal"], 0)
145 | internalMask = local.int_mask
146 | internalGateway = local.extInspectGw
147 | wafSubnetPrefix = cidrhost(var.subnets["waf_ext"], 0)
148 | wafMask = local.waf_ext_mask
149 | wafGateway = local.intInspectGw
150 | log_destination = var.app01ip
151 | }
152 | }
153 |
154 | data "template_cloudinit_config" "config" {
155 | gzip = true
156 | base64_encode = true
157 |
158 | # Main cloud-config configuration file.
159 | part {
160 | filename = "init.cfg"
161 | content_type = "text/cloud-config"
162 | content = data.template_file.vm_onboard.rendered
163 | }
164 | }
165 |
166 | # ips01-VM
167 | resource "azurerm_linux_virtual_machine" "ips01-vm" {
168 | name = "${var.prefix}-ips01-vm"
169 | location = var.resourceGroup.location
170 | resource_group_name = var.resourceGroup.name
171 | depends_on = [azurerm_network_interface_backend_address_pool_association.mpool_assc_ips01]
172 |
173 | network_interface_ids = [azurerm_network_interface.ips01-mgmt-nic.id, azurerm_network_interface.ips01-ext-nic.id, azurerm_network_interface.ips01-int-nic.id]
174 | size = var.instanceType
175 |
176 | admin_username = var.adminUserName
177 | admin_password = var.adminPassword
178 | disable_password_authentication = false
179 | computer_name = "${var.prefix}-ips01-vm"
180 |
181 | os_disk {
182 | caching = "ReadWrite"
183 | storage_account_type = "Premium_LRS"
184 | }
185 |
186 | source_image_reference {
187 | publisher = "Canonical"
188 | offer = "UbuntuServer"
189 | sku = "18.04-LTS"
190 | version = "latest"
191 | }
192 |
193 | custom_data = data.template_cloudinit_config.config.rendered
194 |
195 | boot_diagnostics {
196 | storage_account_uri = azurerm_storage_account.ips_storageaccount.primary_blob_endpoint
197 | }
198 |
199 | tags = var.tags
200 | }
201 |
202 | resource "local_file" "cloud_init_file" {
203 | content = data.template_file.vm_onboard.rendered
204 | filename = "${path.module}/cloud-init.yml"
205 | }
206 |
--------------------------------------------------------------------------------
/three_tier/ips/variables.tf:
--------------------------------------------------------------------------------
1 | # templates directory
2 | variable templates {
3 | default = "/workspace/templates"
4 | }
5 | variable location {}
6 | variable region {}
7 | variable prefix {}
8 | variable resourceGroup {}
9 | variable securityGroup {
10 | default = "none"
11 | }
12 |
13 | variable subnets {}
14 | variable subnetMgmt {}
15 | variable subnetInspectExt {}
16 | variable subnetInspectInt {}
17 | variable internalSubnet {}
18 | variable wafSubnet {}
19 | variable virtual_network_name {}
20 |
21 | variable ips01ext {}
22 | variable ips01int {}
23 | variable ips01mgmt {}
24 | variable app01ip {}
25 | variable adminUserName {}
26 | variable adminPassword {}
27 |
28 | variable ipsIngressPool {}
29 | variable ipsEgressPool {}
30 | variable primaryPool {}
31 |
32 | # device
33 | variable instanceType {}
34 |
35 | # TAGS
36 | variable tags {}
37 |
38 | variable timezone {}
39 |
--------------------------------------------------------------------------------
/three_tier/waf/bigip.tf:
--------------------------------------------------------------------------------
1 | # # Create a Public IP for the Virtual Machines
2 | # resource azurerm_public_ip f5vmpip03 {
3 | # name = "${var.prefix}-vm03-mgmt-pip03-delete-me"
4 | # location = var.resourceGroup.location
5 | # resource_group_name = var.resourceGroup.name
6 | # allocation_method = "Static"
7 | # sku = "Standard"
8 |
9 | # tags = {
10 | # Name = "${var.prefix}-f5vm-public-ip"
11 | # }
12 | # }
13 | # resource azurerm_public_ip f5vmpip04 {
14 | # name = "${var.prefix}-vm04-mgmt-pip04-delete-me"
15 | # location = var.resourceGroup.location
16 | # resource_group_name = var.resourceGroup.name
17 | # allocation_method = "Static"
18 | # sku = "Standard"
19 |
20 | # tags = {
21 | # Name = "${var.prefix}-f5vm-public-ip"
22 | # }
23 | # }
24 |
25 | # Obtain Gateway IP for each Subnet
26 | locals {
27 | depends_on = [var.subnetMgmt, var.subnetWafExt, var.subnetWafInt]
28 | mgmt_gw = cidrhost(var.subnets["management"], 1)
29 | waf_ext_gw = cidrhost(var.subnets["waf_ext"], 1)
30 | waf_int_gw = cidrhost(var.subnets["waf_int"], 1)
31 | }
32 |
33 | # Create the first network interface card for Management
34 | resource "azurerm_network_interface" "vm03-mgmt-nic" {
35 | name = "${var.prefix}-vm03-mgmt-nic"
36 | location = var.resourceGroup.location
37 | resource_group_name = var.resourceGroup.name
38 |
39 | ip_configuration {
40 | name = "primary"
41 | subnet_id = var.subnetMgmt.id
42 | private_ip_address_allocation = "Static"
43 | private_ip_address = var.f5_mgmt["f5vm03mgmt"]
44 | #public_ip_address_id = azurerm_public_ip.f5vmpip03.id
45 | }
46 |
47 | tags = var.tags
48 | }
49 |
50 | resource "azurerm_network_interface" "vm04-mgmt-nic" {
51 | name = "${var.prefix}-vm04-mgmt-nic"
52 | location = var.resourceGroup.location
53 | resource_group_name = var.resourceGroup.name
54 |
55 | ip_configuration {
56 | name = "primary"
57 | subnet_id = var.subnetMgmt.id
58 | private_ip_address_allocation = "Static"
59 | private_ip_address = var.f5_mgmt["f5vm04mgmt"]
60 | #public_ip_address_id = azurerm_public_ip.f5vmpip04.id
61 | }
62 |
63 | tags = var.tags
64 | }
65 |
66 | resource "azurerm_network_interface_security_group_association" "bigip03-mgmt-nsg" {
67 | network_interface_id = azurerm_network_interface.vm03-mgmt-nic.id
68 | network_security_group_id = var.securityGroup.id
69 | }
70 |
71 | resource "azurerm_network_interface_security_group_association" "bigip04-mgmt-nsg" {
72 | network_interface_id = azurerm_network_interface.vm04-mgmt-nic.id
73 | network_security_group_id = var.securityGroup.id
74 | }
75 |
76 | # Associate the Network Interface to the ManagementPool
77 | resource "azurerm_network_interface_backend_address_pool_association" "mpool_assc_vm01" {
78 | network_interface_id = azurerm_network_interface.vm03-mgmt-nic.id
79 | ip_configuration_name = "primary"
80 | #backend_address_pool_id = var.managementPool.id
81 | backend_address_pool_id = var.primaryPool.id
82 | }
83 | # Associate the Network Interface to the ManagementPool
84 | resource "azurerm_network_interface_backend_address_pool_association" "mpool_assc_vm02" {
85 | network_interface_id = azurerm_network_interface.vm04-mgmt-nic.id
86 | ip_configuration_name = "primary"
87 | #backend_address_pool_id = var.managementPool.id
88 | backend_address_pool_id = var.primaryPool.id
89 | }
90 |
91 | # Create the second network interface card for External
92 | resource "azurerm_network_interface" "vm03-ext-nic" {
93 | name = "${var.prefix}-vm03-ext-nic"
94 | location = var.resourceGroup.location
95 | resource_group_name = var.resourceGroup.name
96 | enable_ip_forwarding = true
97 | enable_accelerated_networking = var.bigip_version == "latest" ? true : false
98 |
99 | ip_configuration {
100 | name = "primary"
101 | subnet_id = var.subnetWafExt[0].id
102 | private_ip_address_allocation = "Static"
103 | private_ip_address = var.f5_t3_ext["f5vm03ext"]
104 | primary = true
105 | }
106 |
107 | ip_configuration {
108 | name = "secondary"
109 | subnet_id = var.subnetWafExt[0].id
110 | private_ip_address_allocation = "Static"
111 | private_ip_address = var.f5_t3_ext["f5vm03ext_sec"]
112 | }
113 |
114 | tags = {
115 | Name = "${var.prefix}-vm03-ext-int"
116 | environment = var.tags["environment"]
117 | owner = var.tags["owner"]
118 | group = var.tags["group"]
119 | costcenter = var.tags["costcenter"]
120 | application = var.tags["application"]
121 | f5_cloud_failover_label = "saca"
122 | f5_cloud_failover_nic_map = "external"
123 | }
124 | }
125 |
126 | resource "azurerm_network_interface_security_group_association" "bigip03-ext-nsg" {
127 | network_interface_id = azurerm_network_interface.vm03-ext-nic.id
128 | network_security_group_id = var.securityGroup.id
129 | }
130 |
131 | resource "azurerm_network_interface" "vm04-ext-nic" {
132 | name = "${var.prefix}-vm04-ext-nic"
133 | location = var.resourceGroup.location
134 | resource_group_name = var.resourceGroup.name
135 | enable_ip_forwarding = true
136 | enable_accelerated_networking = var.bigip_version == "latest" ? true : false
137 |
138 | ip_configuration {
139 | name = "primary"
140 | subnet_id = var.subnetWafExt[0].id
141 | private_ip_address_allocation = "Static"
142 | private_ip_address = var.f5_t3_ext["f5vm04ext"]
143 | primary = true
144 | }
145 |
146 | ip_configuration {
147 | name = "secondary"
148 | subnet_id = var.subnetWafExt[0].id
149 | private_ip_address_allocation = "Static"
150 | private_ip_address = var.f5_t3_ext["f5vm04ext_sec"]
151 | }
152 |
153 | tags = {
154 | Name = "${var.prefix}-vm03-ext-int"
155 | environment = var.tags["environment"]
156 | owner = var.tags["owner"]
157 | group = var.tags["group"]
158 | costcenter = var.tags["costcenter"]
159 | application = var.tags["application"]
160 | f5_cloud_failover_label = "saca"
161 | f5_cloud_failover_nic_map = "external"
162 | }
163 | }
164 |
165 | resource "azurerm_network_interface_security_group_association" "bigip04-ext-nsg" {
166 | network_interface_id = azurerm_network_interface.vm04-ext-nic.id
167 | network_security_group_id = var.securityGroup.id
168 | }
169 |
170 | # Associate the External Network Interfaces to the Waf Backend Pools
171 | resource "azurerm_network_interface_backend_address_pool_association" "bpool_assc_vm01" {
172 | network_interface_id = azurerm_network_interface.vm03-ext-nic.id
173 | ip_configuration_name = "secondary"
174 | backend_address_pool_id = var.wafIngressPool.id
175 | }
176 |
177 | resource "azurerm_network_interface_backend_address_pool_association" "bpool_assc_vm02" {
178 | network_interface_id = azurerm_network_interface.vm04-ext-nic.id
179 | ip_configuration_name = "secondary"
180 | backend_address_pool_id = var.wafIngressPool.id
181 | }
182 |
183 | # Create the third network interface card for Internal
184 | resource "azurerm_network_interface" "vm03-int-nic" {
185 | name = "${var.prefix}-vm03-int-nic"
186 | location = var.resourceGroup.location
187 | resource_group_name = var.resourceGroup.name
188 | enable_ip_forwarding = true
189 | enable_accelerated_networking = var.bigip_version == "latest" ? true : false
190 |
191 | ip_configuration {
192 | name = "primary"
193 | subnet_id = var.subnetWafInt[0].id
194 | private_ip_address_allocation = "Static"
195 | private_ip_address = var.f5_t3_int["f5vm03int"]
196 | primary = true
197 | }
198 | tags = var.tags
199 | }
200 |
201 | resource "azurerm_network_interface_security_group_association" "bigip03-int-nsg" {
202 | network_interface_id = azurerm_network_interface.vm03-int-nic.id
203 | network_security_group_id = var.securityGroup.id
204 | }
205 |
206 | resource "azurerm_network_interface" "vm04-int-nic" {
207 | name = "${var.prefix}-vm04-int-nic"
208 | location = var.resourceGroup.location
209 | resource_group_name = var.resourceGroup.name
210 | enable_ip_forwarding = true
211 | enable_accelerated_networking = var.bigip_version == "latest" ? true : false
212 |
213 | ip_configuration {
214 | name = "primary"
215 | subnet_id = var.subnetWafInt[0].id
216 | private_ip_address_allocation = "Static"
217 | private_ip_address = var.f5_t3_int["f5vm04int"]
218 | primary = true
219 | }
220 |
221 | tags = var.tags
222 | }
223 |
224 | resource "azurerm_network_interface_security_group_association" "bigip04-int-nsg" {
225 | network_interface_id = azurerm_network_interface.vm04-int-nic.id
226 | network_security_group_id = var.securityGroup.id
227 | }
228 |
229 | # Create F5 BIGIP VMs
230 | resource "azurerm_virtual_machine" "f5vm03" {
231 | name = "${var.prefix}-f5vm03"
232 | location = var.resourceGroup.location
233 | resource_group_name = var.resourceGroup.name
234 | primary_network_interface_id = azurerm_network_interface.vm03-mgmt-nic.id
235 | network_interface_ids = [azurerm_network_interface.vm03-mgmt-nic.id, azurerm_network_interface.vm03-ext-nic.id, azurerm_network_interface.vm03-int-nic.id]
236 | vm_size = var.instanceType
237 | availability_set_id = var.availabilitySet.id
238 |
239 | delete_os_disk_on_termination = true
240 | delete_data_disks_on_termination = true
241 |
242 | storage_image_reference {
243 | publisher = "f5-networks"
244 | offer = var.product
245 | sku = var.image_name
246 | version = var.bigip_version
247 | }
248 |
249 | storage_os_disk {
250 | name = "${var.prefix}-vm03-osdisk"
251 | caching = "ReadWrite"
252 | create_option = "FromImage"
253 | managed_disk_type = "Standard_LRS"
254 | }
255 |
256 | os_profile {
257 | computer_name = "${var.prefix}vm03"
258 | admin_username = var.adminUserName
259 | admin_password = var.adminPassword
260 | }
261 |
262 | os_profile_linux_config {
263 | disable_password_authentication = false
264 | }
265 |
266 | plan {
267 | name = var.image_name
268 | publisher = "f5-networks"
269 | product = var.product
270 | }
271 |
272 | tags = var.tags
273 | }
274 |
275 | resource "azurerm_virtual_machine" "f5vm04" {
276 | name = "${var.prefix}-f5vm04"
277 | location = var.resourceGroup.location
278 | resource_group_name = var.resourceGroup.name
279 | primary_network_interface_id = azurerm_network_interface.vm04-mgmt-nic.id
280 | network_interface_ids = [azurerm_network_interface.vm04-mgmt-nic.id, azurerm_network_interface.vm04-ext-nic.id, azurerm_network_interface.vm04-int-nic.id]
281 | vm_size = var.instanceType
282 | availability_set_id = var.availabilitySet.id
283 |
284 | delete_os_disk_on_termination = true
285 | delete_data_disks_on_termination = true
286 |
287 | storage_image_reference {
288 | publisher = "f5-networks"
289 | offer = var.product
290 | sku = var.image_name
291 | version = var.bigip_version
292 | }
293 |
294 | storage_os_disk {
295 | name = "${var.prefix}-vm04-osdisk"
296 | caching = "ReadWrite"
297 | create_option = "FromImage"
298 | managed_disk_type = "Standard_LRS"
299 | }
300 |
301 | os_profile {
302 | computer_name = "${var.prefix}vm04"
303 | admin_username = var.adminUserName
304 | admin_password = var.adminPassword
305 | }
306 |
307 | os_profile_linux_config {
308 | disable_password_authentication = false
309 | }
310 |
311 | plan {
312 | name = var.image_name
313 | publisher = "f5-networks"
314 | product = var.product
315 | }
316 |
317 | tags = var.tags
318 | }
319 |
320 | # Setup Onboarding scripts
321 |
322 | data "template_file" "vm_onboard" {
323 | template = file("./templates/onboard.tpl")
324 | vars = {
325 | uname = var.adminUserName
326 | upassword = var.adminPassword
327 | doVersion = "latest"
328 | as3Version = "latest"
329 | tsVersion = "latest"
330 | cfVersion = "latest"
331 | fastVersion = "1.0.0"
332 | doExternalDeclarationUrl = "https://example.domain.com/do.json"
333 | as3ExternalDeclarationUrl = "https://example.domain.com/as3.json"
334 | tsExternalDeclarationUrl = "https://example.domain.com/ts.json"
335 | cfExternalDeclarationUrl = "https://example.domain.com/cf.json"
336 | onboard_log = var.onboard_log
337 | mgmtGateway = local.mgmt_gw
338 | DO1_Document = data.template_file.vm03_do_json.rendered
339 | DO2_Document = data.template_file.vm04_do_json.rendered
340 | AS3_Document = data.template_file.as3_json.rendered
341 | }
342 | }
343 |
344 | # as3 uuid generation
345 | resource "random_uuid" "as3_uuid" {}
346 |
347 | data "http" "onboard" {
348 | url = "https://raw.githubusercontent.com/Mikej81/f5-bigip-hardening-DO/master/dist/terraform/latest/${var.licenses["license3"] != "" ? "byol" : "payg"}_cluster_waf_tier.json"
349 | }
350 |
351 | data "template_file" "vm03_do_json" {
352 | template = data.http.onboard.body
353 | vars = {
354 | host1 = var.hosts["host3"]
355 | host2 = var.hosts["host4"]
356 | local_host = var.hosts["host3"]
357 | external_selfip = "${var.f5_t3_ext["f5vm03ext"]}/${element(split("/", var.subnets["waf_ext"]), 1)}"
358 | internal_selfip = "${var.f5_t3_int["f5vm03int"]}/${element(split("/", var.subnets["waf_int"]), 1)}"
359 | log_localip = var.f5_t3_ext["f5vm03ext"]
360 | log_destination = var.app01ip
361 | vdmsSubnet = var.subnets["vdms"]
362 | appSubnet = var.subnets["application"]
363 | vnetSubnet = var.cidr
364 | remote_host = var.hosts["host4"]
365 | remote_selfip = var.f5_t3_ext["f5vm04ext"]
366 | externalGateway = local.waf_ext_gw
367 | internalGateway = local.waf_int_gw
368 | mgmtGateway = local.mgmt_gw
369 | dns_server = var.dns_server
370 | ntp_server = var.ntp_server
371 | timezone = var.timezone
372 | admin_user = var.adminUserName
373 | admin_password = var.adminPassword
374 | license = var.licenses["license3"] != "" ? var.licenses["license3"] : ""
375 | }
376 | }
377 |
378 | data "template_file" "vm04_do_json" {
379 | template = data.http.onboard.body
380 | vars = {
381 | host1 = var.hosts["host3"]
382 | host2 = var.hosts["host4"]
383 | local_host = var.hosts["host4"]
384 | external_selfip = "${var.f5_t3_ext["f5vm04ext"]}/${element(split("/", var.subnets["waf_ext"]), 1)}"
385 | internal_selfip = "${var.f5_t3_int["f5vm04int"]}/${element(split("/", var.subnets["waf_int"]), 1)}"
386 | log_localip = var.f5_t3_ext["f5vm04ext"]
387 | log_destination = var.app01ip
388 | vdmsSubnet = var.subnets["vdms"]
389 | appSubnet = var.subnets["application"]
390 | vnetSubnet = var.cidr
391 | remote_host = var.hosts["host3"]
392 | remote_selfip = var.f5_t3_ext["f5vm03ext"]
393 | externalGateway = local.waf_ext_gw
394 | internalGateway = local.waf_int_gw
395 | mgmtGateway = local.mgmt_gw
396 | dns_server = var.dns_server
397 | ntp_server = var.ntp_server
398 | timezone = var.timezone
399 | admin_user = var.adminUserName
400 | admin_password = var.adminPassword
401 | license = var.licenses["license4"] != "" ? var.licenses["license4"] : ""
402 | }
403 | }
404 |
405 | data "http" "appservice" {
406 | url = "https://raw.githubusercontent.com/Mikej81/f5-bigip-hardening-AS3/master/dist/terraform/latest/sccaWAFTier.json"
407 | }
408 |
409 | data "template_file" "as3_json" {
410 | template = data.http.appservice.body
411 | vars = {
412 | uuid = random_uuid.as3_uuid.result
413 | baseline_waf_policy = var.asm_policy
414 | exampleVipAddress = var.f5_t3_ext["f5vm03ext"]
415 | exampleVipSubnet = var.subnets["waf_ext"]
416 | ips_pool_addresses = var.app01ip
417 | rdp_pool_addresses = var.winjumpip
418 | ssh_pool_addresses = var.linuxjumpip
419 | app_pool_addresses = var.app01ip
420 | log_destination = var.app01ip
421 | mgmtVipAddress = var.f5_t3_ext["f5vm03ext_sec"]
422 | mgmtVipAddress2 = var.f5_t3_ext["f5vm04ext_sec"]
423 | transitVipAddress = var.f5_t3_int["f5vm03int_sec"]
424 | transitVipAddress2 = var.f5_t3_int["f5vm04int_sec"]
425 | }
426 | }
427 |
428 | # Run Startup Script
429 | resource "azurerm_virtual_machine_extension" "f5vm03-run-startup-cmd" {
430 | name = "${var.prefix}-f5vm03-run-startup-cmd"
431 | depends_on = [azurerm_virtual_machine.f5vm03, azurerm_network_interface_backend_address_pool_association.mpool_assc_vm01, azurerm_network_interface_backend_address_pool_association.mpool_assc_vm02]
432 | virtual_machine_id = azurerm_virtual_machine.f5vm03.id
433 | publisher = "Microsoft.Azure.Extensions"
434 | type = "CustomScript"
435 | type_handler_version = "2.0"
436 |
437 | settings = <> ./startup.b64 && cat ./startup.b64 | base64 -d >> ./startup-temp.sh && sed -e 's/\r$//' ./startup-temp.sh > ./startup-script.sh && chmod +x ./startup-script.sh && rm ./startup.b64 && bash ./startup-script.sh 1"
440 | }
441 | SETTINGS
442 |
443 | tags = var.tags
444 | }
445 |
446 | resource "azurerm_virtual_machine_extension" "f5vm04-run-startup-cmd" {
447 | name = "${var.prefix}-f5vm04-run-startup-cmd"
448 | depends_on = [azurerm_virtual_machine.f5vm03, azurerm_virtual_machine.f5vm04, azurerm_network_interface_backend_address_pool_association.mpool_assc_vm01, azurerm_network_interface_backend_address_pool_association.mpool_assc_vm02]
449 | virtual_machine_id = azurerm_virtual_machine.f5vm04.id
450 | publisher = "Microsoft.Azure.Extensions"
451 | type = "CustomScript"
452 | type_handler_version = "2.0"
453 |
454 | settings = <> ./startup.b64 && cat ./startup.b64 | base64 -d >> ./startup-temp.sh && sed -e 's/\r$//g' ./startup-temp.sh > ./startup-script.sh && chmod +x ./startup-script.sh && rm ./startup.b64 && bash ./startup-script.sh 2"
457 | }
458 | SETTINGS
459 |
460 | tags = var.tags
461 | }
462 |
463 |
464 | # Debug Template Outputs
465 | resource "local_file" "vm03_do_file" {
466 | content = data.template_file.vm03_do_json.rendered
467 | filename = "${path.module}/vm03_do_data.json"
468 | }
469 |
470 | resource "local_file" "vm04_do_file" {
471 | content = data.template_file.vm04_do_json.rendered
472 | filename = "${path.module}/vm04_do_data.json"
473 | }
474 |
475 | resource "local_file" "vm_as3_file" {
476 | content = data.template_file.as3_json.rendered
477 | filename = "${path.module}/vm_as3_data.json"
478 | }
479 |
480 | resource "local_file" "onboard_file" {
481 | content = data.template_file.vm_onboard.rendered
482 | filename = "${path.module}/onboard.sh"
483 | }
484 |
--------------------------------------------------------------------------------
/three_tier/waf/outputs.tf:
--------------------------------------------------------------------------------
1 | # data azurerm_public_ip f5vmpip03 {
2 | # name = azurerm_public_ip.f5vmpip03.name
3 | # resource_group_name = var.resourceGroup.name
4 | # depends_on = [azurerm_public_ip.f5vmpip03, azurerm_virtual_machine.f5vm03]
5 | # }
6 | # data azurerm_public_ip f5vmpip04 {
7 | # name = azurerm_public_ip.f5vmpip04.name
8 | # resource_group_name = var.resourceGroup.name
9 | # depends_on = [azurerm_public_ip.f5vmpip04, azurerm_virtual_machine.f5vm04]
10 | # }
11 |
12 |
13 | output f5vm03_id { value = azurerm_virtual_machine.f5vm03.id }
14 | output f5vm03_mgmt_private_ip { value = azurerm_network_interface.vm03-mgmt-nic.private_ip_address }
15 | #output f5vm03_mgmt_public_ip { value = data.azurerm_public_ip.f5vmpip03.ip_address }
16 | output f5vm03_ext_private_ip { value = azurerm_network_interface.vm03-ext-nic.private_ip_address }
17 |
18 | output f5vm04_id { value = azurerm_virtual_machine.f5vm04.id }
19 | output f5vm04_mgmt_private_ip { value = azurerm_network_interface.vm04-mgmt-nic.private_ip_address }
20 | #output f5vm04_mgmt_public_ip { value = data.azurerm_public_ip.f5vmpip04.ip_address }
21 | output f5vm04_ext_private_ip { value = azurerm_network_interface.vm04-ext-nic.private_ip_address }
22 |
--------------------------------------------------------------------------------
/three_tier/waf/variables.tf:
--------------------------------------------------------------------------------
1 | variable resourceGroup {
2 | default = ""
3 | }
4 | # admin credentials
5 | variable adminUserName { default = "" }
6 | variable adminPassword { default = "" }
7 | variable sshPublicKey { default = "" }
8 | # cloud info
9 | variable location {}
10 | variable region {}
11 | variable securityGroup {}
12 | variable availabilitySet {}
13 | variable availabilitySet2 {}
14 |
15 | variable prefix {}
16 | # bigip network
17 | variable subnets {}
18 | variable subnetMgmt {}
19 | variable subnetExternal {}
20 | variable subnetInternal {}
21 | variable subnetWafExt {}
22 | variable subnetWafInt {}
23 | variable app01ip {}
24 | variable backendPool {
25 | description = "azureLB resource pool"
26 | }
27 | variable primaryPool {}
28 | variable managementPool {}
29 | variable wafEgressPool {}
30 | variable wafIngressPool {}
31 |
32 | variable ilb02ip {}
33 |
34 | # bigip networks
35 | variable f5_mgmt {}
36 | variable f5_t1_ext {}
37 | variable f5_t1_int {}
38 | variable f5_t3_ext {}
39 | variable f5_t3_int {}
40 |
41 | # winjump
42 | variable winjumpip {}
43 |
44 | # linuxjump
45 | variable linuxjumpip {}
46 |
47 | # device
48 | variable instanceType {}
49 |
50 |
51 | # BIGIP Image
52 | variable image_name {}
53 | variable product {}
54 | variable bigip_version {}
55 |
56 | variable vnet {}
57 |
58 | # BIGIP Setup
59 | variable hosts {}
60 | variable cidr {}
61 | variable licenses {
62 | type = map(string)
63 | default = {
64 | "license1" = ""
65 | "license2" = ""
66 | "license3" = ""
67 | "license4" = ""
68 | }
69 | }
70 |
71 | variable dns_server {}
72 | variable ntp_server {}
73 | variable timezone { default = "UTC" }
74 | variable onboard_log { default = "/var/log/startup-script.log" }
75 | ## ASM Policy
76 | ## -Examples: https://github.com/f5devcentral/f5-asm-policy-templates
77 | ## -Default is using OWASP Ready Autotuning
78 | variable asm_policy {}
79 |
80 | # TAGS
81 | variable tags {}
82 |
--------------------------------------------------------------------------------
/variables.tf:
--------------------------------------------------------------------------------
1 | # Azure Environment
2 | variable projectPrefix {
3 | type = string
4 | description = "REQUIRED: Prefix to prepend to all objects created, minus Windows Jumpbox"
5 | default = "ccbad9e7"
6 | }
7 | variable adminUserName {
8 | type = string
9 | description = "REQUIRED: Admin Username for All systems"
10 | default = "xadmin"
11 | }
12 | variable adminPassword {
13 | type = string
14 | description = "REQUIRED: Admin Password for all systems"
15 | default = "pleaseUseVault123!!"
16 | }
17 | variable location {
18 | type = string
19 | description = "REQUIRED: Azure Region: usgovvirginia, usgovarizona, etc. For a list of available locations for your subscription use `az account list-locations -o table`"
20 | default = "usgovvirginia"
21 | }
22 | variable region {
23 | type = string
24 | description = "Azure Region: US Gov Virginia, US Gov Arizona, etc"
25 | default = "US Gov Virginia"
26 | }
27 | variable deploymentType {
28 | type = string
29 | description = "REQUIRED: This determines the type of deployment; one tier versus three tier: one_tier, three_tier"
30 | default = "three_tier"
31 | }
32 | variable deployDemoApp {
33 | type = string
34 | description = "OPTIONAL: Deploy Demo Application with Stack. Recommended to show functionality. Options: deploy, anything else."
35 | default = "deploy"
36 | }
37 | variable sshPublicKey {
38 | type = string
39 | description = "OPTIONAL: ssh public key for instances"
40 | default = ""
41 | }
42 | variable sshPublicKeyPath {
43 | type = string
44 | description = "OPTIONAL: ssh public key path for instances"
45 | default = "/mykey.pub"
46 | }
47 |
48 | # NETWORK
49 | variable cidr {
50 | description = "REQUIRED: VNET Network CIDR"
51 | default = "10.90.0.0/16"
52 | }
53 |
54 | variable subnets {
55 | type = map(string)
56 | description = "REQUIRED: Subnet CIDRs"
57 | default = {
58 | "management" = "10.90.0.0/24"
59 | "external" = "10.90.1.0/24"
60 | "internal" = "10.90.2.0/24"
61 | "vdms" = "10.90.3.0/24"
62 | "inspect_ext" = "10.90.4.0/24"
63 | "inspect_int" = "10.90.5.0/24"
64 | "waf_ext" = "10.90.6.0/24"
65 | "waf_int" = "10.90.7.0/24"
66 | "application" = "10.90.10.0/24"
67 | }
68 | }
69 |
70 | variable f5_mgmt {
71 | description = "F5 BIG-IP Management IPs. These must be in the management subnet."
72 | type = map(string)
73 | default = {
74 | f5vm01mgmt = "10.90.0.4"
75 | f5vm02mgmt = "10.90.0.5"
76 | f5vm03mgmt = "10.90.0.6"
77 | f5vm04mgmt = "10.90.0.7"
78 | }
79 | }
80 |
81 | # bigip external private ips, these must be in external subnet
82 | variable f5_t1_ext {
83 | description = "Tier 1 BIG-IP External IPs. These must be in the external subnet."
84 | type = map(string)
85 | default = {
86 | f5vm01ext = "10.90.1.4"
87 | f5vm01ext_sec = "10.90.1.11"
88 | f5vm02ext = "10.90.1.5"
89 | f5vm02ext_sec = "10.90.1.12"
90 | }
91 | }
92 |
93 | variable f5_t1_int {
94 | description = "Tier 1 BIG-IP Internal IPs. These must be in the internal subnet."
95 | type = map(string)
96 | default = {
97 | f5vm01int = "10.90.2.4"
98 | f5vm01int_sec = "10.90.2.11"
99 | f5vm02int = "10.90.2.5"
100 | f5vm02int_sec = "10.90.2.12"
101 | }
102 | }
103 |
104 | variable f5_t3_ext {
105 | description = "Tier 3 BIG-IP External IPs. These must be in the waf external subnet."
106 | type = map(string)
107 | default = {
108 | f5vm03ext = "10.90.6.4"
109 | f5vm03ext_sec = "10.90.6.11"
110 | f5vm04ext = "10.90.6.5"
111 | f5vm04ext_sec = "10.90.6.12"
112 | }
113 | }
114 |
115 | variable f5_t3_int {
116 | description = "Tier 3 BIG-IP Internal IPs. These must be in the waf internal subnet."
117 | type = map(string)
118 | default = {
119 | f5vm03int = "10.90.7.4"
120 | f5vm03int_sec = "10.90.7.11"
121 | f5vm04int = "10.90.7.5"
122 | f5vm04int_sec = "10.90.7.12"
123 | }
124 | }
125 |
126 | variable internalILBIPs {
127 | description = "REQUIRED: Used by One and Three Tier. Azure internal load balancer ips, these are used for ingress and egress."
128 | type = map(string)
129 | default = {}
130 | }
131 |
132 | variable ilb01ip {
133 | type = string
134 | description = "REQUIRED: Used by One and Three Tier. Azure internal load balancer ip, this is used as egress, must be in internal subnet."
135 | default = "10.90.2.10"
136 | }
137 |
138 | variable ilb02ip {
139 | type = string
140 | description = "REQUIRED: Used by Three Tier only. Azure waf external load balancer ip, this is used as egress, must be in waf_ext subnet."
141 | default = "10.90.6.10"
142 | }
143 |
144 | variable ilb03ip {
145 | type = string
146 | description = "REQUIRED: Used by Three Tier only. Azure waf external load balancer ip, this is used as ingress, must be in waf_ext subnet."
147 | default = "10.90.6.13"
148 | }
149 |
150 | variable ilb04ip {
151 | type = string
152 | description = "REQUIRED: Used by Three Tier only. Azure waf external load balancer ip, this is used as ingress, must be in inspect_external subnet."
153 | default = "10.90.4.13"
154 | }
155 |
156 | variable app01ip {
157 | type = string
158 | description = "OPTIONAL: Example Application used by all use-cases to demonstrate functionality of deploymeny, must reside in the application subnet."
159 | default = "10.90.10.101"
160 | }
161 |
162 | # Example IPS private ips
163 | variable ips01ext { default = "10.90.4.4" }
164 | variable ips01int { default = "10.90.5.4" }
165 | variable ips01mgmt { default = "10.90.0.8" }
166 |
167 | variable winjumpip {
168 | type = string
169 | description = "REQUIRED: Used by all use-cases for RDP/Windows Jumpbox, must reside in VDMS subnet."
170 | default = "10.90.3.98"
171 | }
172 |
173 | variable linuxjumpip {
174 | type = string
175 | description = "REQUIRED: Used by all use-cases for SSH/Linux Jumpbox, must reside in VDMS subnet."
176 | default = "10.90.3.99"
177 | }
178 |
179 | # BIGIP Instance Type, DS5_v2 is a solid baseline for BEST
180 | variable instanceType { default = "Standard_DS5_v2" }
181 |
182 | # Be careful which instance type selected, jump boxes currently use Premium_LRS managed disks
183 | variable jumpinstanceType { default = "Standard_B2s" }
184 |
185 | # Demo Application Instance Size
186 | variable appInstanceType { default = "Standard_DS3_v2" }
187 |
188 | # BIGIP Image
189 | variable image_name {
190 | type = string
191 | description = "REQUIRED: BIG-IP Image Name. 'az vm image list --output table --publisher f5-networks --location [region] --offer f5-big-ip --all' Default f5-bigip-virtual-edition-1g-best-hourly is PAYG Image. For BYOL use f5-big-all-2slot-byol"
192 | default = "f5-bigip-virtual-edition-1g-best-hourly"
193 | }
194 | variable product {
195 | type = string
196 | description = "REQUIRED: BYOL = f5-big-ip-byol, PAYG = f5-big-ip-best"
197 | default = "f5-big-ip-best"
198 | }
199 | variable bigip_version {
200 | type = string
201 | description = "REQUIRED: BIG-IP Version. Note: verify available versions before using as images can change."
202 | default = "14.1.400000"
203 | }
204 |
205 | # BIGIP Setup
206 | # Licenses are only needed when using BYOL images
207 | variable licenses {
208 | type = map(string)
209 | default = {
210 | "license1" = ""
211 | "license2" = ""
212 | "license3" = ""
213 | "license4" = ""
214 | }
215 | }
216 |
217 | variable hosts {
218 | type = map(string)
219 | default = {
220 | "host1" = "f5vm01"
221 | "host2" = "f5vm02"
222 | "host3" = "f5vm03"
223 | "host4" = "f5vm04"
224 | }
225 | }
226 |
227 | variable dns_server {
228 | type = string
229 | description = "REQUIRED: Default is set to Azure DNS."
230 | default = "168.63.129.16"
231 | }
232 |
233 | ## ASM Policy
234 | variable asm_policy {
235 | type = string
236 | description = "REQUIRED: ASM Policy. Examples: https://github.com/f5devcentral/f5-asm-policy-templates. Default: OWASP Ready Autotuning"
237 | default = "https://raw.githubusercontent.com/f5devcentral/f5-asm-policy-templates/master/owasp_ready_template/owasp-auto-tune-v1.1.xml"
238 | }
239 |
240 | variable ntp_server { default = "time.nist.gov" }
241 | variable timezone { default = "UTC" }
242 | variable onboard_log { default = "/var/log/startup-script.log" }
243 |
244 | # TAGS
245 | variable tags {
246 | description = "Environment tags for objects"
247 | type = map(string)
248 | default = {
249 | "purpose" = "public"
250 | "environment" = "f5env"
251 | "owner" = "f5owner"
252 | "group" = "f5group"
253 | "costcenter" = "f5costcenter"
254 | "application" = "f5app"
255 | }
256 | }
257 |
--------------------------------------------------------------------------------