Compare commits

...

270 Commits

Author SHA1 Message Date
f303bd2b2f Microsoft mandatory file 2022-07-28 16:55:58 +00:00
Gin
40c33d528f Cosmosdb l100 examples (#100) 2022-07-01 17:14:52 +08:00
e0f9c4b8cc Merge pull request #103 from myc2h6o/vm_ade
Add examples for Azure Disk Encryption Extension for VM and VMSS
2022-06-29 15:58:49 -07:00
aac920d615 Merge pull request #102 from myc2h6o/confidential_vm
Add examples for confidential VM, VMSS and OS Disk
2022-06-29 15:56:03 -07:00
191572bc6b resolve comments 2022-06-28 17:23:27 +08:00
e11e21b525 resolve comments 2022-06-28 16:18:31 +08:00
45c260955b Merge pull request #104 from neil-yechenwei/mysqlfsdbfix
Update example link for Mysql FS
2022-06-27 16:24:21 -07:00
7a63c76cec Update example link for Mysql FS 2022-06-23 16:42:04 +08:00
aae3e0fbec Add examples for Azure Disk Encryption Extension 2022-06-22 22:11:55 +08:00
bd01573941 Add examples for confidential VM, VMSS and OS Disk 2022-06-22 18:08:20 +08:00
742b875490 Merge pull request #80 from neil-yechenwei/examplemysqlfsdb
Add example for MySQL Flexible Server Database
2022-04-21 14:21:43 -07:00
5cf7ca9d66 update code 2022-04-14 09:51:49 +08:00
18b79a7eda Merge pull request #78 from mcraiha/typofix
Fix resource TYPOs in variables
2022-04-13 16:35:11 -07:00
ffa78e6b67 Merge pull request #89 from mingweihe/master
fix versions & mlsources to make publicNetworkAccess=Disabled work in…
2022-04-13 15:58:57 -07:00
2978cf215b Merge pull request #97 from Azure/issue_templates
few more minor tweaks to templates
2022-04-13 13:49:35 -07:00
b9b4d29725 few more minor tweaks to templates 2022-04-13 13:49:04 -07:00
8e22a0f19d Merge pull request #96 from Azure/issue_templates
fixed few description issue
2022-04-13 13:43:09 -07:00
a8f6580471 fixed few description issue 2022-04-13 13:42:14 -07:00
88309de25b Merge pull request #95 from Azure/issue_templates
tweaking order of issue templates
2022-04-13 13:39:10 -07:00
b0bd81d8d2 tweaking order of issue templates 2022-04-13 13:38:12 -07:00
dbd45b1065 Merge pull request #94 from Azure/issue_templates
added bug templates for azapi, aztfy, examples and feature template
2022-04-13 13:34:22 -07:00
5d0bc04169 added bug templates for azapi, aztfy, examples and feature template 2022-04-13 13:32:31 -07:00
1d9cfd0aec Merge pull request #93 from Azure/issue_templates
few tweaks to module bug issue
2022-04-12 15:13:27 -07:00
248ca2b267 few tweaks to module bug issue 2022-04-12 15:10:58 -07:00
56b0d864b2 Merge pull request #92 from Azure/issue_templates
Beginning of Issue Forms
2022-04-12 15:00:41 -07:00
d142476be6 Beginning of Issue Forms 2022-04-12 14:59:24 -07:00
2d9a6c5bb6 Merge pull request #91 from Azure/azapi-examples
Removed work around for registering Microsoft.LabServices provider
2022-04-11 18:09:14 -07:00
dc8d94b026 Removed work around for registering Microsoft.LabServices provider 2022-04-11 18:07:24 -07:00
9784b3a2d5 Merge pull request #90 from Azure/azapi-examples
Examples for documentation
2022-04-11 15:18:54 -07:00
3fcccfc376 Examples for documentation for AzAPI provider including resource and update_resource 2022-04-11 15:09:07 -07:00
c644dcdafa Merge pull request #88 from jensheerin/AVD
refactor code
2022-04-11 11:13:46 -07:00
6643221681 fix versions & mlsources to make publicNetworkAccess=Disabled work in the related terraform template 2022-04-04 16:15:08 -07:00
a2399f96b5 fmt 2022-03-28 22:05:53 -04:00
b562c8a2fc format 2022-03-28 21:52:14 -04:00
d0af975d18 refactor code 2022-03-25 14:54:22 -04:00
311ed006e3 update code 2022-03-23 10:28:16 +08:00
64aa77f9f8 Merge pull request #86 from TomArcherMsft/UserStory1929747-code
User Story 1929747
2022-03-15 16:30:18 -07:00
78da765a23 Fixed 'autopilot' mistake of naming file with an MD extension 2022-03-14 16:33:27 -07:00
23a2e2cb73 Added providers.tf file 2022-03-14 15:56:55 -07:00
7c4e2dd434 Merge pull request #79 from vhorne/ag-qs
create app gateway quickstart
2022-03-11 10:32:14 -08:00
9adb4bf7d7 rename file 2022-03-11 06:05:22 -08:00
4950e13207 Merge pull request #83 from TomArcherMsft/UserStory1871520-fix-readme
User Story 1871520 - Fix readme
2022-03-10 10:31:04 -08:00
1ba0df3660 create providers.tf 2022-03-08 08:26:25 -08:00
ac98d2cfbe fixed readme 2022-03-07 11:47:36 -08:00
f4492d47ea Merge pull request #81 from TomArcherMsft/UserStory1871520-2
User Story 1871520 (Code)
2022-03-07 11:15:41 -08:00
744613923a Formatted code via 'terraform fmt' 2022-03-05 14:16:56 -08:00
e4a7a6e1f3 randomized resource group name for resources 2022-03-05 11:52:02 -08:00
742e4c7a5d changed reserved ip addresses 2022-03-05 09:05:17 -08:00
baa2ce42c7 added output of app ip 2022-03-05 08:03:57 -08:00
09f7f93885 creates app i can run 2022-03-04 20:32:36 -08:00
1c548de790 Working on randomizing RG 2022-03-04 15:03:42 -08:00
e7300d5f62 Added quotes around placeholders 2022-03-04 14:39:52 -08:00
613ac38924 Removed use of reserved subnet ip addresses 2022-03-04 10:55:28 -08:00
62f0de1b76 Added readme file 2022-03-04 10:18:32 -08:00
679c91f666 Updated code to remove unused var 2022-03-03 14:56:39 -08:00
8b536b44ef Updated deprecated code 2022-03-02 20:30:18 -08:00
3c2d766490 Modifying providers.tf as provider blocks can't contain vars 2022-03-02 20:04:55 -08:00
3770c0b277 Changes 2022-03-02 19:41:10 -08:00
af4a2cbdd5 Randomizing resource group and leaving in tfvars only the min the cust needs to mod 2022-03-02 18:59:01 -08:00
c25d0c2f2f Changing to adhere to standards 2022-03-02 16:47:07 -08:00
198b9bdd2f update code 2022-03-02 14:50:38 +08:00
c70498ea85 Add example for MySQL Flexible Server Database 2022-03-02 14:26:28 +08:00
7b381c92db create app gateway quickstart 2022-02-24 14:14:36 -08:00
9b007da5d9 Fix resources typo in 201-web-app-docker-acr
resoruce -> resource
2022-02-22 19:23:13 +02:00
2402916336 Fix resources typo in 101-web-app-linux-container
resoruce -> resource
2022-02-22 19:22:15 +02:00
ae358385cc Fix resources typo in 101-web-app-windows-dotnet
resoruce -> resource
2022-02-22 19:21:05 +02:00
970894aa73 Fix resources typo in 101-web-app-linux-java
resoruce -> resource
2022-02-22 19:19:20 +02:00
112c5b5192 Merge pull request #77 from neil-yechenwei/examplepostgresqlfsdb
Add example for PostgreSQL Flexible Server Database
2022-02-16 23:51:35 -08:00
ece38850c7 update code 2022-02-17 13:40:25 +08:00
85d82f8c72 update code 2022-02-17 13:36:44 +08:00
226c83b637 update code 2022-02-17 13:24:33 +08:00
7384552428 update code 2022-02-17 12:17:28 +08:00
7cb6c914d4 update code 2022-02-17 12:16:39 +08:00
30ed335f30 update code 2022-02-17 12:14:23 +08:00
be9fb6ff53 Merge pull request #76 from jensheerin/AVD
Add 101-azure-virtual-desktop
2022-02-15 11:08:36 -08:00
a69ec0bec0 fix broken link 2022-02-07 09:36:11 -05:00
ad42d646d8 Add example for PostgreSQL Flexible Server Database 2022-02-07 13:23:28 +08:00
5fca0727aa Merge branch 'AVD' of https://github.com/jensheerin/terraform into AVD 2022-02-06 23:57:50 -05:00
f8c986b4dc update readme 2022-02-06 23:57:47 -05:00
f11c1958b6 Delete .vscode directory 2022-02-06 23:55:15 -05:00
b49da51665 new folder for anf option, edits to variables 2022-02-06 23:51:32 -05:00
95c7436033 update link 2022-01-03 19:54:16 -05:00
dbcd0a7415 update readme 2022-01-03 19:51:51 -05:00
4dab10866f initial file creation 2022-01-03 19:38:18 -05:00
48a25a1440 Merge pull request #75 from ryhud/master
Adding AML 301 and updates to 201 and 202
2021-11-13 09:30:51 -08:00
f42bebeab3 Delete .gitignore 2021-11-13 11:43:26 -05:00
78c96d168b Merge pull request #6 from ryhud/ryhud-301
terraform fmt
2021-11-12 16:35:02 -05:00
057a0330ca terraform fmt 2021-11-12 16:33:12 -05:00
7aa93d44bc Merge pull request #5 from ryhud/ryhud-301
Ryhud 301
2021-11-12 16:23:58 -05:00
91b12bb8b9 updating tf version 1.0 2021-11-12 16:20:50 -05:00
a4f39d340c tf version 1.0 2021-11-12 15:38:18 -05:00
b16eefa5ca terraform fmt 2021-11-12 15:37:16 -05:00
3de3a1242f Update .gitignore 2021-10-29 09:14:21 -04:00
70ef1e48e5 Merge pull request #4 from ryhud/ryhud-301
adding Log Analytics to the resources section
2021-10-29 09:07:04 -04:00
442a99009d adding Log Analytics to the resources section 2021-10-29 09:05:20 -04:00
53417992c7 Merge pull request #3 from ryhud/ryhud-301
Ryhud 301
2021-10-28 12:21:56 -04:00
fa746473ff updating readme 2021-10-28 12:19:00 -04:00
f851ebafdc Updating readme 2021-10-28 12:17:22 -04:00
1d2ae575e2 Merge pull request #2 from ryhud/ryhud-301
Ryhud 301
2021-10-28 11:56:17 -04:00
71b05cfc0e updating readme 2021-10-28 11:52:12 -04:00
3adc707d42 removing comments 2021-10-28 11:51:42 -04:00
0943dd0568 adding resource dependancy to fix destroy issue 2021-10-28 11:35:41 -04:00
e6cbe158b7 adding sensitive to DSVM password variable 2021-10-28 11:05:39 -04:00
8e503110f9 Updating AML 201 readme 2021-10-26 10:11:56 -04:00
a1d13658a3 random string for fw diagnostics + missing FW rule 2021-10-25 19:10:15 -04:00
5808615b75 Merge pull request #1 from ryhud/ryhud-301
Ryhud 301
2021-10-25 11:05:07 -04:00
2b9b074b9c adding Azure Bastion and DSVM 2021-10-25 10:45:29 -04:00
54355dcdc3 added dependency for Azure Firewall 2021-10-14 17:41:42 -04:00
7cfe24f0ff add missing fw rules for ml 2021-10-07 15:55:47 -04:00
e3d2f4db37 Add FW rules, spoke DNS and UDRs to FW 2021-10-07 13:26:44 -04:00
32a9580ffb adding AML 301 2021-10-06 14:10:15 -04:00
fa0ee0bb58 Merge pull request #69 from TomArcherMsft/UserStory1866077-Code
User Story 1866077 Code
2021-10-01 11:01:37 -07:00
01c7abe31b Changes per tech review 2021-09-30 08:02:50 -07:00
22cf568a9b Merge pull request #71 from TomArcherMsft/UserStory1871520
User Story 1871520
2021-09-29 16:36:31 -07:00
5219ad380e Merge pull request #73 from denniseik/master
Including Azure ML compute with existing examples. Adding network-isolated examples.
2021-09-29 16:34:31 -07:00
2f2199f204 include var 2021-09-29 14:01:30 -07:00
7f015dd153 update readme 2021-09-29 13:52:43 -07:00
b63853c77b use data construct to reference existing resources 2021-09-29 13:26:50 -07:00
56b2b6deed Merge pull request #10 from denniseik/ryhud
Ryhud
2021-09-29 13:22:30 -07:00
8559028099 updating TF variables 2021-09-29 14:10:20 -04:00
ac8b38f3dd updating readme variables 2021-09-29 14:07:54 -04:00
5c674c6100 Include variable defaults in read me 2021-09-29 09:13:01 -07:00
9fcd0f3fb2 apply terraform fmt 2021-09-29 08:48:01 -07:00
a8ba805c8b Implemented changes per review 2021-09-29 06:47:25 -07:00
a609b64fd1 update image_build_compute ref 2021-09-28 12:31:17 -07:00
646c7f32a8 Merge pull request #9 from denniseik/ml-updates
Ml updates
2021-09-24 12:16:57 -07:00
71e22e1e3b Include public network access arg 2021-09-24 12:16:23 -07:00
8d25835eab Include public mode arg for completeness 2021-09-24 12:15:24 -07:00
0b18cf4739 updating aks subnetvar default to larger cidr 2021-09-24 14:33:46 -04:00
44955e3422 adding TF native image_build_compute setting 2021-09-24 14:30:07 -04:00
e814b48966 adding resource dependency to compute instance 2021-09-24 14:25:06 -04:00
9a52e9aa55 updating minimum TF version 2021-09-24 14:21:54 -04:00
cb79cbc272 remove ACLs keyvault 2021-09-24 09:53:07 -07:00
fff24e257b remove gitignore before tf repo merge 2021-09-21 17:12:56 -07:00
a2957c998d Merge branch 'master' of https://github.com/denniseik/terraform 2021-09-21 17:11:52 -07:00
37d13dbb19 update gitignores 2021-09-21 17:10:13 -07:00
b5f97979db Merge pull request #8 from denniseik/feature/201-fitandfinish
Add compute, private link dependencies and updated readme's for publication
2021-09-21 17:07:24 -07:00
bcd263ed5f updates to network and compute 2021-09-21 17:02:40 -07:00
7c4abc8e7e update gitignore 2021-09-20 15:57:46 -07:00
9d04bc247e ci naming 2021-09-20 15:55:51 -07:00
fdbb100df1 add comment 2021-09-20 15:51:03 -07:00
2713f07c82 include compute resources and network dependencies 2021-09-20 15:41:46 -07:00
ae58331e4e fit and finish 101 2021-09-20 10:41:09 -07:00
5c6087899a formatting updates 2021-09-20 10:18:18 -07:00
44679c877a separated compute 2021-09-20 11:22:12 -04:00
7a356afd12 Merge pull request #7 from denniseik/ryhud
Adding 202 for existing VNet
2021-09-17 15:51:30 -07:00
be2da81a47 Merge branch 'ryhud' of https://github.com/denniseik/terraform into ryhud 2021-09-17 18:40:58 -04:00
b52527ceb6 clearing comments 2021-09-17 18:40:44 -04:00
1631260cd2 Add readme links and variable descriptions 2021-09-17 15:31:06 -07:00
00396b82eb Update compute timeout 2021-09-17 15:25:11 -07:00
4f13164bde Tidy up 2021-09-17 15:24:49 -07:00
8011d6b516 Link terraform docs 2021-09-17 15:12:35 -07:00
9358a1cae3 link terraform docs 2021-09-17 15:12:11 -07:00
ce37d06206 Adding 202 for existing VNet 2021-09-17 18:05:06 -04:00
c272d2d0ea Include learn more links 2021-09-17 14:47:23 -07:00
a78a330a33 Include learn more links 2021-09-17 14:46:38 -07:00
c2ded7bfd4 Reflect latest variable state 2021-09-17 14:43:57 -07:00
bb5e5893e7 Include nsg resource with docs 2021-09-17 14:42:02 -07:00
7973eb855d Tidy up 2021-09-17 14:40:06 -07:00
a6a26c372f Tidy up 2021-09-17 14:39:33 -07:00
3733966dfd Updated compute properties 2021-09-17 14:38:06 -07:00
cc25a40362 Include description on compute resources 2021-09-17 14:36:07 -07:00
790fbc87d3 Update compute resources description 2021-09-17 14:35:06 -07:00
5173414efe Include reference to compute 2021-09-17 14:33:51 -07:00
a9b0bd794d Merge pull request #6 from denniseik/ryhud
updating firewall on ACR
2021-09-17 14:25:27 -07:00
6a6b30681f updating firewall on ACR 2021-09-17 16:44:12 -04:00
725e6e13f2 Merge pull request #5 from denniseik/ryhud
updating notebooks Private DNS Zone
2021-09-17 12:14:51 -07:00
40a0e273fa updating notebooks Private DNS Zone 2021-09-17 09:40:41 -04:00
a420a370b0 Updated time 2021-09-16 16:13:26 -07:00
a314cc5351 Fix typo 2021-09-16 16:11:33 -07:00
a6baf22a68 Merge pull request #3 from denniseik/ryhud
updating 201 AML
2021-09-16 16:09:32 -07:00
7cdb4d59e4 Merge pull request #4 from denniseik/feature/azureml-workspace-compute
Feature/azureml workspace compute
2021-09-16 16:08:10 -07:00
4412fb6f00 Merge branch 'Azure:master' into feature/azureml-workspace-compute 2021-09-16 11:51:55 -04:00
0c5c67244a Added Compute Instance and Compute Cluster Resources 2021-09-16 11:49:49 -04:00
ca36cf3e5d updating naming convention 2021-09-16 11:24:11 -04:00
40caddf47c updating 201 AML 2021-09-14 17:37:10 -04:00
38e62ab0ce Merge pull request #2 from denniseik/feature/naming
Templates naming
2021-09-14 13:17:07 -07:00
505f4238b5 naming 2021-09-14 13:15:16 -07:00
2fa2a3f754 Merge pull request #1 from denniseik/feature/azureml-workspace
removed network rules to allow for dataset creation
2021-09-14 13:09:14 -07:00
76decf7a31 network connectivity purpose 2021-09-14 13:05:47 -07:00
d42dcb167c clarify network connectivitiy model 2021-09-14 11:56:23 -07:00
22055a70a0 removed network rules to allow for dataset creation 2021-09-14 13:09:53 -04:00
e3985c1024 Removed code fencing from code file 2021-08-29 20:17:20 -07:00
4223ffbb40 Merge pull request #70 from vhorne/fw-name-fix
fix net test collection name
2021-08-19 11:27:44 -07:00
20a846a0b4 Merge pull request #68 from denniseik/feature/azureml-workspace
Looks great!
2021-08-18 13:47:19 -07:00
d814115559 update resource abbrevations to azure standarsd 2021-08-18 11:58:01 -07:00
96075ca1ef Merge branch 'feature/azureml-workspace' of https://github.com/denniseik/terraform into feature/azureml-workspace 2021-08-18 10:36:13 -07:00
79449910c3 Clarify examples and read me 2021-08-18 10:36:04 -07:00
d0bba2ea8d Removing git ignore from PR
Git ignore should not be include in the PR.
2021-08-18 10:28:14 -07:00
f6733657bf fix net test collection name 2021-08-18 09:00:25 -07:00
3cb80cebe4 update docs 2021-08-18 08:23:27 -07:00
14b6c7c279 include vnet links 2021-08-16 09:53:59 -07:00
2c79eb6a23 Added randomness of rg name, links to ref docs 2021-08-07 22:17:06 -07:00
abc1bd8bbe Merge pull request #66 from TomArcherMsft/tarcher-move-sample-code-to-github
Move documentation sample code to GitHub
2021-08-06 16:41:52 -07:00
bd3972caab Added min tf version 2021-08-06 16:29:03 -07:00
92dacc76d9 Merge pull request #67 from vhorne/fw-upgrade
add firewall
2021-08-06 10:06:35 -07:00
8a9d0949f8 required verson update 2021-08-06 09:38:14 -07:00
8ec6339e99 update 2021-08-06 06:44:45 -07:00
5e52a3836b Added two Azure ML quickstart templates 2021-08-05 14:52:54 -07:00
eeb9d1e303 add required_providers 2021-08-05 12:05:11 -07:00
1ddd8fb226 add firewall 2021-08-05 10:06:02 -07:00
da2472a399 201-k8s-cluster-with-aks-applicationgateway-ingress 2021-08-01 19:42:50 -07:00
c06f51bda0 Tweaking attestation code 2021-08-01 18:53:36 -07:00
e120e52351 Code changes to multiple projects 2021-07-31 17:36:47 -07:00
d18741890d 301-hub-spoke - Added spoke1.tf, spoke2.tf 2021-07-31 16:31:16 -07:00
8e5492e98f 301-hub-spoke - Added hub-nva.tf 2021-07-31 16:21:12 -07:00
20d7d8dd94 301-hub-spoke - Added hub-vnet.tf 2021-07-31 16:10:17 -07:00
54e5c9f9b7 301-hub-spoke - Added on-prem.tf 2021-07-31 15:59:23 -07:00
f0e2d41e89 301-hub-spoke - Created and added main.tf and variables.tf files 2021-07-31 12:49:54 -07:00
9f3049620f Fixed formatting 2021-07-30 18:47:43 -07:00
f13f873692 Fixed DNA naming for VMSS and Jumpbox VM 2021-07-30 18:46:16 -07:00
8e9fd86c2a Updated code for two VMSS articles - 2 2021-07-30 17:27:29 -07:00
a7b8413823 Updated code for two VMSS articles 2021-07-30 16:51:30 -07:00
1bb60e6a06 Added code for create-vm-scaleset-network-disks-using-packer-hcl 2021-07-28 16:42:54 -07:00
8d4c15722d Changes to output 2021-07-28 14:48:27 -07:00
5ebe66c2fc Fixed links 2021-07-28 13:51:29 -07:00
8a6ba16abd Added ip address to output to aid in customer verifying results of example 2021-07-28 13:47:16 -07:00
b1b458ab50 Reformatted create-vm-scaleset-network-disks-hcl 2021-07-28 12:12:40 -07:00
b4528513d2 Added code for create-vm-scaleset-network-disks-hcl 2021-07-28 09:56:18 -07:00
ef2d32ca99 Changed folder to match convention, added sample to top-level readme 2021-07-27 20:14:29 -07:00
d699082efb 101-create-resource-group 2021-07-27 18:25:12 -07:00
cefacf9966 Adding quickstart template example 2021-04-19 18:44:18 -07:00
e932a95d27 Merge pull request #60 from metahertz/fix-issue-57
Always use the latest version of Checkov
2021-04-06 17:39:41 -07:00
f21032933d Merge pull request #59 from powershellpr0mpt/patch-1
Update README.md
2021-04-06 17:32:14 -07:00
96f19bed11 Merge pull request #62 from mgrotheer/patch-1
Update README.md
2021-04-06 17:31:14 -07:00
023dcf5201 Update README.md
Fixed typo
2020-12-24 08:20:08 -08:00
c5d39a4631 Always use the latest version of Checkov
For inclusion of new builtin checks.
2020-10-29 18:23:56 +00:00
25ab251ac1 Update README.md
Fixed broken link to github.com/Azure/terraform repo
2020-10-21 20:23:51 +02:00
d05f030d03 Fix integration testing sample path (#58)
* fix path in pipeline for integration-testing sample
* add exec permission on checkov.sh
2020-10-09 10:22:21 +02:00
00d15e09c5 Merge pull request #53 from feiskyer/aks-quickstart
Add quickstart sample for AKS private cluster with custom DNS
2020-09-09 12:01:41 -07:00
e4e2b20dd5 Update testing samples README files (#56)
add links to the Msft Docs to the sample READMEs
2020-08-27 08:29:45 +02:00
713cbfc0a7 Add quickstart sample for private AKS cluster with custom DNS 2020-08-24 13:57:52 +08:00
WS
cc6b61aa3a Merge pull request #51 from yupwei68/wyp-20200622
Update the Terraform Azurerm Provider Resource Contribute.md
2020-07-26 20:45:54 -07:00
ef757830e6 r1 2020-06-28 10:10:30 +08:00
359f0633f8 update 2020-06-23 10:29:58 +08:00
70eb0555e3 update 2020-06-22 16:34:59 +08:00
24455a9336 Samples: end-to-end testing (#47)
Add a new sample for end-to-end testing in Terraform projects.
2020-06-18 14:48:42 +02:00
74170d8203 Merge pull request #46 from aheumaier/samples/compliance-testing
Samples/compliance testing
2020-06-16 14:53:02 +02:00
8d795d595b Fix: Sync README from azure-dev-docs-pr on best-practice-compliance-testing 2020-06-16 14:39:39 +02:00
a1f201a7b0 Sync README from azure-dev-docs-pr on best-practice-compliance-testing 2020-06-16 14:09:58 +02:00
ac6f9729b0 Sync README from azure-dev-docs-pr on best-practice-compliance-testing 2020-06-16 14:07:51 +02:00
452680862c Sync README from azure-dev-docs-pr on best-practice-compliance-testing 2020-06-16 14:06:24 +02:00
e4058efbd2 Update samples/compliance-testing/README.md
Co-authored-by: Julien Corioland <jcorioland@users.noreply.github.com>
2020-06-16 09:31:48 +02:00
a935d8bf5e Added samples for compliance testing with terraform-compliance 2020-06-16 09:31:48 +02:00
9dd87817cf Update samples/compliance-testing/README.md
Co-authored-by: Julien Corioland <jcorioland@users.noreply.github.com>
2020-06-15 18:07:58 +02:00
708a45ea5a Added samples for compliance testing with terraform-compliance 2020-06-11 10:57:02 +02:00
3328af0982 Add Sample: Integration Testing (#43)
add samples for integration testing
2020-06-11 10:35:53 +02:00
7d4ee2d346 Merge pull request #33 from stfnbrndg/fix-readme-grammar
fix quickstart readme grammar
2019-12-02 14:46:58 -08:00
0b8f7162f4 fix quickstart readme grammar 2019-11-08 21:12:11 -05:00
f607c17060 Merge pull request #32 from jlorich/master
Add initial Quickstart templates
2019-11-07 13:16:16 -05:00
5f390fa368 update aks enterprise 2019-11-06 16:39:48 -05:00
415e3caa97 reorganize, add scaffold folder
update readmes

clean up tf provider

add readme and initial templates

add initial pass at readmes

more readme updates

update various quickstarts

finish cleaning up 101s

more updates

lots fo template updates

add remaining

more updates
2019-11-06 16:39:59 -05:00
fa82feccc7 moved Eugenes Contrib.md file to the module folder and deleted the modules folder 2019-06-12 11:31:19 -07:00
84e8f362fc Merge pull request #31 from echuvyrov/modulecontributionguide
Looks great @echuvyrov
2019-06-12 11:22:46 -07:00
3ba339f80e Adding Terraform Module Contribution Guide 2019-06-11 20:10:56 -07:00
d5b9799f8d Merge pull request #25 from Azure/contrib
Merging Contrib branch to master
2019-05-29 10:58:00 -07:00
3d6183de4b Merge pull request #3 from jcorioland/contrib
Update contribution guide
2019-05-24 11:00:43 -07:00
8b65cc21c0 add data source/resource registration in provider.go 2019-05-24 09:27:35 +02:00
e8d6b4f92c few changes after @JunyiYi review 2019-05-21 09:58:42 +02:00
eaef681e00 fix typo and few additions 2019-05-17 10:11:21 +02:00
3b18e78dcd update local built provider 2019-05-15 16:08:10 +02:00
99ae52231c add link to official docs 2019-05-15 15:30:09 +02:00
ce248d03ef add instructions to develop the provider 2019-05-15 14:59:18 +02:00
649503b5e1 Merge pull request #2 from jcorioland/jcorioland/contrib
AzureRM Terraform Provider Contribution Guide
2019-05-14 08:47:11 +08:00
e6612d2970 addings/corrections after review 2019-05-13 16:03:06 +02:00
1c4804a006 Initial draft 2019-05-07 01:22:00 -07:00
dd927286fd add how to for debugging azurerm tf provider 2019-05-02 18:40:43 +02:00
8004c17619 contributing on AzureRM 2019-04-23 17:10:21 +02:00
9a78fe6869 provider contribute guide 2019-04-08 13:26:30 +02:00
69b2da1921 added submodules for TF modules and providers 2018-10-29 15:44:56 -07:00
344 changed files with 20655 additions and 988 deletions

48
.github/ISSUE_TEMPLATE/1_feature.yml vendored Normal file
View File

@ -0,0 +1,48 @@
name: 'Azure Terraform feature Ask'
description: Request a feature for Azure Terraform Verified Modules, Examples, AzAPI provider, Azure Terrafy, etc.
title: "<title>"
labels: [enhancement]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: dropdown
attributes:
label: Where would you like this feature added?
description: Let us know what product or area you would like to see this feature added to.
multiple: false
options:
- "Verified Modules"
- "AzAPI Provider"
- "Azure Terrafy"
- "Examples (Quickstart, Samples, etc.)"
- "Other/Unknown"
validations:
required: true
- type: textarea
attributes:
label: Is this feature ask due to a problem that you are encountering?
description: If so, please provide a clear and concise description of what the problem is.
placeholder: I'm always frustrated when [...]
validations:
required: false
- type: textarea
attributes:
label: Describe potential solutions.
description: Please provide a clear and concise description of what you want to happen.
placeholder: Add a way for me to [...]
validations:
required: true
- type: textarea
attributes:
label: Anything else?
description: |
Links? References? Anything that will give us more context about the feature you are requesting!
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false

View File

@ -0,0 +1,58 @@
name: 'Azure Terraform example Bug Report'
description: File a bug/issue for a configuration example (Quickstart, samples, etc.)
title: "<title>"
labels: [bug, example]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: input
attributes:
label: Example Name
description: The name of the example where you found the bug.
validations:
required: true
- type: input
attributes:
label: Terraform Version
description: |
What version of Terraform were you using when you encountered this issue?
`terraform --version
placeholder: 1.0.0
validations:
required: true
- type: textarea
attributes:
label: Current Behavior
description: A concise description of what you're experiencing.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: A concise description of what you expected to happen.
validations:
required: true
- type: textarea
attributes:
label: Steps To Reproduce
description: Steps to reproduce the behavior.
placeholder: |
1. Run '...'
2. See error...
validations:
required: false
- type: textarea
attributes:
label: Anything else?
description: |
Links? References? Anything that will give us more context about the issue you are encountering!
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false

73
.github/ISSUE_TEMPLATE/3_module_bug.yml vendored Normal file
View File

@ -0,0 +1,73 @@
name: 'Azure Verified Module Bug Report'
description: File a bug/issue for a verified module
title: "<title>"
labels: [bug, module]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: input
attributes:
label: Module Name
description: The name of the module where you found the bug.
validations:
required: true
- type: input
attributes:
label: Terraform Version
description: |
What version of Terraform were you using when you encountered this issue?
`terraform --version
placeholder: 1.0.0
validations:
required: true
- type: input
attributes:
label: Module Version
description: |
What version of the Azure module were you using when you encountered this issue?
placeholder: 0.1.0
validations:
required: true
- type: textarea
attributes:
label: Current Behavior
description: A concise description of what you're experiencing.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: A concise description of what you expected to happen.
validations:
required: true
- type: textarea
attributes:
label: Terraform configuration
description: Please provide the minimum Terraform configuration that is resulting in the bug / issue.
render: terraform
validations:
required: true
- type: textarea
attributes:
label: Steps To Reproduce
description: Steps to reproduce the behavior.
placeholder: |
1. Run '...'
2. See error...
validations:
required: false
- type: textarea
attributes:
label: Anything else?
description: |
Links? References? Anything that will give us more context about the issue you are encountering!
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false

71
.github/ISSUE_TEMPLATE/4_azapi_bug.yml vendored Normal file
View File

@ -0,0 +1,71 @@
name: 'AzAPI Provider Bug Report'
description: File a bug/issue for the AzAPI Terraform Provider
title: "<title>"
labels: [bug, azapi]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: input
attributes:
label: Terraform Version
description: |
What version of Terraform were you using when you encountered this issue?
Please include operating system when applicable.
`terraform --version`
placeholder: 1.0.0
validations:
required: true
- type: input
attributes:
label: Provider Version
description: |
What version of the AzAPI provider were you using when you encountered this issue?
placeholder: 0.1.0
validations:
required: true
- type: textarea
attributes:
label: Current Behavior
description: A concise description of what you're experiencing. Include Error output where applicable.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: A concise description of what you expected to happen.
validations:
required: true
- type: textarea
attributes:
label: Terraform configuration
description: Please provide the minimum Terraform configuration that is resulting in the bug / issue.
render: terraform
validations:
required: true
- type: textarea
attributes:
label: Steps To Reproduce
description: |
Steps to reproduce the behavior.
`terraform apply`
placeholder: |
1. Run '...'
2. See error...
validations:
required: false
- type: textarea
attributes:
label: Anything else?
description: |
Links? References? Anything that will give us more context about the issue you are encountering!
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false

43
.github/ISSUE_TEMPLATE/5_aztfy_bug.yml vendored Normal file
View File

@ -0,0 +1,43 @@
name: 'Azure Terrafy Bug Report'
description: File a bug/issue for Azure Terrafy (aztfy)
title: "<title>"
labels: [bug, aztfy]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: Current Behavior
description: A concise description of what you're experiencing. Include error output where applicable.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: A concise description of what you expected to happen.
validations:
required: true
- type: textarea
attributes:
label: Steps To Reproduce
description: Steps to reproduce the behavior.
placeholder: |
1. In this environment...
2. Run '...'
3. See error...
validations:
required: true
- type: textarea
attributes:
label: Anything else?
description: |
Links? References? Anything that will give us more context about the issue you are encountering!
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: AzureRM provider issues and Feature requests
url: https://github.com/hashicorp/terraform-provider-azurerm/issues
about: Please ask questions and report issues with the AzureRM provider and related resources here.

298
.gitignore vendored
View File

@ -1,288 +1,12 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
log/
obj/
_site/
.optemp/
_themes*/
_repo.*/
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Typescript v1 declaration files
typings/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
.vscode/
.idea
.ionide/
.openpublishing.buildcore.ps1.vscode/
*.DS_Store

104
.gitmodules vendored Normal file
View File

@ -0,0 +1,104 @@
[submodule "provider/terraform-provider-azurerm"]
path = provider/terraform-provider-azurerm
url = git@github.com:terraform-providers/terraform-provider-azurerm.git
branch = master
[submodule "module/terraform-azurerm-compute"]
path = module/terraform-azurerm-compute
url = git@github.com:Azure/terraform-azurerm-compute.git
branch = master
[submodule "module/terraform-azurerm-network"]
path = module/terraform-azurerm-network
url = git@github.com:Azure/terraform-azurerm-network.git
branch = master
[submodule "module/terraform-azurerm-database"]
path = module/terraform-azurerm-database
url = git@github.com:Azure/terraform-azurerm-database.git
branch = master
[submodule "module/terraform-azurerm-loadbalancer"]
path = module/terraform-azurerm-loadbalancer
url = git@github.com:Azure/terraform-azurerm-loadbalancer.git
branch = master
[submodule "module/terraform-azurerm-computegroup"]
path = module/terraform-azurerm-computegroup
url = git@github.com:Azure/terraform-azurerm-computegroup.git
branch = master
[submodule "module/terraform-azurerm-network-security-group"]
path = module/terraform-azurerm-network-security-group
url = git@github.com:Azure/terraform-azurerm-network-security-group.git
branch = master
[submodule "module/terraform-azurerm-manageddisk"]
path = module/terraform-azurerm-manageddisk
url = git@github.com:Azure/terraform-azurerm-manageddisk.git
branch = master
[submodule "module/terraform-azurerm-vm"]
path = module/terraform-azurerm-vm
url = git@github.com:Azure/terraform-azurerm-vm.git
branch = master
[submodule "module/terraform-azurerm-vmss-cloudinit"]
path = module/terraform-azurerm-vmss-cloudinit
url = git@github.com:Azure/terraform-azurerm-vmss-cloudinit.git
branch = master
[submodule "module/terraform-azurerm-vnet"]
path = module/terraform-azurerm-vnet
url = git@github.com:Azure/terraform-azurerm-vnet.git
branch = master
[submodule "module/terraform-azurerm-encryptedmanageddisk"]
path = module/terraform-azurerm-encryptedmanageddisk
url = git@github.com:Azure/terraform-azurerm-encryptedmanageddisk.git
branch = master
[submodule "module/terraform-azurerm-diskencrypt"]
path = module/terraform-azurerm-diskencrypt
url = git@github.com:Azure/terraform-azurerm-diskencrypt.git
branch = master
[submodule "module/terraform-azurerm-postgresql"]
path = module/terraform-azurerm-postgresql
url = git@github.com:Azure/terraform-azurerm-postgresql.git
branch = master
[submodule "module/terraform-azurerm-storage-account"]
path = module/terraform-azurerm-storage-account
url = git@github.com:Azure/terraform-azurerm-storage-account.git
branch = master
[submodule "module/terraform-azurerm-routetable"]
path = module/terraform-azurerm-routetable
url = git@github.com:Azure/terraform-azurerm-routetable.git
branch = master
[submodule "module/terraform-azurerm-search-service"]
path = module/terraform-azurerm-search-service
url = git@github.com:Azure/terraform-azurerm-search-service.git
branch = master
[submodule "module/terraform-azurerm-vnetpeering"]
path = module/terraform-azurerm-vnetpeering
url = git@github.com:Azure/terraform-azurerm-vnetpeering.git
branch = master
[submodule "module/terraform-azurerm-aks"]
path = module/terraform-azurerm-aks
url = git@github.com:Azure/terraform-azurerm-aks.git
branch = master
[submodule "module/terraform-azurerm-consul"]
path = module/terraform-azurerm-consul
url = git@github.com:Azure/terraform-azurerm-consul.git
branch = master
[submodule "module/terraform-azurerm-aci"]
path = module/terraform-azurerm-aci
url = git@github.com:Azure/terraform-azurerm-aci.git
branch = master
[submodule "module/terraform-azurerm-disk-snapshot"]
path = module/terraform-azurerm-disk-snapshot
url = git@github.com:Azure/terraform-azurerm-disk-snapshot.git
branch = master
[submodule "module/terraform-azurerm-resource-group"]
path = module/terraform-azurerm-resource-group
url = git@github.com:Azure/terraform-azurerm-resource-group.git
branch = master
[submodule "module/terraform-azurerm-vm-extension-msi"]
path = module/terraform-azurerm-vm-extension-msi
url = git@github.com:Azure/terraform-azurerm-vm-extension-msi.git
branch = master
[submodule "module/terraform-azurerm-application-security-group"]
path = module/terraform-azurerm-application-security-group
url = git@github.com:Azure/terraform-azurerm-application-security-group.git
branch = master
[submodule "module/terraform-azurerm-module-test-jenkins"]
path = module/terraform-azurerm-module-test-jenkins
url = git@github.com:Azure/terraform-azurerm-module-test-jenkins.git
branch = master

42
LICENSE
View File

@ -1,21 +1,21 @@
MIT License
Copyright (c) Microsoft Corporation. All rights reserved.
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:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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
MIT License
Copyright (c) Microsoft Corporation. All rights reserved.
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:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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

View File

@ -1,14 +1,24 @@
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
# Contributing
This project welcomes contributions and suggestions.
## Modules
Module summary
[Module contribution guide](./module/CONTRIBUTE.md)
## Providers
Provider summary
[Provider contribution guide](./provider/CONTRIBUTE.md)
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

41
SECURITY.md Normal file
View File

@ -0,0 +1,41 @@
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->
## Security
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
## Reporting Security Issues
**Please do not report security vulnerabilities through public GitHub issues.**
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
This information will help us triage your report more quickly.
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
## Preferred Languages
We prefer all communications to be in English.
## Policy
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
<!-- END MICROSOFT SECURITY.MD BLOCK -->

37
module/CONTRIBUTE.md Normal file
View File

@ -0,0 +1,37 @@
# Contribute to Terraform Modules Registry
This document describes the basic process of authoring and contributing re-usable, verifiable Terraform templates to Terraform Registry (https://registry.terraform.io). Terraform Registry serves as a centralized location to discover, learn and use Terraform artifacts to provision infrastructure into Azure, as well as into other cloud platforms.
## Basic Steps
Below are the basic steps to create and publish a verified Azure module into the Terraform Registry:
1. Following best practices for Terraform template authoring, create a template deploying infrastructure components into Azure.
2. Create a set of tests verifying correctness of Terraform template created in Step 1.
3. Set up a basic Azure DevOps pipeline for Continuous Integration and Deployment, including running the tests created in Step 2 above.
4. Using your GitHub credentials, sign into Terraform Registry and publish your module.
While Steps 2 and 3 are not a requirement for Terraform Registry, we strongly encourage all modules published as "Azure Verified" to include those steps.
### Step 1 - Creating Terraform template
While Terraform offers an easy-to-create, easy-to-understand template authoring language in the form HCL, creating components that could be re-usable is often a time-consuming art form. With Terraform Registry, you are forced to think about various customer scenarios a template could be deployed with, and the permutation of various use cases could be daunting. While it is impossible to anticipate all the scenarios, we recommend that you familiarize yourself with a [set of Terraform Best Practices] (https://www.terraform.io/docs/enterprise/guides/recommended-practices/index.html) published by HashiCorp. Then, think through the most common use cases your module would likely serve, and try to author it in such a way that it will accommodate a set of those scenarios (as opposed to being strongly coupled to a single use case).
We have [created and documented a tool](https://docs.microsoft.com/en-us/azure/terraform/terraform-vscode-module-generator) that builds basic scaffolding for an Azure module, including a sample test. You are also welcome to clone one of the [existing modules] (https://github.com/Azure/terraform-azurerm-postgresql), providing you a set of Terraform files that you can customize for your module.
### Step 2 - Create a set of tests
After experimenting with several approaches for testing Terraform modules, we have settled on using [Terratest](https://github.com/gruntwork-io/terratest). The benefits of Terratest are its ease of integration with CI/CD tooling, as well its similarity to native [Terraform acceptance testing](https://github.com/hashicorp/terraform/blob/master/.github/CONTRIBUTING.md#writing-an-acceptance-test) framework. You will, however, need to be familiar with Go to create tests using Terratest.
If you used [Module Generator](https://docs.microsoft.com/en-us/azure/terraform/terraform-vscode-module-generator) in Step 1, a default test using Terratest is created for you in the test folder. You will need to think through additional tests that you can create that verify correctness of your template.
### Step 3 - Integrate with Azure DevOps
As you introduce changes to the module, or approve pull requests, you'd like to be certain that new changes did not break the functionality the users have become dependent on. This is where CI/CD integration comes in. Integration with Azure DevOps is straightforward to setup - you will need to make sure you have an [azure-pipelines.yml](https://github.com/Azure/terraform-azurerm-postgresql/blob/master/azure-pipelines.yml) in your repo, as well as add the [test.sh](https://github.com/Azure/terraform-azurerm-postgresql/blob/master/test.sh) file to the root of the repo.
The pipelines file is very generic - it builds a docker container and then calls into test.sh for Terratest execution. The only thing you will change in that file is the imageName variable - this will be the docker image name that the pipeline will create. The test.sh file is generic and stays as is, calling all of the test methods that were authored in Step 2.
After your pipelines succeed, please send a request to Terraform on Azure distribution list to pull this pipeline into Terraform ADO environment.
### Step 4 - Publish Module to Terraform Registry
This is the easiest step of all. Simply sign into [Terraform Registry](https://registry.terraform.io) using your GitHub credentials, then click on Publish in the top right corner. Select the repo to publish, then click publish to complete the process.
After your module has been published, please send a request to Terraform on Azure distribution list to enusre we add an "Azure Verified" check box next to the module you've created.

0
module/README.md Normal file
View File

276
provider/CONTRIBUTE.md Normal file
View File

@ -0,0 +1,276 @@
# Contribute to Terraform AzureRM provider
This document describe how you can get ready to contribute to the [AzureRM Terraform provider](https://github.com/terraform-providers/terraform-provider-azurerm).
We also recommend that you read the [README](https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/README.md) on the AzureRM Terraform Provider repository.
## Setup your system
### Terraform
You need to install Terraform on your dev environment. You can downlaod it from [terraform](https://www.terraform.io/downloads.html).
### Go tools
Terraform is developed using Go Programming Language. You need to install Go Programming Language **1.x.x** to be able to build and debug the provider locally. You can check to see what version of Go is currently being used in the project by checking the [go.mod](https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/go.mod) file in the root directory.
You can download it from [golang](https://golang.org/dl/) and find the installation instructions for your system [golang install](https://golang.org/doc/install#install)
Then you can test your environment following the instructions on [golang testing](https://golang.org/doc/install#testing).
### Check your environment variables
As with many Go project, AzureRM Terraform provider rely on your GOPATH environment variable. You may want to make sure it is well configured for your system, reading [golang setting go path](https://github.com/golang/go/wiki/SettingGOPATH).
### Visual Studio Code
You can use the IDE you love, but in this documentation we will describe how to contribute to the Terraform AzureRM provider using Visual Studio Code. You can download it for your system from [visual studio](https://code.visualstudio.com/Download).
Once installed, download the Go extension for VS Code:
![VS Code Go Extension](assets/ms-vscode-go.png)
Once installed, open VS Code and look for the `Go: Install/Update Tools` in the command palette, a select all the tools:
![Install Go Tools](assets/code-install-go-tools.png)
![Install Go Tools - All](assets/code-install-go-tools-all.png)
![Install Go Tools - Wait](assets/code-install-go-tools-wait.png)
### Specific requirements for Windows users
If you are running Windows, then you need to install Git Bash and Make for Windows. Check the dedicated section on Terraform on Azure repository [terraform developer requirements](https://github.com/terraform-providers/terraform-provider-azurerm#developer-requirements).
## Get the sources
First, go to the [AzureRM Terraform provider](https://github.com/terraform-providers/terraform-provider-azurerm) project page and fork the repository into your GitHub account.
Once done, you need to clone your fork into the `$GOPATH/src/github.com/terraform-providers/terraform-provider-azurerm` folder.
## Build the sources
You can check that everything is OK by building the AzureRM provider:
```bash
cd $GOPATH/src/github.com/terraform-providers/terraform-provider-azurerm
make build
```
Once completed, the binary of the AzureRM provider should be available in the `$GOPATH/bin` directory.
*Note: on Windows, you need to use Git Bash*
More information [here](https://github.com/terraform-providers/terraform-provider-azurerm#developing-the-provider).
## Work with your local build
Once you have built a new version of the AzureRM Terraform provider, you can use it locally.
First, you need to move your `terraform` binary which is in the `$GOPATH/bin` folder on your machine, to the third-party plugins folder which is located at `~/.terraform.d/plugins` on most operating systems and `%APPDATA%\terraform.d\plugins` on Windows.
Then you will need to go to your terraform test folder where the `main.tf` configuration file exists and initialize your terraform working directory by using the `terraform init` command.
If the third-party plugin folder is empty, the init operation will download the AzureRM Provider for you.
More information [here](https://www.terraform.io/docs/extend/how-terraform-works.html#plugin-locations).
## Debug the AzureRM provider using Visual Studio Code and Delve
It is possible to use Visual Studio Code and Delve (the Golang debugger) to debug the AzureRM provider.
The easiest way to debug Terraform AzureRM Provider is to execute the acceptances unit test with the Delve debugger attached. Acceptance tests are tests that are written for every resources and data sources and that will really execute the code to an Azure subscription, to validate everything is working well.
First, to be able to connect to Azure, you need to create a service principal using the following command:
```bash
az ad sp create-for-rbac --role=Contributor --scope=/subscriptions/<YOUR_SUBSCRIPTION_ID>
```
Then, you need to create a `.launch.json` file inside the `.vscode` folder at the root of the Terraform AzureRM provider directory (create the `.vscode` folder if it does not exist).
Copy the following content into the file:
```json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch test function",
"type": "go",
"request": "launch",
"mode": "test",
"program": "${workspaceRoot}/azurerm/resource_arm_container_registry_test.go",
"args": [
"-test.v",
"-test.run",
"TestAccAzureRMContainerRegistry_geoReplication"
],
"envFile": "${workspaceRoot}/.vscode/private.env",
"showLog": true
},
]
}
```
The configuration above allows to start debugging a Terraform resource, by launching one or more acceptance test:
- The `program` property indicates the file you want to debug
- The last entry of the `args` property, here `TestAccAzureRMContainerRegistry_geoReplication` represents th test to launch. You can use regex to run multiple tests (ex: `TestAccAzureRMContainerRegistry_*`)
- The `envFile` property defines the path to get the environment variables file (mainly Azure credentials) that needs to be used to run the acceptance test.
Create the `private.env` file into the `.vscode` folder and fill it with the following environment variables:
```
ARM_CLIENT_ID=<YOUR_SERVICE_PRINCIPAL_CLIENT_ID>
ARM_CLIENT_SECRET=<YOUR_SERVICE_PRINCIPAL_CLIENT_SECRET>
ARM_SUBSCRIPTION_ID=<YOUR_AZURE_SUBSCRIPTION_ID>
ARM_TENANT_ID=<YOUR_AZURE_TENANT_ID>
ARM_TEST_LOCATION=<AZURE_LOCATION_1>
ARM_TEST_LOCATION_ALT=<AZURE_LOCATION_2>
TF_ACC=1
```
*Note: it is possible to customize the logging level of Terraform. It might be super useful in some situations. It can be done by setting the `TF_LOG` environment variable. Refer to [the official debugging documentation](https://www.terraform.io/docs/internals/debugging.html) for more details.*
Once done, you can just press F5 and the debug will start! You can place breakpoints in your code to do step by step debugging:
![Install Go Tools - Wait](assets/code-debug-breakpoint.png)
*Note: the first time your start the debug, it can take a while, you need to be patient :-)*
## How to contribute to the Azure RM provider
*Note: we also invite you to read the official documentation about developing a provider [here](https://www.terraform.io/docs/plugins/basics.html#developing-a-plugin)*
First you need to pick [an issue on the provider](https://github.com/terraform-providers/terraform-provider-azurerm/issues) by commenting the issue and saying that you're going to work on that, to make sure that the repo maintainers are aware that you are going to work on this issue.
We also strongly advise that you describe the work you are planning to do, like explaining your implementation, submitting the TF schema for new resources, to make sure the discussion start early as possible with the reviewers.
*Note: if there is no issue for the problem you are trying to solve, you can create one.*
If you are a new contributor, there is a [good first issue](https://github.com/terraform-providers/terraform-provider-azurerm/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label that may help you to filter the issue and start with a simple one.
For each piece of code that you write into the provider, you need to make sure that you have:
- the implementations of the `data source` and/or `resource` definition
- acceptance test created or updated
- documentation created or updated
- example created or updated (optional)
Data sources, resources and tests are defined in the [azurerm/internal/services](https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/azurerm/internal/services) folder of the repository.
Documentation for data sources is in the [website/docs/d](https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/website/docs/d) folder and documentation for resources is in the [website/docs/r](https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/website/docs/r) folder.
Finally, examples are located in the [examples](https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/examples) folder.
AzureRM Terraform provider uses the [Azure SDK for Go](https://github.com/Azure/azure-sdk-for-go) to interact with Azure. It's important that you respect that rule. If you are trying to do something that is not available in the Azure SDK for Go, then you should check if the API is availble in [Azure Service Repository](https://github.com/Azure/azure-rest-api-specs) and open an issue in the **Azure SDK for Go** repository to have it added to a future release of the Azure SDK for Go.
We recommand that you start with fixing issues/patching an existing data source or resource to understand how it works in details before trying to implement a brand new one.
Don't forget that you are working on your own fork of the repository and that you need to open a pull request to the main repository to bring your update to the HashiCorp team, for review.
### Working with Azure SDK for Go
All the imports for the Azure for Go SDK services have to be done in the [client.go](https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/azurerm/internal/clients/client.go) file. It exposes a top level struct, `Client` that exposes all the service clients that you may use in a data source or resource to interact with Azure. If the service already exist and you are just modifying an existing resource you can skip this step.
Then you need to register your subservice in `client.go` in your corresponding service folder.
For example, if you need to work on implementing Azure Batch Account support to the provider:
1. Check if the service `Batch` registered in service [client.go](https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/azurerm/internal/clients/client.go). If not, you need to register your service.
2. Go to your corresponding service folder [batch](https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/azurerm/internal/services/batch) and write a `client.go` in client folder. If the service folder does not exist, you will need to create one.
3. Add a variable `AccountClient` which is created by the service api `NewAccountClientWithBaseURI` from `"github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2019-08-01/batch"`.
```go
type Client struct {
AccountClient *batch.AccountClient
}
```
4. Register your client in the Terraform ResourceManagerAuthorizer:
```go
func NewClient(o *common.ClientOptions) *Client {
accountClient := batch.NewAccountClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&accountClient.Client, o.ResourceManagerAuthorizer)
return &Client{
AccountClient: &accountClient,
}
}
```
By doing the four steps above, you will make sure that when developping the data source or the resource, you can access the Azure SDK for Go clients that you need.
### Developing a Data Source
When naming a new data source file it should follow the below naming convention:
**name_of_the_data_source**_data_source.go
A data source is composed of two relevant functions:
- The function that creates a `schema.Resource` object that returns the schema (definition) of the data source,i.e. the property that compose the data source, and some rules about those properties. You only need to provide required properties to locate that resource, and mark all other properties returned from the service as `Computed`. This function is named by convention dataSourceArm*NAME_OF_THE_DATA_SOURCE*, for example `dataSourceArmBatchAccount` for a Batch Account.
- The function that retrieves the data from Azure using the Azure SDK for Go client and set all the values related to the data source. This function is named by convention dataSourceArm*NAME_OF_THE_DATA_SOURCE*Read, for example `dataSourceArmBatchAccountRead` for a Batch Account.
This function takes a `schema.ResourceData` in parameter. You can get the name of the object to retrieve and any property that is defined by the user on that object:
```go
resourceGroup := d.Get("resource_group_name").(string)
name := d.Get("name").(string)
```
You can get a reference on any Azure SDK for Go client registered in the `client.go` using:
```go
client := meta.(*clients.Client).Batch.AccountClient
```
Finally, you can set values retrieve from Azure on the same object, using the `Set` function:
```go
d.Set("account_endpoint", resp.AccountEndpoint)
```
You can check the whole definition of the Azure Batch Account data source [here](https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/azurerm/internal/services/batch/batch_account_data_source.go).
Once your data source is defined, you need to register it into the data sources map in the `registration.go` file:
```go
func (r Registration) SupportedDataSources() map[string]*schema.Resource {
return map[string]*schema.Resource{
"azurerm_batch_account": dataSourceArmBatchAccount(),
}
}
```
### Developing a resource
Developing a resource is really similar to developing a data source. Instead of having only a function to read the data from Azure, it also offers the possibility to write functions to create, update and delete the resource. Apart from that, concepts are the same:
- The file is named using the convention: *name_of_resource*_resource.go
- One function to define the schema of the resource, named by convention resourceArm*NAME_OF_RESOURCE*, for example `resourceArmBatchAccount`.
- One function to create the resource, named by convention resourceArm*NAME_OF_RESOURCE*Create, for example `resourceArmBatchAccountCreate`.
- One function to read the resource, named by convention resourceArm*NAME_OF_RESOURCE*Read, for example `resourceArmBatchAccountRead`.
- One function to update the resource, named by convention resourceArm*NAME_OF_RESOURCE*Update, for example `resourceArmBatchAccountUpdate`.
- One function to delete the resource, named by convention resourceArm*NAME_OF_RESOURCE*Delete, for example `resourceArmBatchAccountDelete`.
The [Azure Batch Account resource](https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/azurerm/internal/services/batch/batch_account_resource.go) is a good and simple example to understand the flow.
Once your resource is defined, you need to register it into the resources map in the `registration.go` file:
```go
func (r Registration) SupportedResources() map[string]*schema.Resource {
return map[string]*schema.Resource{
"azurerm_batch_account": resourceArmBatchAccount(),
}
}
```
### Acceptance tests
Acceptance tests are tests that will run live on your Azure subscription to validate that your resource/data source is working as expected. Each resource/data source should have its own set of acceptance tests that will run independently of each other.
All tests for a given resource/data source are located in the `test` folder which is a sub folder of the service folder. The file name for the tests will be exactly the same as the resource/data source with the addition of the `_test.go` suffix. For example, if you created a data source for `batch account`, the data source file would be named **batch_account_data_source.go** and the test file would have the name **batch_account_data_source_test.go**.
You can find examples of tests for Azure Batch Account data source [here](https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/azurerm/internal/services/batch/batch_account_data_source_test.go) and Azure Batch Account resource [here](https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/azurerm/internal/services/batch/batch_account_resource_test.go).
Please refer to the above section to learn how to run the acceptance tests on your computer.

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@ -0,0 +1,160 @@
resource "azurerm_resource_group" "rg1" {
name = "myResourceGroupAG"
location = "eastus"
}
resource "azurerm_virtual_network" "vnet1" {
name = "myVNet"
resource_group_name = azurerm_resource_group.rg1.name
location = azurerm_resource_group.rg1.location
address_space = ["10.21.0.0/16"]
}
resource "azurerm_subnet" "frontend" {
name = "myAGSubnet"
resource_group_name = azurerm_resource_group.rg1.name
virtual_network_name = azurerm_virtual_network.vnet1.name
address_prefixes = ["10.21.0.0/24"]
}
resource "azurerm_subnet" "backend" {
name = "myBackendSubnet"
resource_group_name = azurerm_resource_group.rg1.name
virtual_network_name = azurerm_virtual_network.vnet1.name
address_prefixes = ["10.21.1.0/24"]
}
resource "azurerm_public_ip" "pip1" {
name = "myAGPublicIPAddress"
resource_group_name = azurerm_resource_group.rg1.name
location = azurerm_resource_group.rg1.location
allocation_method = "Static"
sku = "Standard"
}
resource "azurerm_application_gateway" "network" {
name = "myAppGateway"
resource_group_name = azurerm_resource_group.rg1.name
location = azurerm_resource_group.rg1.location
sku {
name = "Standard_v2"
tier = "Standard_v2"
capacity = 2
}
gateway_ip_configuration {
name = "my-gateway-ip-configuration"
subnet_id = azurerm_subnet.frontend.id
}
frontend_port {
name = var.frontend_port_name
port = 80
}
frontend_ip_configuration {
name = var.frontend_ip_configuration_name
public_ip_address_id = azurerm_public_ip.pip1.id
}
backend_address_pool {
name = var.backend_address_pool_name
}
backend_http_settings {
name = var.http_setting_name
cookie_based_affinity = "Disabled"
port = 80
protocol = "Http"
request_timeout = 60
}
http_listener {
name = var.listener_name
frontend_ip_configuration_name = var.frontend_ip_configuration_name
frontend_port_name = var.frontend_port_name
protocol = "Http"
}
request_routing_rule {
name = var.request_routing_rule_name
rule_type = "Basic"
http_listener_name = var.listener_name
backend_address_pool_name = var.backend_address_pool_name
backend_http_settings_name = var.http_setting_name
}
}
resource "azurerm_network_interface" "nic" {
count = 2
name = "nic-${count.index+1}"
location = azurerm_resource_group.rg1.location
resource_group_name = azurerm_resource_group.rg1.name
ip_configuration {
name = "nic-ipconfig-${count.index+1}"
subnet_id = azurerm_subnet.backend.id
private_ip_address_allocation = "Dynamic"
}
}
resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "nic-assoc01" {
count = 2
network_interface_id = azurerm_network_interface.nic[count.index].id
ip_configuration_name = "nic-ipconfig-${count.index+1}"
backend_address_pool_id = azurerm_application_gateway.network.backend_address_pool[0].id
}
resource "random_password" "password" {
length = 16
special = true
lower = true
upper = true
number = true
}
resource "azurerm_windows_virtual_machine" "vm" {
count = 2
name = "myVM${count.index+1}"
resource_group_name = azurerm_resource_group.rg1.name
location = azurerm_resource_group.rg1.location
size = "Standard_DS1_v2"
admin_username = "azureadmin"
admin_password = random_password.password.result
network_interface_ids = [
azurerm_network_interface.nic[count.index].id,
]
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2019-Datacenter"
version = "latest"
}
}
resource "azurerm_virtual_machine_extension" "vm-extensions" {
count = 2
name = "vm${count.index+1}-ext"
virtual_machine_id = azurerm_windows_virtual_machine.vm[count.index].id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.10"
settings = <<SETTINGS
{
"commandToExecute": "powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path \"C:\\inetpub\\wwwroot\\Default.htm\" -Value $($env:computername)"
}
SETTINGS
}

View File

@ -0,0 +1,15 @@
terraform {
required_version = ">=0.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=2.97.0"
}
}
}
provider "azurerm" {
features {}
}

View File

@ -0,0 +1,382 @@
# Azure Application Gateway
This template deploys an [Azure Application Gateway](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/application_gateway) v2 and two Windows Server 2019 Datacenter test servers for the backend pool.
## Resources
| Terraform Resource Type | Description |
| - | - |
| `azurerm_resource_group` | The resource group all the deployed resources.|
| `azurerm_virtual_network` | The virtual network for the application gateway. |
| `azurerm_subnet` |The application gateway subnets.|
| `azurerm_public_ip` | The application gateway public IP address. |
| `azurerm_application_gateway` | The v2 Azure Application Gateway. |
| `azurerm_network_interface` | The network interfaces for the test servers. |
| `azurerm_network_interface_application_gateway_backend_address_pool_association` | The network interface association to the backend pool. |
| `azurerm_virtual_machine_extension` | The VM extension for the test servers to install the Web server. |
| `azurerm_windows_virtual_machine` | The VM test servers. |
| `random_password` | Random password for the VM test servers. |
## Variables
| Name | Description |
|-|-|
| `backend_address_pool_name` | Backend pool name |
| `frontend_port_name` | Frontend port name|
| `frontend_ip_configuration_name` | Frontend IP configuration name |
| `http_setting_name` | HTTP setting name |
| `listener_name` | Listener name |
| `request_routing_rule_name` | Routing rule name|
| `redirect_configuration_name` | Redirection configuration name |
## Example
```bash
$ terraform plan -out main.tfplan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# azurerm_application_gateway.network will be created
+ resource "azurerm_application_gateway" "network" {
+ id = (known after apply)
+ location = "eastus"
+ name = "myAppGateway"
+ private_endpoint_connection = (known after apply)
+ resource_group_name = "myResourceGroupAG"
+ backend_address_pool {
+ id = (known after apply)
+ name = "myBackendPool"
}
+ backend_http_settings {
+ cookie_based_affinity = "Disabled"
+ id = (known after apply)
+ name = "myHTTPsetting"
+ pick_host_name_from_backend_address = false
+ port = 80
+ probe_id = (known after apply)
+ protocol = "Http"
+ request_timeout = 60
}
+ frontend_ip_configuration {
+ id = (known after apply)
+ name = "myAGIPConfig"
+ private_ip_address = (known after apply)
+ private_ip_address_allocation = (known after apply)
+ private_link_configuration_id = (known after apply)
+ public_ip_address_id = (known after apply)
+ subnet_id = (known after apply)
}
+ frontend_port {
+ id = (known after apply)
+ name = "myFrontendPort"
+ port = 80
}
+ gateway_ip_configuration {
+ id = (known after apply)
+ name = "my-gateway-ip-configuration"
+ subnet_id = (known after apply)
}
+ http_listener {
+ frontend_ip_configuration_id = (known after apply)
+ frontend_ip_configuration_name = "myAGIPConfig"
+ frontend_port_id = (known after apply)
+ frontend_port_name = "myFrontendPort"
+ id = (known after apply)
+ name = "myListener"
+ protocol = "Http"
+ ssl_certificate_id = (known after apply)
+ ssl_profile_id = (known after apply)
}
+ request_routing_rule {
+ backend_address_pool_id = (known after apply)
+ backend_address_pool_name = "myBackendPool"
+ backend_http_settings_id = (known after apply)
+ backend_http_settings_name = "myHTTPsetting"
+ http_listener_id = (known after apply)
+ http_listener_name = "myListener"
+ id = (known after apply)
+ name = "myRoutingRule"
+ redirect_configuration_id = (known after apply)
+ rewrite_rule_set_id = (known after apply)
+ rule_type = "Basic"
+ url_path_map_id = (known after apply)
}
+ sku {
+ capacity = 2
+ name = "Standard_v2"
+ tier = "Standard_v2"
}
+ ssl_policy {
+ cipher_suites = (known after apply)
+ disabled_protocols = (known after apply)
+ min_protocol_version = (known after apply)
+ policy_name = (known after apply)
+ policy_type = (known after apply)
}
}
# azurerm_network_interface.nic[0] will be created
+ resource "azurerm_network_interface" "nic" {
+ applied_dns_servers = (known after apply)
+ dns_servers = (known after apply)
+ enable_accelerated_networking = false
+ enable_ip_forwarding = false
+ id = (known after apply)
+ internal_dns_name_label = (known after apply)
+ internal_domain_name_suffix = (known after apply)
+ location = "eastus"
+ mac_address = (known after apply)
+ name = "nic-1"
+ private_ip_address = (known after apply)
+ private_ip_addresses = (known after apply)
+ resource_group_name = "myResourceGroupAG"
+ virtual_machine_id = (known after apply)
+ ip_configuration {
+ gateway_load_balancer_frontend_ip_configuration_id = (known after apply)
+ name = "nic-ipconfig-1"
+ primary = (known after apply)
+ private_ip_address = (known after apply)
+ private_ip_address_allocation = "Dynamic"
+ private_ip_address_version = "IPv4"
+ subnet_id = (known after apply)
}
}
# azurerm_network_interface.nic[1] will be created
+ resource "azurerm_network_interface" "nic" {
+ applied_dns_servers = (known after apply)
+ dns_servers = (known after apply)
+ enable_accelerated_networking = false
+ enable_ip_forwarding = false
+ id = (known after apply)
+ internal_dns_name_label = (known after apply)
+ internal_domain_name_suffix = (known after apply)
+ location = "eastus"
+ mac_address = (known after apply)
+ name = "nic-2"
+ private_ip_address = (known after apply)
+ private_ip_addresses = (known after apply)
+ resource_group_name = "myResourceGroupAG"
+ virtual_machine_id = (known after apply)
+ ip_configuration {
+ gateway_load_balancer_frontend_ip_configuration_id = (known after apply)
+ name = "nic-ipconfig-2"
+ primary = (known after apply)
+ private_ip_address = (known after apply)
+ private_ip_address_allocation = "Dynamic"
+ private_ip_address_version = "IPv4"
+ subnet_id = (known after apply)
}
}
# azurerm_network_interface_application_gateway_backend_address_pool_association.nic-assoc01[0] will be created
+ resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "nic-assoc01" {
+ backend_address_pool_id = (known after apply)
+ id = (known after apply)
+ ip_configuration_name = "nic-ipconfig-1"
+ network_interface_id = (known after apply)
}
# azurerm_network_interface_application_gateway_backend_address_pool_association.nic-assoc01[1] will be created
+ resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "nic-assoc01" {
+ backend_address_pool_id = (known after apply)
+ id = (known after apply)
+ ip_configuration_name = "nic-ipconfig-2"
+ network_interface_id = (known after apply)
}
# azurerm_public_ip.pip1 will be created
+ resource "azurerm_public_ip" "pip1" {
+ allocation_method = "Static"
+ availability_zone = (known after apply)
+ fqdn = (known after apply)
+ id = (known after apply)
+ idle_timeout_in_minutes = 4
+ ip_address = (known after apply)
+ ip_version = "IPv4"
+ location = "eastus"
+ name = "myAGPublicIPAddress"
+ resource_group_name = "myResourceGroupAG"
+ sku = "Standard"
+ sku_tier = "Regional"
+ zones = (known after apply)
}
# azurerm_resource_group.rg1 will be created
+ resource "azurerm_resource_group" "rg1" {
+ id = (known after apply)
+ location = "eastus"
+ name = "myResourceGroupAG"
}
# azurerm_subnet.backend will be created
+ resource "azurerm_subnet" "backend" {
+ address_prefix = (known after apply)
+ address_prefixes = [
+ "10.21.1.0/24",
]
+ enforce_private_link_endpoint_network_policies = false
+ enforce_private_link_service_network_policies = false
+ id = (known after apply)
+ name = "myBackendSubnet"
+ resource_group_name = "myResourceGroupAG"
+ virtual_network_name = "myVNet"
}
# azurerm_subnet.frontend will be created
+ resource "azurerm_subnet" "frontend" {
+ address_prefix = (known after apply)
+ address_prefixes = [
+ "10.21.0.0/24",
]
+ enforce_private_link_endpoint_network_policies = false
+ enforce_private_link_service_network_policies = false
+ id = (known after apply)
+ name = "myAGSubnet"
+ resource_group_name = "myResourceGroupAG"
+ virtual_network_name = "myVNet"
}
# azurerm_virtual_machine_extension.vm-extensions[0] will be created
+ resource "azurerm_virtual_machine_extension" "vm-extensions" {
+ id = (known after apply)
+ name = "vm1-ext"
+ publisher = "Microsoft.Compute"
+ settings = jsonencode(
{
+ commandToExecute = "powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path \"C:\\inetpub\\wwwroot\\Default.htm\" -Value $($env:computername)"
}
)
+ type = "CustomScriptExtension"
+ type_handler_version = "1.10"
+ virtual_machine_id = (known after apply)
}
# azurerm_virtual_machine_extension.vm-extensions[1] will be created
+ resource "azurerm_virtual_machine_extension" "vm-extensions" {
+ id = (known after apply)
+ name = "vm2-ext"
+ publisher = "Microsoft.Compute"
+ settings = jsonencode(
{
+ commandToExecute = "powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path \"C:\\inetpub\\wwwroot\\Default.htm\" -Value $($env:computername)"
}
)
+ type = "CustomScriptExtension"
+ type_handler_version = "1.10"
+ virtual_machine_id = (known after apply)
}
# azurerm_virtual_network.vnet1 will be created
+ resource "azurerm_virtual_network" "vnet1" {
+ address_space = [
+ "10.21.0.0/16",
]
+ dns_servers = (known after apply)
+ guid = (known after apply)
+ id = (known after apply)
+ location = "eastus"
+ name = "myVNet"
+ resource_group_name = "myResourceGroupAG"
+ subnet = (known after apply)
+ vm_protection_enabled = false
}
# azurerm_windows_virtual_machine.vm[0] will be created
+ resource "azurerm_windows_virtual_machine" "vm" {
+ admin_password = (sensitive value)
+ admin_username = "azureadmin"
+ allow_extension_operations = true
+ computer_name = (known after apply)
+ enable_automatic_updates = true
+ extensions_time_budget = "PT1H30M"
+ hotpatching_enabled = false
+ id = (known after apply)
+ location = "eastus"
+ max_bid_price = -1
+ name = "myVM1"
+ network_interface_ids = (known after apply)
+ patch_mode = "AutomaticByOS"
+ platform_fault_domain = -1
+ priority = "Regular"
+ private_ip_address = (known after apply)
+ private_ip_addresses = (known after apply)
+ provision_vm_agent = true
+ public_ip_address = (known after apply)
+ public_ip_addresses = (known after apply)
+ resource_group_name = "myResourceGroupAG"
+ size = "Standard_DS1_v2"
+ virtual_machine_id = (known after apply)
+ zone = (known after apply)
+ os_disk {
+ caching = "ReadWrite"
+ disk_size_gb = (known after apply)
+ name = (known after apply)
+ storage_account_type = "Standard_LRS"
+ write_accelerator_enabled = false
}
+ source_image_reference {
+ offer = "WindowsServer"
+ publisher = "MicrosoftWindowsServer"
+ sku = "2019-Datacenter"
+ version = "latest"
}
}
# azurerm_windows_virtual_machine.vm[1] will be created
+ resource "azurerm_windows_virtual_machine" "vm" {
+ admin_password = (sensitive value)
+ admin_username = "azureadmin"
+ allow_extension_operations = true
+ computer_name = (known after apply)
+ enable_automatic_updates = true
+ extensions_time_budget = "PT1H30M"
+ hotpatching_enabled = false
+ id = (known after apply)
+ location = "eastus"
+ max_bid_price = -1
+ name = "myVM2"
+ network_interface_ids = (known after apply)
+ patch_mode = "AutomaticByOS"
+ platform_fault_domain = -1
+ priority = "Regular"
+ private_ip_address = (known after apply)
+ private_ip_addresses = (known after apply)
+ provision_vm_agent = true
+ public_ip_address = (known after apply)
+ public_ip_addresses = (known after apply)
+ resource_group_name = "myResourceGroupAG"
+ size = "Standard_DS1_v2"
+ virtual_machine_id = (known after apply)
+ zone = (known after apply)
+ os_disk {
+ lower = true
+ min_lower = 0
+ min_numeric = 0
+ min_special = 0
+ min_upper = 0
+ number = true
+ result = (sensitive value)
+ special = true
+ upper = true
}
Plan: 15 to add, 0 to change, 0 to destroy.
```

View File

@ -0,0 +1,27 @@
variable "backend_address_pool_name" {
default = "myBackendPool"
}
variable "frontend_port_name" {
default = "myFrontendPort"
}
variable "frontend_ip_configuration_name" {
default = "myAGIPConfig"
}
variable "http_setting_name" {
default = "myHTTPsetting"
}
variable "listener_name" {
default = "myListener"
}
variable "request_routing_rule_name" {
default = "myRoutingRule"
}
variable "redirect_configuration_name" {
default = "myRedirectConfig"
}

View File

@ -0,0 +1,28 @@
terraform {
required_version = ">=0.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>2.0"
}
}
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "rg" {
name = var.resource_group_name
location = var.resource_group_location
}
resource "azurerm_attestation_provider" "corpAttestation" {
name = var.attestation_provider_name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
policy_signing_certificate_data = file(var.policy_file)
}

View File

@ -0,0 +1,15 @@
variable "resource_group_name" {
default = "myResourceGroup"
}
variable "resource_group_location" {
default = "eastus"
}
variable "policy_file" {
default = "~/.certs/cert.pem"
}
variable "attestation_provider_name" {
default = "attestationprovider007"
}

View File

@ -0,0 +1,28 @@
# AzAPI update resource is used to enable Network Rule sets on Event Hub namespace
resource "azapi_update_resource" "qs101" {
type = "Microsoft.EventHub/namespaces/networkRuleSets@2021-11-01"
name = "default"
parent_id = azurerm_eventhub_namespace.qs101.id
body = jsonencode({
properties = {
defaultAction = "Deny"
publicNetworkAccess = "Enabled"
virtualNetworkRules = [
{
ignoreMissingVnetServiceEndpoint = false
subnet = {
# API bug, returned id replaced `resourceGroups` with `resourcegroups`
id = replace(azurerm_subnet.qs101.id, "resourceGroups", "resourcegroups")
}
}
]
ipRules = [
{
action = "Allow"
ipMask = "1.1.1.1"
}
]
}
})
}

View File

@ -0,0 +1,34 @@
resource "azurerm_resource_group" "qs101" {
name = "rg-qs101-eh-rules"
location = "westus2"
}
resource "azurerm_virtual_network" "qs101" {
name = "myvnet"
location = azurerm_resource_group.qs101.location
resource_group_name = azurerm_resource_group.qs101.name
address_space = ["172.17.0.0/16"]
dns_servers = ["10.0.0.4", "10.0.0.5"]
}
resource "azurerm_subnet" "qs101" {
name = "default"
resource_group_name = azurerm_resource_group.qs101.name
virtual_network_name = azurerm_virtual_network.qs101.name
address_prefixes = ["172.17.0.0/24"]
service_endpoints = ["Microsoft.EventHub"]
}
resource "random_pet" "qs101_namespace" {
length = 3
separator = ""
}
resource "azurerm_eventhub_namespace" "qs101" {
name = random_pet.qs101_namespace.id
location = azurerm_resource_group.qs101.location
resource_group_name = azurerm_resource_group.qs101.name
sku = "Standard"
capacity = 2
}

View File

@ -0,0 +1,28 @@
terraform {
required_providers {
azapi = {
source = "azure/azapi"
version = "=0.1.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "=3.0.2"
}
random = {
source = "hashicorp/random"
version = "=3.1.2"
}
}
}
provider "azapi" {
}
provider "azurerm" {
features {}
}
provider "random" {
}

View File

@ -0,0 +1,25 @@
# Provision a Lab Service Account and a Lab that are in public preview
resource "azapi_resource" "qs101-account" {
type = "Microsoft.LabServices/labaccounts@2018-10-15"
name = "qs101LabAccount"
parent_id = azurerm_resource_group.qs101.id
body = jsonencode({
properties = {
enabledRegionSelection = false
}
})
}
resource "azapi_resource" "qs101-lab" {
type = "Microsoft.LabServices/labaccounts/labs@2018-10-15"
name = "qs101Lab"
parent_id = azapi_resource.qs101-account.id
body = jsonencode({
properties = {
maxUsersInLab = 10
userAccessMode = "Restricted"
}
})
}

View File

@ -0,0 +1,4 @@
resource "azurerm_resource_group" "qs101" {
name = "rg-qs101"
location = "westus2"
}

View File

@ -0,0 +1,23 @@
terraform {
required_providers {
azapi = {
source = "azure/azapi"
version = "=0.1.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "=3.0.2"
}
}
}
provider "azapi" {
default_location = "eastus"
default_tags = {
team = "Azure deployments"
}
}
provider "azurerm" {
features {}
}

View File

@ -0,0 +1,123 @@
## Terraform for Azure Virtual Desktop
The purpose of this repository is to demonstrate using Terraform to deploy a simple Azure Virtual Desktop environment. For Classic Azure Virtual Desktop click [here](https://github.com/Azure/RDS-Templates/tree/master/wvd-sh/terraform-azurerm-windowsvirtualdesktop).
## Requirements and limitations
* Ensure that you meet the [requirements for Azure Virtual Desktop](https://docs.microsoft.com/en-us/azure/virtual-desktop/overview#requirements)
* Terraform must be installed and configured as outlined [here](https://docs.microsoft.com/en-us/azure/developer/terraform/get-started-cloud-shell)
* Active Directory already in place in this example, we are using AD in its own VNet.
* Users in AAD that will be given access to AVD
* This demo does not support Azure ADDS only deployment
* Destroy could produce errors deleting subnet due to resources associated. Manually delete resources within the subnet before running destroy
## Components
* Azure Virtual Desktop Environment
* Networking Infrastructure
* Session Hosts
* Profile Storage
* Role Based Access Control
## Features
This directory contains the various components for building out Azure Virtual Desktop.
* `main.tf`
deploys a new workspace, hostpool, application group with associations
* `networking.tf`
deploys a new vnet, subnet, nsg and peering to AD vnet
* `host.tf`
deploys new session host from the marketplace build and join to domain
* `rbac.tf`
deploys rbac assignment for the users group
* `variables.tf`
Input variables
* `loganalytics.tf`
deploys log anaylytics workspace
* `sig.tf`
deploys log anaylytics workspace
* `random.tf`
Random provider configuration
* `defaults.tfvars`
declares the actual input values (keep security in mind if you are putting confidential data)
* `provider.tf`
Azure RM and Azure AD provider configuration
* `outputs.tf`
defines the outputs that will be displayed on deployment
* `netappstorage.tf`
as an alternate to Azure Files storage this deploys NetApp Files storage for profiles in a dedicated subnet (access needs to be granted to the ANF service) [Set up Azure NetApp Files](https://docs.microsoft.com/en-us/azure/azure-netapp-files/azure-netapp-files-quickstart-set-up-account-create-volumes?tabs=azure-portal)
## Variable Inputs
[Variable Inputs](USAGE.md#inputs)
## Deploy
If youve not previously setup terraform, check out this article to get it installed [Quickstart - Configure Terraform using Azure Cloud Shell](https://docs.microsoft.com/en-us/azure/developer/terraform/get-started-cloud-shell)
You can review our sample configuration video here
Once Terraform is setup and you have created your Terraform templates, the first step is to initialize Terraform. This step ensures that Terraform has all the prerequisites to build your template in Azure.
```
terraform init
```
The next step is to have Terraform review and validate the template. An execution plan is generated and stored in the file specified by the -out parameter.
We also need to pass our variable definitions file during the plan. We can either load it automatically by renaming env.tfvars as terraform.tfvars OR env.auto.tfvars, in which case we will use the following to create the execution plan:
```bash
terraform plan -out terraform_azure.tfplan
```
When you're ready to build the infrastructure in Azure, apply the execution plan:
```bash
terraform apply terraform_azure.tfplan
```
## Final Configuration
Youll notice we didnt actually configure the session hosts to use our profile storage at any point. There is an assumption that we are using GPO to manage FSLogix across our host pools as documented here: [Use FSLogix Group Policy Template Files - FSLogix](https://docs.microsoft.com/en-us/fslogix/use-group-policy-templates-ht).
At a minimum youll need to configure the registry keys to enable FSLogix and configure the VHD Location to the NetApp Share URI: [Profile Container registry configuration settings - FSLogix](https://docs.microsoft.com/en-us/fslogix/profile-container-configuration-reference#enabled)
## Troubleshooting Terraform deployment
<details>
<summary>Click to expand</summary>
Terraform deployment can fail in two main categories:
Issues with Terraform code
1. [Issues with Desired State Configuration (DSC)](#issues-with-desired-state-configuration-dsc)
2. [Issues with Terraform code](#issues-with-desired-state-configuration-dsc)
While it is rare to have issues with the Terraform code it is still possible, however most often errors are due to bad input in variables.tf.
* If there are errors in the Terraform code, please file a GitHub issue.
* If there are warning in the Terraform code feel free to ignore or address for your own instance of that code.
* Using Terraform error messages it's a good starting point towards identifying issues with input variables
### Issues with Desired State Configuration (DSC)
To troubleshoot this type of issue, navigate to the Azure portal and if needed reset the password on the VM that failed DSC. Once you are able to log in to the VM review the log files in the following two folders:
</details>
## Additional References
<details>
<summary>Click to expand</summary>
* [Terraform Download](https://www.terraform.io/downloads.html)
* [Visual Code Download](https://code.visualstudio.com/Download)
* [Powershell VS Code Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)
* [HashiCorp Terraform VS Code Extension](https://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform)
* [Azure Terraform VS Code Extension Name](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azureterraform)
* [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?tabs=azure-cli)
* [Configure the Azure Terraform Visual Studio Code extension](https://docs.microsoft.com/en-us/azure/developer/terraform/configure-vs-code-extension-for-terraform)
* [Setup video](https://youtu.be/YmbmpGdhI6w)
</details>

View File

@ -0,0 +1,102 @@
# Usage
<!--- BEGIN_TF_DOCS --->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | ~>2.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | ~>2.0 |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
| <a name="provider_time"></a> [time](#provider\_time) | n/a |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [azuread_group.aad_group](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/group) | resource |
| [azuread_group_member.aad_group_member](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/group_member) | resource |
| [azurerm_log_analytics_workspace.law](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/log_analytics_workspace) | resource |
| [azurerm_network_interface.avd_vm_nic](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) | resource |
| [azurerm_network_security_group.nsg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_group) | resource |
| [azurerm_resource_group.log](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_resource_group.rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_resource_group.rg_storage](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_resource_group.sigrg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_role_assignment.af_role](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.role](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_shared_image.example](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/shared_image) | resource |
| [azurerm_shared_image_gallery.sig](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/shared_image_gallery) | resource |
| [azurerm_storage_account.storage](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account) | resource |
| [azurerm_storage_share.FSShare](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_share) | resource |
| [azurerm_subnet.subnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet) | resource |
| [azurerm_subnet_network_security_group_association.nsg_assoc](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet_network_security_group_association) | resource |
| [azurerm_virtual_desktop_application_group.dag](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_desktop_application_group) | resource |
| [azurerm_virtual_desktop_host_pool.hostpool](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_desktop_host_pool) | resource |
| [azurerm_virtual_desktop_workspace.workspace](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_desktop_workspace) | resource |
| [azurerm_virtual_desktop_workspace_application_group_association.ws-dag](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_desktop_workspace_application_group_association) | resource |
| [azurerm_virtual_machine_extension.domain_join](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) | resource |
| [azurerm_virtual_machine_extension.vmext_dsc](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) | resource |
| [azurerm_virtual_network.vnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network) | resource |
| [azurerm_virtual_network_peering.peer1](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_peering) | resource |
| [azurerm_virtual_network_peering.peer2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_peering) | resource |
| [azurerm_windows_virtual_machine.avd_vm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_virtual_machine) | resource |
| [random_string.AVD_local_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
| [random_string.random](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
| [time_rotating.avd_token](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/rotating) | resource |
| [azuread_user.aad_user](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/user) | data source |
| [azurerm_role_definition.role](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/role_definition) | data source |
| [azurerm_role_definition.storage_role](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/role_definition) | data source |
| [azurerm_virtual_network.ad_vnet_data](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_aad_group_name"></a> [aad\_group\_name](#input\_aad\_group\_name) | Azure Active Directory Group for AVD users | `string` | n/a | yes |
| <a name="input_ad_rg"></a> [ad\_rg](#input\_ad\_rg) | The resource group for AD VM | `string` | n/a | yes |
| <a name="input_ad_vnet"></a> [ad\_vnet](#input\_ad\_vnet) | Name of domain controller vnet | `string` | n/a | yes |
| <a name="input_avd_users"></a> [avd\_users](#input\_avd\_users) | AVD users | `list` | `[]` | no |
| <a name="input_deploy_location"></a> [deploy\_location](#input\_deploy\_location) | The Azure Region in which all resources in this example should be created. | `string` | n/a | yes |
| <a name="input_dns_servers"></a> [dns\_servers](#input\_dns\_servers) | Custom DNS configuration | `list(string)` | n/a | yes |
| <a name="input_domain_name"></a> [domain\_name](#input\_domain\_name) | Name of the domain to join | `string` | n/a | yes |
| <a name="input_domain_password"></a> [domain\_password](#input\_domain\_password) | Password of the user to authenticate with the domain | `string` | n/a | yes |
| <a name="input_domain_user_upn"></a> [domain\_user\_upn](#input\_domain\_user\_upn) | Username for domain join (do not include domain name as this is appended) | `string` | n/a | yes |
| <a name="input_hostpool"></a> [hostpool](#input\_hostpool) | Name of the Azure Virtual Desktop host pool | `string` | `"AVD-TF-HP"` | no |
| <a name="input_local_admin_password"></a> [local\_admin\_password](#input\_local\_admin\_password) | local admin password | `any` | n/a | yes |
| <a name="input_local_admin_username"></a> [local\_admin\_username](#input\_local\_admin\_username) | local admin username | `string` | n/a | yes |
| <a name="input_ou_path"></a> [ou\_path](#input\_ou\_path) | n/a | `string` | `""` | no |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | Prefix of the name of the AVD machine(s) | `string` | n/a | yes |
| <a name="input_rdsh_count"></a> [rdsh\_count](#input\_rdsh\_count) | Number of AVD machines to deploy | `number` | `2` | no |
| <a name="input_rg_name"></a> [rg\_name](#input\_rg\_name) | Name of the Resource group in which to deploy these resources | `string` | `"AVD-TF"` | no |
| <a name="input_shared"></a> [shared](#input\_shared) | Prefix of the name of the AVD machine(s) | `string` | n/a | yes |
| <a name="input_subnet_range"></a> [subnet\_range](#input\_subnet\_range) | Address range for session host subnet | `list(string)` | n/a | yes |
| <a name="input_vm_size"></a> [vm\_size](#input\_vm\_size) | Size of the machine to deploy | `string` | `"Standard_DS2_v2"` | no |
| <a name="input_vnet_range"></a> [vnet\_range](#input\_vnet\_range) | Address range for deployment VNet | `list(string)` | n/a | yes |
| <a name="input_workspace"></a> [workspace](#input\_workspace) | Name of the Azure Virtual Desktop workspace | `string` | `"AVD TF Workspace"` | no |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_aadgroupname"></a> [aadgroupname](#output\_aadgroupname) | Azure Active Directory Group for AVD users |
| <a name="output_avdusers"></a> [avdusers](#output\_avdusers) | AVD users |
| <a name="output_dnsservers"></a> [dnsservers](#output\_dnsservers) | Custom DNS configuration |
| <a name="output_location"></a> [location](#output\_location) | The Azure region |
| <a name="output_rdshcount"></a> [rdshcount](#output\_rdshcount) | The number of VMs created |
| <a name="output_resource_group_name"></a> [resource\_group\_name](#output\_resource\_group\_name) | Name of the Resource group created |
| <a name="output_storage_account_share"></a> [storage\_account\_share](#output\_storage\_account\_share) | Name of the Azure File Share created for FSLogix |
| <a name="output_vnetrange"></a> [vnetrange](#output\_vnetrange) | Address range for deployment vnet |
<!--- END_TF_DOCS --->

View File

@ -0,0 +1,21 @@
# Customized the sample values below for your environment and either rename to terraform.tfvars or env.auto.tfvars
deploy_location = "west europe"
rg_name = "avd-resources-rg"
prefix = "avdtf"
local_admin_username = "localadm"
local_admin_password = "ChangeMe123$"
vnet_range = ["10.1.0.0/16"]
subnet_range = ["10.1.0.0/24"]
netapp_address = ["10.1.1.0/24"]
dns_servers = ["10.0.1.4", "168.63.129.16"]
aad_group_name = "AVDUsers"
domain_name = "infra.local"
domain_user_upn = "admin" # do not include domain name as this is appended
domain_password = "ChangeMe123!"
ad_vnet = "infra-network"
ad_rg = "infra-rg"
avd_users = [
"avduser01@infra.local",
"avduser01@infra.local"
]

View File

@ -0,0 +1,131 @@
locals {
registration_token = azurerm_virtual_desktop_host_pool_registration_info.registrationinfo.token
}
resource "random_string" "AVD_local_password" {
count = var.rdsh_count
length = 16
special = true
min_special = 2
override_special = "*!@#?"
}
resource "azurerm_resource_group" "rg" {
name = var.rg
location = var.resource_group_location
}
resource "azurerm_network_interface" "avd_vm_nic" {
count = var.rdsh_count
name = "${var.prefix}-${count.index + 1}-nic"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
ip_configuration {
name = "nic${count.index + 1}_config"
subnet_id = azurerm_subnet.subnet.id
private_ip_address_allocation = "dynamic"
}
depends_on = [
azurerm_resource_group.rg
]
}
resource "azurerm_windows_virtual_machine" "avd_vm" {
count = var.rdsh_count
name = "${var.prefix}-${count.index + 1}"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
size = var.vm_size
network_interface_ids = ["${azurerm_network_interface.avd_vm_nic.*.id[count.index]}"]
provision_vm_agent = true
admin_username = var.local_admin_username
admin_password = var.local_admin_password
os_disk {
name = "${lower(var.prefix)}-${count.index + 1}"
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsDesktop"
offer = "Windows-10"
sku = "20h2-evd"
version = "latest"
}
depends_on = [
azurerm_resource_group.rg,
azurerm_network_interface.avd_vm_nic
]
}
resource "azurerm_virtual_machine_extension" "domain_join" {
count = var.rdsh_count
name = "${var.prefix}-${count.index + 1}-domainJoin"
virtual_machine_id = azurerm_windows_virtual_machine.avd_vm.*.id[count.index]
publisher = "Microsoft.Compute"
type = "JsonADDomainExtension"
type_handler_version = "1.3"
auto_upgrade_minor_version = true
settings = <<SETTINGS
{
"Name": "${var.domain_name}",
"OUPath": "${var.ou_path}",
"User": "${var.domain_user_upn}@${var.domain_name}",
"Restart": "true",
"Options": "3"
}
SETTINGS
protected_settings = <<PROTECTED_SETTINGS
{
"Password": "${var.domain_password}"
}
PROTECTED_SETTINGS
lifecycle {
ignore_changes = [settings, protected_settings]
}
depends_on = [
azurerm_virtual_network_peering.peer1,
azurerm_virtual_network_peering.peer2
]
}
resource "azurerm_virtual_machine_extension" "vmext_dsc" {
count = var.rdsh_count
name = "${var.prefix}${count.index + 1}-avd_dsc"
virtual_machine_id = azurerm_windows_virtual_machine.avd_vm.*.id[count.index]
publisher = "Microsoft.Powershell"
type = "DSC"
type_handler_version = "2.73"
auto_upgrade_minor_version = true
settings = <<-SETTINGS
{
"modulesUrl": "https://wvdportalstorageblob.blob.core.windows.net/galleryartifacts/Configuration_3-10-2021.zip",
"configurationFunction": "Configuration.ps1\\AddSessionHost",
"properties": {
"HostPoolName":"${azurerm_virtual_desktop_host_pool.hostpool.name}"
}
}
SETTINGS
protected_settings = <<PROTECTED_SETTINGS
{
"properties": {
"registrationInfoToken": "${local.registration_token}"
}
}
PROTECTED_SETTINGS
depends_on = [
azurerm_virtual_machine_extension.domain_join,
azurerm_virtual_desktop_host_pool.hostpool
]
}

View File

@ -0,0 +1,14 @@
resource "azurerm_resource_group" "log" {
name = var.rg_shared_name
location = var.deploy_location
}
# Creates Log Anaylytics Workspace
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/log_analytics_workspace
resource "azurerm_log_analytics_workspace" "law" {
name = "log${random_string.random.id}"
location = azurerm_resource_group.log.location
resource_group_name = azurerm_resource_group.log.name
sku = "PerGB2018"
retention_in_days = 30
}

View File

@ -0,0 +1,51 @@
# Resource group name is output when execution plan is applied.
resource "azurerm_resource_group" "sh" {
name = var.rg_name
location = var.resource_group_location
}
# Create AVD workspace
resource "azurerm_virtual_desktop_workspace" "workspace" {
name = var.workspace
resource_group_name = azurerm_resource_group.sh.name
location = azurerm_resource_group.sh.location
friendly_name = "${var.prefix} Workspace"
description = "${var.prefix} Workspace"
}
# Create AVD host pool
resource "azurerm_virtual_desktop_host_pool" "hostpool" {
resource_group_name = azurerm_resource_group.sh.name
location = azurerm_resource_group.sh.location
name = var.hostpool
friendly_name = var.hostpool
validate_environment = true
custom_rdp_properties = "audiocapturemode:i:1;audiomode:i:0;"
description = "${var.prefix} Terraform HostPool"
type = "Pooled"
maximum_sessions_allowed = 16
load_balancer_type = "DepthFirst" #[BreadthFirst DepthFirst]
}
resource "azurerm_virtual_desktop_host_pool_registration_info" "registrationinfo" {
hostpool_id = azurerm_virtual_desktop_host_pool.hostpool.id
expiration_date = var.rfc3339
}
# Create AVD DAG
resource "azurerm_virtual_desktop_application_group" "dag" {
resource_group_name = azurerm_resource_group.sh.name
host_pool_id = azurerm_virtual_desktop_host_pool.hostpool.id
location = azurerm_resource_group.sh.location
type = "Desktop"
name = "${var.prefix}-dag"
friendly_name = "Desktop AppGroup"
description = "AVD application group"
depends_on = [azurerm_virtual_desktop_host_pool.hostpool, azurerm_virtual_desktop_workspace.workspace]
}
# Associate Workspace and DAG
resource "azurerm_virtual_desktop_workspace_application_group_association" "ws-dag" {
application_group_id = azurerm_virtual_desktop_application_group.dag.id
workspace_id = azurerm_virtual_desktop_workspace.workspace.id
}

View File

@ -0,0 +1,69 @@
# As an alternate to Azure Files storage use this file to replace afstorage.tf to deploy NetApp Files storage for profiles in a dedicated subnet (access needs to be granted to the ANF service)
# Set up Azure NetApp Files https://docs.microsoft.com/en-us/azure/azure-netapp-files/azure-netapp-files-quickstart-set-up-account-create-volumes?tabs=azure-portal
resource "azurerm_subnet" "netapp_subnet" {
name = var.netapp_subnet_name
resource_group_name = var.rg_stor
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = var.netapp_address
delegation {
name = "NetAppdelegation"
service_delegation {
name = "Microsoft.Netapp/volumes"
}
}
}
resource "azurerm_netapp_account" "netapp_acct" {
name = var.netapp_acct_name
resource_group_name = var.rg_stor
location = var.deploy_location
active_directory {
username = var.domain_user_upn
password = var.domain_password
smb_server_name = var.netapp_smb_name
dns_servers = var.dns_servers
domain = var.domain_name
organizational_unit = var.ou_path
}
depends_on = [
azurerm_resource_group.rg
]
}
resource "azurerm_netapp_pool" "netapp_pool" {
name = var.netapp_pool_name
location = var.deploy_location
resource_group_name = var.rg_stor
account_name = var.netapp_acct_name
service_level = "Standard"
size_in_tb = 4
depends_on = [
azurerm_resource_group.rg, azurerm_netapp_account.netapp_acct
]
}
resource "azurerm_netapp_volume" "NetApp_Vol" {
lifecycle {
prevent_destroy = true
}
name = var.netapp_volume_name
location = var.deploy_location
resource_group_name = var.rg_stor
account_name = var.netapp_acct_name
pool_name = var.netapp_pool_name
volume_path = var.netapp_volume_path
service_level = "Standard"
subnet_id = azurerm_subnet.netapp_subnet.id
protocols = ["CIFS"]
storage_quota_in_gb = 100
depends_on = [
azurerm_netapp_pool.netapp_pool
]
}

View File

@ -0,0 +1,57 @@
resource "azurerm_virtual_network" "vnet" {
name = "${var.prefix}-VNet"
address_space = var.vnet_range
dns_servers = var.dns_servers
location = var.deploy_location
resource_group_name = var.rg_name
depends_on = [azurerm_resource_group.rg]
}
resource "azurerm_subnet" "subnet" {
name = "default"
resource_group_name = var.rg_name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = var.subnet_range
depends_on = [azurerm_resource_group.rg]
}
resource "azurerm_network_security_group" "nsg" {
name = "${var.prefix}-NSG"
location = var.deploy_location
resource_group_name = var.rg_name
security_rule {
name = "HTTPS"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = "*"
}
depends_on = [azurerm_resource_group.rg]
}
resource "azurerm_subnet_network_security_group_association" "nsg_assoc" {
subnet_id = azurerm_subnet.subnet.id
network_security_group_id = azurerm_network_security_group.nsg.id
}
data "azurerm_virtual_network" "ad_vnet_data" {
name = var.ad_vnet
resource_group_name = var.ad_rg
}
resource "azurerm_virtual_network_peering" "peer1" {
name = "peer_avd_ad"
resource_group_name = var.rg_name
virtual_network_name = azurerm_virtual_network.vnet.name
remote_virtual_network_id = data.azurerm_virtual_network.ad_vnet_data.id
}
resource "azurerm_virtual_network_peering" "peer2" {
name = "peer_ad_avd"
resource_group_name = var.ad_rg
virtual_network_name = var.ad_vnet
remote_virtual_network_id = azurerm_virtual_network.vnet.id
}

View File

@ -0,0 +1,54 @@
output "azure_virtual_desktop_compute_resource_group" {
description = "Name of the Resource group in which to deploy session host"
value = azurerm_resource_group.rg.name
}
output "azure_virtual_desktop_host_pool" {
description = "Name of the Azure Virtual Desktop host pool"
value = azurerm_virtual_desktop_host_pool.hostpool.name
}
output "azurerm_virtual_desktop_application_group" {
description = "Name of the Azure Virtual Desktop DAG"
value = azurerm_virtual_desktop_application_group.dag.name
}
output "azurerm_virtual_desktop_workspace" {
description = "Name of the Azure Virtual Desktop workspace"
value = azurerm_virtual_desktop_workspace.workspace.name
}
output "location" {
description = "The Azure region"
value = azurerm_resource_group.rg.location
}
output "storage_account" {
description = "Storage account for Profiles"
value = azurerm_storage_account.storage.name
}
output "storage_account_share" {
description = "Name of the Azure File Share created for FSLogix"
value = azurerm_storage_share.FSShare.name
}
output "session_host_count" {
description = "The number of VMs created"
value = var.rdsh_count
}
output "dnsservers" {
description = "Custom DNS configuration"
value = azurerm_virtual_network.vnet.dns_servers
}
output "vnetrange" {
description = "Address range for deployment vnet"
value = azurerm_virtual_network.vnet.address_space
}
output "AVD_user_groupname" {
description = "Azure Active Directory Group for AVD users"
value = azuread_group.aad_group.display_name
}

View File

@ -0,0 +1,15 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>2.0"
}
azuread = {
source = "hashicorp/azuread"
}
}
}
provider "azurerm" {
features {}
}

View File

@ -0,0 +1,25 @@
data "azuread_user" "aad_user" {
for_each = toset(var.avd_users)
user_principal_name = format("%s", each.key)
}
data "azurerm_role_definition" "role" { # access an existing built-in role
name = "Desktop Virtualization User"
}
resource "azuread_group" "aad_group" {
display_name = var.aad_group_name
security_enabled = true
}
resource "azuread_group_member" "aad_group_member" {
for_each = data.azuread_user.aad_user
group_object_id = azuread_group.aad_group.id
member_object_id = each.value["id"]
}
resource "azurerm_role_assignment" "role" {
scope = azurerm_virtual_desktop_application_group.dag.id
role_definition_id = data.azurerm_role_definition.role.id
principal_id = azuread_group.aad_group.id
}

View File

@ -0,0 +1,44 @@
resource "azurerm_resource_group" "sigrg" {
location = var.deploy_location
name = var.rg_shared_name
}
# generate a random string (consisting of four characters)
# https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string
resource "random_string" "rando" {
length = 4
upper = false
special = false
}
# Creates Shared Image Gallery
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/shared_image_gallery
resource "azurerm_shared_image_gallery" "sig" {
name = "sig${random_string.random.id}"
resource_group_name = azurerm_resource_group.sigrg.name
location = azurerm_resource_group.sigrg.location
description = "Shared images"
tags = {
Environment = "Demo"
Tech = "Terraform"
}
}
#Creates image definition
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/shared_image
resource "azurerm_shared_image" "example" {
name = "avd-image"
gallery_name = azurerm_shared_image_gallery.sig.name
resource_group_name = azurerm_resource_group.sigrg.name
location = azurerm_resource_group.sigrg.location
os_type = "Windows"
identifier {
publisher = "MicrosoftWindowsDesktop"
offer = "office-365"
sku = "20h2-evd-o365pp"
}
}

View File

@ -0,0 +1,176 @@
variable "resource_group_location" {
default = "eastus"
description = "Location of the resource group."
}
variable "rg" {
type = string
default = "rg-avd-compute"
description = "Name of the Resource group in which to deploy session host"
}
variable "rg_name" {
type = string
default = "rg-avd-resources"
description = "Name of the Resource group in which to deploy service objects"
}
variable "rg_stor" {
type = string
default = "rg-avd-storage"
description = "Name of the Resource group in which to deploy storage"
}
variable "rg_shared_name" {
type = string
default = "rg-shared-resources"
description = "Name of the Resource group in which to deploy shared resources"
}
variable "deploy_location" {
type = string
default = "eastus"
description = "The Azure Region in which all resources in this example should be created."
}
variable "workspace" {
type = string
description = "Name of the Azure Virtual Desktop workspace"
default = "AVD TF Workspace"
}
variable "hostpool" {
type = string
description = "Name of the Azure Virtual Desktop host pool"
default = "AVD-TF-HP"
}
variable "ad_vnet" {
type = string
default = "infra-network"
description = "Name of domain controller vnet"
}
variable "rfc3339" {
type = string
default = "2022-03-30T12:43:13Z"
description = "Registration token expiration"
}
variable "dns_servers" {
type = list(string)
default = ["10.0.1.4", "168.63.129.16"]
description = "Custom DNS configuration"
}
variable "vnet_range" {
type = list(string)
default = ["10.2.0.0/16"]
description = "Address range for deployment VNet"
}
variable "subnet_range" {
type = list(string)
default = ["10.2.0.0/24"]
description = "Address range for session host subnet"
}
variable "ad_rg" {
type = string
default = "infra-rg"
description = "The resource group for AD VM"
}
variable "avd_users" {
description = "AVD users"
default = [
"avduser01@contoso.net",
"avduser02@contoso.net"
]
}
variable "aad_group_name" {
type = string
default = "AVDUsers"
description = "Azure Active Directory Group for AVD users"
}
variable "rdsh_count" {
description = "Number of AVD machines to deploy"
default = 2
}
variable "prefix" {
type = string
default = "avdtf"
description = "Prefix of the name of the AVD machine(s)"
}
variable "domain_name" {
type = string
default = "infra.local"
description = "Name of the domain to join"
}
variable "domain_user_upn" {
type = string
default = "domainjoineruser" # do not include domain name as this is appended
description = "Username for domain join (do not include domain name as this is appended)"
}
variable "domain_password" {
type = string
default = "ChangeMe123!"
description = "Password of the user to authenticate with the domain"
sensitive = true
}
variable "vm_size" {
description = "Size of the machine to deploy"
default = "Standard_DS2_v2"
}
variable "ou_path" {
default = ""
}
variable "local_admin_username" {
type = string
default = "localadm"
description = "local admin username"
}
variable "local_admin_password" {
type = string
default = "ChangeMe123!"
description = "local admin password"
sensitive = true
}
variable "netapp_acct_name" {
default = "AVD_NetApp"
}
variable "netapp_pool_name" {
default = "AVD_NetApp_pool"
}
variable "netapp_volume_name" {
default = "AVD_NetApp_volume"
}
variable "netapp_smb_name" {
default = "AVDNetApp"
}
variable "netapp_volume_path" {
default = "AVDNetAppVolume"
}
variable "netapp_subnet_name" {
default = "NetAppSubnet"
}
variable "netapp_address" {
default = ["10.1.1.0/24"]
description = "Address range for NetApp Subnet"
}

View File

@ -0,0 +1,123 @@
## Terraform for Azure Virtual Desktop
The purpose of this repository is to demonstrate using Terraform to deploy a simple Azure Virtual Desktop environment. For Classic Azure Virtual Desktop click [here](https://github.com/Azure/RDS-Templates/tree/master/wvd-sh/terraform-azurerm-windowsvirtualdesktop).
## Requirements and limitations
* Ensure that you meet the [requirements for Azure Virtual Desktop](https://docs.microsoft.com/en-us/azure/virtual-desktop/overview#requirements)
* Terraform must be installed and configured as outlined [here](https://docs.microsoft.com/en-us/azure/developer/terraform/get-started-cloud-shell)
* Active Directory already in place in this example, we are using AD in its own VNet.
* Users in AAD that will be given access to AVD
* This demo does not support Azure ADDS only deployment
* Destroy could produce errors deleting subnet due to resources associated. Manually delete resources within the subnet before running destroy
## Components
* Azure Virtual Desktop Environment
* Networking Infrastructure
* Session Hosts
* Profile Storage
* Role Based Access Control
## Features
This directory contains the various components for building out Azure Virtual Desktop.
* `main.tf`
deploys a new workspace, hostpool, application group with associations
* `networking.tf`
deploys a new vnet, subnet, nsg and peering to AD vnet
* `host.tf`
deploys new session host from the marketplace build and join to domain
* `afstorage.tf`
deploys Azure Files storage for profiles and creates file share with RBAC permissions for the users group ([NTFS permissions will need to be configured](https://docs.microsoft.com/en-us/azure/virtual-desktop/create-file-share))
* `rbac.tf`
deploys rbac assignment for the users group
* `variables.tf`
Input variables
* `loganalytics.tf`
deploys log anaylytics workspace
* `sig.tf`
deploys log anaylytics workspace
* `random.tf`
Random provider configuration
* `defaults.tfvars`
declares the actual input values (keep security in mind if you are putting confidential data)
* `provider.tf`
Azure RM and Azure AD provider configuration
* `outputs.tf`
defines the outputs that will be displayed on deployment
## Variable Inputs
[Variable Inputs](USAGE.md#inputs)
## Deploy
If youve not previously setup terraform, check out this article to get it installed [Quickstart - Configure Terraform using Azure Cloud Shell](https://docs.microsoft.com/en-us/azure/developer/terraform/get-started-cloud-shell)
You can review our sample configuration video here
Once Terraform is setup and you have created your Terraform templates, the first step is to initialize Terraform. This step ensures that Terraform has all the prerequisites to build your template in Azure.
```
terraform init
```
The next step is to have Terraform review and validate the template. An execution plan is generated and stored in the file specified by the -out parameter.
We also need to pass our variable definitions file during the plan. We can either load it automatically by renaming env.tfvars as terraform.tfvars OR env.auto.tfvars, in which case we will use the following to create the execution plan:
```bash
terraform plan -out terraform_azure.tfplan
```
When you're ready to build the infrastructure in Azure, apply the execution plan:
```bash
terraform apply terraform_azure.tfplan
```
## Final Configuration
Youll notice we didnt actually configure the session hosts to use our profile storage at any point. There is an assumption that we are using GPO to manage FSLogix across our host pools as documented here: [Use FSLogix Group Policy Template Files - FSLogix](https://docs.microsoft.com/en-us/fslogix/use-group-policy-templates-ht).
At a minimum youll need to configure the registry keys to enable FSLogix and configure the VHD Location to the NetApp Share URI: [Profile Container registry configuration settings - FSLogix](https://docs.microsoft.com/en-us/fslogix/profile-container-configuration-reference#enabled)
## Troubleshooting Terraform deployment
<details>
<summary>Click to expand</summary>
Terraform deployment can fail in two main categories:
Issues with Terraform code
1. [Issues with Desired State Configuration (DSC)](#issues-with-desired-state-configuration-dsc)
2. [Issues with Terraform code](#issues-with-desired-state-configuration-dsc)
While it is rare to have issues with the Terraform code it is still possible, however most often errors are due to bad input in variables.tf.
* If there are errors in the Terraform code, please file a GitHub issue.
* If there are warning in the Terraform code feel free to ignore or address for your own instance of that code.
* Using Terraform error messages it's a good starting point towards identifying issues with input variables
### Issues with Desired State Configuration (DSC)
To troubleshoot this type of issue, navigate to the Azure portal and if needed reset the password on the VM that failed DSC. Once you are able to log in to the VM review the log files in the following two folders:
</details>
## Additional References
<details>
<summary>Click to expand</summary>
* [Terraform Download](https://www.terraform.io/downloads.html)
* [Visual Code Download](https://code.visualstudio.com/Download)
* [Powershell VS Code Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)
* [HashiCorp Terraform VS Code Extension](https://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform)
* [Azure Terraform VS Code Extension Name](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azureterraform)
* [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?tabs=azure-cli)
* [Configure the Azure Terraform Visual Studio Code extension](https://docs.microsoft.com/en-us/azure/developer/terraform/configure-vs-code-extension-for-terraform)
* [Setup video](https://youtu.be/YmbmpGdhI6w)
</details>

View File

@ -0,0 +1,102 @@
# Usage
<!--- BEGIN_TF_DOCS --->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | ~>2.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | ~>2.0 |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
| <a name="provider_time"></a> [time](#provider\_time) | n/a |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [azuread_group.aad_group](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/group) | resource |
| [azuread_group_member.aad_group_member](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/group_member) | resource |
| [azurerm_log_analytics_workspace.law](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/log_analytics_workspace) | resource |
| [azurerm_network_interface.avd_vm_nic](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) | resource |
| [azurerm_network_security_group.nsg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_group) | resource |
| [azurerm_resource_group.log](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_resource_group.rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_resource_group.rg_storage](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_resource_group.sigrg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_role_assignment.af_role](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.role](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_shared_image.example](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/shared_image) | resource |
| [azurerm_shared_image_gallery.sig](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/shared_image_gallery) | resource |
| [azurerm_storage_account.storage](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account) | resource |
| [azurerm_storage_share.FSShare](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_share) | resource |
| [azurerm_subnet.subnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet) | resource |
| [azurerm_subnet_network_security_group_association.nsg_assoc](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet_network_security_group_association) | resource |
| [azurerm_virtual_desktop_application_group.dag](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_desktop_application_group) | resource |
| [azurerm_virtual_desktop_host_pool.hostpool](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_desktop_host_pool) | resource |
| [azurerm_virtual_desktop_workspace.workspace](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_desktop_workspace) | resource |
| [azurerm_virtual_desktop_workspace_application_group_association.ws-dag](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_desktop_workspace_application_group_association) | resource |
| [azurerm_virtual_machine_extension.domain_join](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) | resource |
| [azurerm_virtual_machine_extension.vmext_dsc](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) | resource |
| [azurerm_virtual_network.vnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network) | resource |
| [azurerm_virtual_network_peering.peer1](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_peering) | resource |
| [azurerm_virtual_network_peering.peer2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_peering) | resource |
| [azurerm_windows_virtual_machine.avd_vm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_virtual_machine) | resource |
| [random_string.AVD_local_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
| [random_string.random](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
| [time_rotating.avd_token](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/rotating) | resource |
| [azuread_user.aad_user](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/user) | data source |
| [azurerm_role_definition.role](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/role_definition) | data source |
| [azurerm_role_definition.storage_role](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/role_definition) | data source |
| [azurerm_virtual_network.ad_vnet_data](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_aad_group_name"></a> [aad\_group\_name](#input\_aad\_group\_name) | Azure Active Directory Group for AVD users | `string` | n/a | yes |
| <a name="input_ad_rg"></a> [ad\_rg](#input\_ad\_rg) | The resource group for AD VM | `string` | n/a | yes |
| <a name="input_ad_vnet"></a> [ad\_vnet](#input\_ad\_vnet) | Name of domain controller vnet | `string` | n/a | yes |
| <a name="input_avd_users"></a> [avd\_users](#input\_avd\_users) | AVD users | `list` | `[]` | no |
| <a name="input_deploy_location"></a> [deploy\_location](#input\_deploy\_location) | The Azure Region in which all resources in this example should be created. | `string` | n/a | yes |
| <a name="input_dns_servers"></a> [dns\_servers](#input\_dns\_servers) | Custom DNS configuration | `list(string)` | n/a | yes |
| <a name="input_domain_name"></a> [domain\_name](#input\_domain\_name) | Name of the domain to join | `string` | n/a | yes |
| <a name="input_domain_password"></a> [domain\_password](#input\_domain\_password) | Password of the user to authenticate with the domain | `string` | n/a | yes |
| <a name="input_domain_user_upn"></a> [domain\_user\_upn](#input\_domain\_user\_upn) | Username for domain join (do not include domain name as this is appended) | `string` | n/a | yes |
| <a name="input_hostpool"></a> [hostpool](#input\_hostpool) | Name of the Azure Virtual Desktop host pool | `string` | `"AVD-TF-HP"` | no |
| <a name="input_local_admin_password"></a> [local\_admin\_password](#input\_local\_admin\_password) | local admin password | `any` | n/a | yes |
| <a name="input_local_admin_username"></a> [local\_admin\_username](#input\_local\_admin\_username) | local admin username | `string` | n/a | yes |
| <a name="input_ou_path"></a> [ou\_path](#input\_ou\_path) | n/a | `string` | `""` | no |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | Prefix of the name of the AVD machine(s) | `string` | n/a | yes |
| <a name="input_rdsh_count"></a> [rdsh\_count](#input\_rdsh\_count) | Number of AVD machines to deploy | `number` | `2` | no |
| <a name="input_rg_name"></a> [rg\_name](#input\_rg\_name) | Name of the Resource group in which to deploy these resources | `string` | `"AVD-TF"` | no |
| <a name="input_shared"></a> [shared](#input\_shared) | Prefix of the name of the AVD machine(s) | `string` | n/a | yes |
| <a name="input_subnet_range"></a> [subnet\_range](#input\_subnet\_range) | Address range for session host subnet | `list(string)` | n/a | yes |
| <a name="input_vm_size"></a> [vm\_size](#input\_vm\_size) | Size of the machine to deploy | `string` | `"Standard_DS2_v2"` | no |
| <a name="input_vnet_range"></a> [vnet\_range](#input\_vnet\_range) | Address range for deployment VNet | `list(string)` | n/a | yes |
| <a name="input_workspace"></a> [workspace](#input\_workspace) | Name of the Azure Virtual Desktop workspace | `string` | `"AVD TF Workspace"` | no |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_aadgroupname"></a> [aadgroupname](#output\_aadgroupname) | Azure Active Directory Group for AVD users |
| <a name="output_avdusers"></a> [avdusers](#output\_avdusers) | AVD users |
| <a name="output_dnsservers"></a> [dnsservers](#output\_dnsservers) | Custom DNS configuration |
| <a name="output_location"></a> [location](#output\_location) | The Azure region |
| <a name="output_rdshcount"></a> [rdshcount](#output\_rdshcount) | The number of VMs created |
| <a name="output_resource_group_name"></a> [resource\_group\_name](#output\_resource\_group\_name) | Name of the Resource group created |
| <a name="output_storage_account_share"></a> [storage\_account\_share](#output\_storage\_account\_share) | Name of the Azure File Share created for FSLogix |
| <a name="output_vnetrange"></a> [vnetrange](#output\_vnetrange) | Address range for deployment vnet |
<!--- END_TF_DOCS --->

View File

@ -0,0 +1,43 @@
## Create a Resource Group for Storage
resource "azurerm_resource_group" "rg_storage" {
location = var.deploy_location
name = var.rg_stor
}
# generate a random string (consisting of four characters)
# https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string
resource "random_string" "random" {
length = 4
upper = false
special = false
}
## Azure Storage Accounts requires a globally unique names
## https://docs.microsoft.com/en-us/azure/storage/common/storage-account-overview
## Create a File Storage Account
resource "azurerm_storage_account" "storage" {
name = "stor${random_string.random.id}"
resource_group_name = azurerm_resource_group.rg_storage.name
location = azurerm_resource_group.rg_storage.location
account_tier = "Premium"
account_replication_type = "LRS"
account_kind = "FileStorage"
}
resource "azurerm_storage_share" "FSShare" {
name = "fslogix"
storage_account_name = azurerm_storage_account.storage.name
depends_on = [azurerm_storage_account.storage]
}
## Azure built-in roles
## https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles
data "azurerm_role_definition" "storage_role" {
name = "Storage File Data SMB Share Contributor"
}
resource "azurerm_role_assignment" "af_role" {
scope = azurerm_storage_account.storage.id
role_definition_id = data.azurerm_role_definition.storage_role.id
principal_id = azuread_group.aad_group.id
}

View File

@ -0,0 +1,20 @@
# Customized the sample values below for your environment and either rename to terraform.tfvars or env.auto.tfvars
deploy_location = "west europe"
rg_name = "avd-resources-rg"
prefix = "avdtf"
local_admin_username = "localadm"
local_admin_password = "ChangeMe123$"
vnet_range = ["10.1.0.0/16"]
subnet_range = ["10.1.0.0/24"]
dns_servers = ["10.0.1.4", "168.63.129.16"]
aad_group_name = "AVDUsers"
domain_name = "infra.local"
domain_user_upn = "admin" # do not include domain name as this is appended
domain_password = "ChangeMe123!"
ad_vnet = "infra-network"
ad_rg = "infra-rg"
avd_users = [
"avduser01@infra.local",
"avduser01@infra.local"
]

View File

@ -0,0 +1,131 @@
locals {
registration_token = azurerm_virtual_desktop_host_pool_registration_info.registrationinfo.token
}
resource "random_string" "AVD_local_password" {
count = var.rdsh_count
length = 16
special = true
min_special = 2
override_special = "*!@#?"
}
resource "azurerm_resource_group" "rg" {
name = var.rg
location = var.resource_group_location
}
resource "azurerm_network_interface" "avd_vm_nic" {
count = var.rdsh_count
name = "${var.prefix}-${count.index + 1}-nic"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
ip_configuration {
name = "nic${count.index + 1}_config"
subnet_id = azurerm_subnet.subnet.id
private_ip_address_allocation = "dynamic"
}
depends_on = [
azurerm_resource_group.rg
]
}
resource "azurerm_windows_virtual_machine" "avd_vm" {
count = var.rdsh_count
name = "${var.prefix}-${count.index + 1}"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
size = var.vm_size
network_interface_ids = ["${azurerm_network_interface.avd_vm_nic.*.id[count.index]}"]
provision_vm_agent = true
admin_username = var.local_admin_username
admin_password = var.local_admin_password
os_disk {
name = "${lower(var.prefix)}-${count.index + 1}"
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsDesktop"
offer = "Windows-10"
sku = "20h2-evd"
version = "latest"
}
depends_on = [
azurerm_resource_group.rg,
azurerm_network_interface.avd_vm_nic
]
}
resource "azurerm_virtual_machine_extension" "domain_join" {
count = var.rdsh_count
name = "${var.prefix}-${count.index + 1}-domainJoin"
virtual_machine_id = azurerm_windows_virtual_machine.avd_vm.*.id[count.index]
publisher = "Microsoft.Compute"
type = "JsonADDomainExtension"
type_handler_version = "1.3"
auto_upgrade_minor_version = true
settings = <<SETTINGS
{
"Name": "${var.domain_name}",
"OUPath": "${var.ou_path}",
"User": "${var.domain_user_upn}@${var.domain_name}",
"Restart": "true",
"Options": "3"
}
SETTINGS
protected_settings = <<PROTECTED_SETTINGS
{
"Password": "${var.domain_password}"
}
PROTECTED_SETTINGS
lifecycle {
ignore_changes = [settings, protected_settings]
}
depends_on = [
azurerm_virtual_network_peering.peer1,
azurerm_virtual_network_peering.peer2
]
}
resource "azurerm_virtual_machine_extension" "vmext_dsc" {
count = var.rdsh_count
name = "${var.prefix}${count.index + 1}-avd_dsc"
virtual_machine_id = azurerm_windows_virtual_machine.avd_vm.*.id[count.index]
publisher = "Microsoft.Powershell"
type = "DSC"
type_handler_version = "2.73"
auto_upgrade_minor_version = true
settings = <<-SETTINGS
{
"modulesUrl": "https://wvdportalstorageblob.blob.core.windows.net/galleryartifacts/Configuration_3-10-2021.zip",
"configurationFunction": "Configuration.ps1\\AddSessionHost",
"properties": {
"HostPoolName":"${azurerm_virtual_desktop_host_pool.hostpool.name}"
}
}
SETTINGS
protected_settings = <<PROTECTED_SETTINGS
{
"properties": {
"registrationInfoToken": "${local.registration_token}"
}
}
PROTECTED_SETTINGS
depends_on = [
azurerm_virtual_machine_extension.domain_join,
azurerm_virtual_desktop_host_pool.hostpool
]
}

View File

@ -0,0 +1,14 @@
resource "azurerm_resource_group" "log" {
name = var.rg_shared_name
location = var.deploy_location
}
# Creates Log Anaylytics Workspace
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/log_analytics_workspace
resource "azurerm_log_analytics_workspace" "law" {
name = "log${random_string.random.id}"
location = azurerm_resource_group.log.location
resource_group_name = azurerm_resource_group.log.name
sku = "PerGB2018"
retention_in_days = 30
}

View File

@ -0,0 +1,51 @@
# Resource group name is output when execution plan is applied.
resource "azurerm_resource_group" "sh" {
name = var.rg_name
location = var.resource_group_location
}
# Create AVD workspace
resource "azurerm_virtual_desktop_workspace" "workspace" {
name = var.workspace
resource_group_name = azurerm_resource_group.sh.name
location = azurerm_resource_group.sh.location
friendly_name = "${var.prefix} Workspace"
description = "${var.prefix} Workspace"
}
# Create AVD host pool
resource "azurerm_virtual_desktop_host_pool" "hostpool" {
resource_group_name = azurerm_resource_group.sh.name
location = azurerm_resource_group.sh.location
name = var.hostpool
friendly_name = var.hostpool
validate_environment = true
custom_rdp_properties = "audiocapturemode:i:1;audiomode:i:0;"
description = "${var.prefix} Terraform HostPool"
type = "Pooled"
maximum_sessions_allowed = 16
load_balancer_type = "DepthFirst" #[BreadthFirst DepthFirst]
}
resource "azurerm_virtual_desktop_host_pool_registration_info" "registrationinfo" {
hostpool_id = azurerm_virtual_desktop_host_pool.hostpool.id
expiration_date = var.rfc3339
}
# Create AVD DAG
resource "azurerm_virtual_desktop_application_group" "dag" {
resource_group_name = azurerm_resource_group.sh.name
host_pool_id = azurerm_virtual_desktop_host_pool.hostpool.id
location = azurerm_resource_group.sh.location
type = "Desktop"
name = "${var.prefix}-dag"
friendly_name = "Desktop AppGroup"
description = "AVD application group"
depends_on = [azurerm_virtual_desktop_host_pool.hostpool, azurerm_virtual_desktop_workspace.workspace]
}
# Associate Workspace and DAG
resource "azurerm_virtual_desktop_workspace_application_group_association" "ws-dag" {
application_group_id = azurerm_virtual_desktop_application_group.dag.id
workspace_id = azurerm_virtual_desktop_workspace.workspace.id
}

View File

@ -0,0 +1,57 @@
resource "azurerm_virtual_network" "vnet" {
name = "${var.prefix}-VNet"
address_space = var.vnet_range
dns_servers = var.dns_servers
location = var.deploy_location
resource_group_name = var.rg_name
depends_on = [azurerm_resource_group.rg]
}
resource "azurerm_subnet" "subnet" {
name = "default"
resource_group_name = var.rg_name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = var.subnet_range
depends_on = [azurerm_resource_group.rg]
}
resource "azurerm_network_security_group" "nsg" {
name = "${var.prefix}-NSG"
location = var.deploy_location
resource_group_name = var.rg_name
security_rule {
name = "HTTPS"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = "*"
}
depends_on = [azurerm_resource_group.rg]
}
resource "azurerm_subnet_network_security_group_association" "nsg_assoc" {
subnet_id = azurerm_subnet.subnet.id
network_security_group_id = azurerm_network_security_group.nsg.id
}
data "azurerm_virtual_network" "ad_vnet_data" {
name = var.ad_vnet
resource_group_name = var.ad_rg
}
resource "azurerm_virtual_network_peering" "peer1" {
name = "peer_avdspoke_ad"
resource_group_name = var.rg_name
virtual_network_name = azurerm_virtual_network.vnet.name
remote_virtual_network_id = data.azurerm_virtual_network.ad_vnet_data.id
}
resource "azurerm_virtual_network_peering" "peer2" {
name = "peer_ad_avdspoke"
resource_group_name = var.ad_rg
virtual_network_name = var.ad_vnet
remote_virtual_network_id = azurerm_virtual_network.vnet.id
}

View File

@ -0,0 +1,54 @@
output "azure_virtual_desktop_compute_resource_group" {
description = "Name of the Resource group in which to deploy session host"
value = azurerm_resource_group.rg.name
}
output "azure_virtual_desktop_host_pool" {
description = "Name of the Azure Virtual Desktop host pool"
value = azurerm_virtual_desktop_host_pool.hostpool.name
}
output "azurerm_virtual_desktop_application_group" {
description = "Name of the Azure Virtual Desktop DAG"
value = azurerm_virtual_desktop_application_group.dag.name
}
output "azurerm_virtual_desktop_workspace" {
description = "Name of the Azure Virtual Desktop workspace"
value = azurerm_virtual_desktop_workspace.workspace.name
}
output "location" {
description = "The Azure region"
value = azurerm_resource_group.rg.location
}
output "storage_account" {
description = "Storage account for Profiles"
value = azurerm_storage_account.storage.name
}
output "storage_account_share" {
description = "Name of the Azure File Share created for FSLogix"
value = azurerm_storage_share.FSShare.name
}
output "session_host_count" {
description = "The number of VMs created"
value = var.rdsh_count
}
output "dnsservers" {
description = "Custom DNS configuration"
value = azurerm_virtual_network.vnet.dns_servers
}
output "vnetrange" {
description = "Address range for deployment vnet"
value = azurerm_virtual_network.vnet.address_space
}
output "AVD_user_groupname" {
description = "Azure Active Directory Group for AVD users"
value = azuread_group.aad_group.display_name
}

View File

@ -0,0 +1,15 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>2.0"
}
azuread = {
source = "hashicorp/azuread"
}
}
}
provider "azurerm" {
features {}
}

View File

@ -0,0 +1,25 @@
data "azuread_user" "aad_user" {
for_each = toset(var.avd_users)
user_principal_name = format("%s", each.key)
}
data "azurerm_role_definition" "role" { # access an existing built-in role
name = "Desktop Virtualization User"
}
resource "azuread_group" "aad_group" {
display_name = var.aad_group_name
security_enabled = true
}
resource "azuread_group_member" "aad_group_member" {
for_each = data.azuread_user.aad_user
group_object_id = azuread_group.aad_group.id
member_object_id = each.value["id"]
}
resource "azurerm_role_assignment" "role" {
scope = azurerm_virtual_desktop_application_group.dag.id
role_definition_id = data.azurerm_role_definition.role.id
principal_id = azuread_group.aad_group.id
}

View File

@ -0,0 +1,44 @@
resource "azurerm_resource_group" "sigrg" {
location = var.deploy_location
name = var.rg_shared_name
}
# generate a random string (consisting of four characters)
# https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string
resource "random_string" "rando" {
length = 4
upper = false
special = false
}
# Creates Shared Image Gallery
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/shared_image_gallery
resource "azurerm_shared_image_gallery" "sig" {
name = "sig${random_string.random.id}"
resource_group_name = azurerm_resource_group.sigrg.name
location = azurerm_resource_group.sigrg.location
description = "Shared images"
tags = {
Environment = "Demo"
Tech = "Terraform"
}
}
#Creates image definition
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/shared_image
resource "azurerm_shared_image" "example" {
name = "avd-image"
gallery_name = azurerm_shared_image_gallery.sig.name
resource_group_name = azurerm_resource_group.sigrg.name
location = azurerm_resource_group.sigrg.location
os_type = "Windows"
identifier {
publisher = "MicrosoftWindowsDesktop"
offer = "office-365"
sku = "20h2-evd-o365pp"
}
}

View File

@ -0,0 +1,148 @@
variable "resource_group_location" {
default = "eastus"
description = "Location of the resource group."
}
variable "rg" {
type = string
default = "rg-avd-compute"
description = "Name of the Resource group in which to deploy session host"
}
variable "rg_name" {
type = string
default = "rg-avd-resources"
description = "Name of the Resource group in which to deploy service objects"
}
variable "rg_stor" {
type = string
default = "rg-avd-storage"
description = "Name of the Resource group in which to deploy storage"
}
variable "rg_shared_name" {
type = string
default = "rg-shared-resources"
description = "Name of the Resource group in which to deploy shared resources"
}
variable "deploy_location" {
type = string
default = "eastus"
description = "The Azure Region in which all resources in this example should be created."
}
variable "workspace" {
type = string
description = "Name of the Azure Virtual Desktop workspace"
default = "AVD TF Workspace"
}
variable "hostpool" {
type = string
description = "Name of the Azure Virtual Desktop host pool"
default = "AVD-TF-HP"
}
variable "ad_vnet" {
type = string
default = "infra-network"
description = "Name of domain controller vnet"
}
variable "rfc3339" {
type = string
default = "2022-03-30T12:43:13Z"
description = "Registration token expiration"
}
variable "dns_servers" {
type = list(string)
default = ["10.0.1.4", "168.63.129.16"]
description = "Custom DNS configuration"
}
variable "vnet_range" {
type = list(string)
default = ["10.2.0.0/16"]
description = "Address range for deployment VNet"
}
variable "subnet_range" {
type = list(string)
default = ["10.2.0.0/24"]
description = "Address range for session host subnet"
}
variable "ad_rg" {
type = string
default = "infra-rg"
description = "The resource group for AD VM"
}
variable "avd_users" {
description = "AVD users"
default = [
"avduser01@contoso.net",
"avduser02@contoso.net"
]
}
variable "aad_group_name" {
type = string
default = "AVDUsers"
description = "Azure Active Directory Group for AVD users"
}
variable "rdsh_count" {
description = "Number of AVD machines to deploy"
default = 2
}
variable "prefix" {
type = string
default = "avdtf"
description = "Prefix of the name of the AVD machine(s)"
}
variable "domain_name" {
type = string
default = "infra.local"
description = "Name of the domain to join"
}
variable "domain_user_upn" {
type = string
default = "domainjoineruser" # do not include domain name as this is appended
description = "Username for domain join (do not include domain name as this is appended)"
}
variable "domain_password" {
type = string
default = "ChangeMe123!"
description = "Password of the user to authenticate with the domain"
sensitive = true
}
variable "vm_size" {
description = "Size of the machine to deploy"
default = "Standard_DS2_v2"
}
variable "ou_path" {
default = ""
}
variable "local_admin_username" {
type = string
default = "localadm"
description = "local admin username"
}
variable "local_admin_password" {
type = string
default = "ChangeMe123!"
description = "local admin password"
sensitive = true
}

View File

@ -0,0 +1,199 @@
# Cosmos db with role definition and assignment
This template deploys a cosmos db account with sql db and aad role definition and assignment. A similar example can be created using the [azurerm/cosmosdb module](https://github.com/azure/terraform-azurerm-cosmosdb).
## Terraform resource types
- [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group)
- [azurerm_cosmosdb_account](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_account)
- [azurerm_cosmosdb_sql_database](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_sql_database)
- [azurerm_cosmosdb_sql_container](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_sql_container)
- [azurerm_cosmosdb_sql_role_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_sql_role_assignment)
- [azurerm_cosmosdb_sql_role_definition](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_sql_role_definition)
## Variables
| Name | Description |
|-|-|
| `resource_group_name` | Resource group name |
| `resource_group_location` | Resource group location |
| `cosmosdb_account_name` | Cosmos db account name |
| `cosmosdb_location` | Cosmos db primary location |
| `throughput` | DB manual throughput |
| `sql_container_name` | Name of sql container |
## Example terraform.tfvars file
```
resource_group_name = "rg-cosmosdb-101"
location = "centralus"
cosmosdb_account_name = "cosmosdb-dev-centralus-101"
cosmosdb_account_location = "centralus"
cosmosdb_sqldb_name = "sqlapidb"
throughput = 400
sql_container_name = "example-container"
```
## Usage
```bash
>terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# azurerm_cosmosdb_account.example will be created
+ resource "azurerm_cosmosdb_account" "example" {
+ access_key_metadata_writes_enabled = true
+ analytical_storage_enabled = false
+ connection_strings = (sensitive value)
+ create_mode = (known after apply)
+ default_identity_type = "FirstPartyIdentity"
+ enable_automatic_failover = false
+ enable_free_tier = false
+ enable_multiple_write_locations = false
+ endpoint = (known after apply)
+ id = (known after apply)
+ is_virtual_network_filter_enabled = false
+ kind = "GlobalDocumentDB"
+ local_authentication_disabled = false
+ location = "centralus"
+ mongo_server_version = (known after apply)
+ name = "cosmosdb-dev-centralus-101"
+ network_acl_bypass_for_azure_services = false
+ offer_type = "Standard"
+ primary_key = (sensitive value)
+ primary_readonly_key = (sensitive value)
+ public_network_access_enabled = true
+ read_endpoints = (known after apply)
+ resource_group_name = "rg-cosmosdb-101"
+ secondary_key = (sensitive value)
+ secondary_readonly_key = (sensitive value)
+ write_endpoints = (known after apply)
+ analytical_storage {
+ schema_type = (known after apply)
}
+ backup {
+ interval_in_minutes = (known after apply)
+ retention_in_hours = (known after apply)
+ storage_redundancy = (known after apply)
+ type = (known after apply)
}
+ capabilities {
+ name = (known after apply)
}
+ capacity {
+ total_throughput_limit = (known after apply)
}
+ consistency_policy {
+ consistency_level = "BoundedStaleness"
+ max_interval_in_seconds = 300
+ max_staleness_prefix = 100000
}
+ geo_location {
+ failover_priority = 0
+ id = (known after apply)
+ location = "centralus"
+ zone_redundant = false
}
}
# azurerm_cosmosdb_sql_container.example will be created
+ resource "azurerm_cosmosdb_sql_container" "example" {
+ account_name = "cosmosdb-dev-centralus-101"
+ database_name = "sqlapidb"
+ default_ttl = (known after apply)
+ id = (known after apply)
+ name = "example-container"
+ partition_key_path = "/definition/id"
+ partition_key_version = 1
+ resource_group_name = "rg-cosmosdb-101"
+ throughput = 400
+ conflict_resolution_policy {
+ conflict_resolution_path = (known after apply)
+ conflict_resolution_procedure = (known after apply)
+ mode = (known after apply)
}
+ indexing_policy {
+ indexing_mode = "consistent"
+ excluded_path {
+ path = "/excluded/?"
}
+ included_path {
+ path = "/*"
}
+ included_path {
+ path = "/included/?"
}
}
+ unique_key {
+ paths = [
+ "/definition/idlong",
+ "/definition/idshort",
]
}
}
# azurerm_cosmosdb_sql_database.example will be created
+ resource "azurerm_cosmosdb_sql_database" "example" {
+ account_name = "cosmosdb-dev-centralus-101"
+ id = (known after apply)
+ name = "sqlapidb"
+ resource_group_name = "rg-cosmosdb-101"
+ throughput = 400
}
# azurerm_cosmosdb_sql_role_assignment.example will be created
+ resource "azurerm_cosmosdb_sql_role_assignment" "example" {
+ account_name = "cosmosdb-dev-centralus-101"
+ id = (known after apply)
+ name = (known after apply)
+ principal_id = "1b887731-4609-4904-a699-64f06f3d380d"
+ resource_group_name = "rg-cosmosdb-101"
+ role_definition_id = (known after apply)
+ scope = "/subscriptions/aa86e73d-372b-4cd6-a37e-0d12ae93e964/resourceGroups/rg-cosmosdb-101/providers/Microsoft.DocumentDB/databaseAccounts/cosmosdb-dev-centralus-101"
}
# azurerm_cosmosdb_sql_role_definition.example will be created
+ resource "azurerm_cosmosdb_sql_role_definition" "example" {
+ account_name = "cosmosdb-dev-centralus-101"
+ assignable_scopes = [
+ "/subscriptions/aa86e73d-372b-4cd6-a37e-0d12ae93e964/resourceGroups/rg-cosmosdb-101/providers/Microsoft.DocumentDB/databaseAccounts/cosmosdb-dev-centralus-101",
]
+ id = (known after apply)
+ name = "examplesqlroledef"
+ resource_group_name = "rg-cosmosdb-101"
+ role_definition_id = (known after apply)
+ type = "CustomRole"
+ permissions {
+ data_actions = [
+ "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read",
]
}
}
# azurerm_resource_group.example will be created
+ resource "azurerm_resource_group" "example" {
+ id = (known after apply)
+ location = "centralus"
+ name = "rg-cosmosdb-101"
}
Plan: 6 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ cosmosdb_account_id = (known after apply)
+ cosmosdb_sql_database_id = (known after apply)
```

View File

@ -0,0 +1,86 @@
data "azurerm_client_config" "current" {}
resource "azurerm_resource_group" "example" {
name = var.resource_group_name
location = var.location
}
resource "azurerm_cosmosdb_account" "example" {
name = var.cosmosdb_account_name
location = var.cosmosdb_account_location
resource_group_name = azurerm_resource_group.example.name
offer_type = "Standard"
kind = "GlobalDocumentDB"
enable_automatic_failover = false
geo_location {
location = var.location
failover_priority = 0
}
consistency_policy {
consistency_level = "BoundedStaleness"
max_interval_in_seconds = 300
max_staleness_prefix = 100000
}
depends_on = [
azurerm_resource_group.example
]
}
resource "azurerm_cosmosdb_sql_database" "example" {
name = var.cosmosdb_sqldb_name
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_cosmosdb_account.example.name
throughput = var.throughput
}
resource "azurerm_cosmosdb_sql_container" "example" {
name = var.sql_container_name
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_cosmosdb_account.example.name
database_name = azurerm_cosmosdb_sql_database.example.name
partition_key_path = "/definition/id"
partition_key_version = 1
throughput = 400
indexing_policy {
indexing_mode = "consistent"
included_path {
path = "/*"
}
included_path {
path = "/included/?"
}
excluded_path {
path = "/excluded/?"
}
}
unique_key {
paths = ["/definition/idlong", "/definition/idshort"]
}
}
resource "azurerm_cosmosdb_sql_role_definition" "example" {
name = "examplesqlroledef"
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_cosmosdb_account.example.name
type = "CustomRole"
assignable_scopes = ["/subscriptions/${data.azurerm_client_config.current.subscription_id}/resourceGroups/${azurerm_resource_group.example.name}/providers/Microsoft.DocumentDB/databaseAccounts/${azurerm_cosmosdb_account.example.name}"]
permissions {
data_actions = ["Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read"]
}
}
resource "azurerm_cosmosdb_sql_role_assignment" "example" {
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_cosmosdb_account.example.name
role_definition_id = azurerm_cosmosdb_sql_role_definition.example.id
principal_id = data.azurerm_client_config.current.object_id
scope = "/subscriptions/${data.azurerm_client_config.current.subscription_id}/resourceGroups/${azurerm_resource_group.example.name}/providers/Microsoft.DocumentDB/databaseAccounts/${azurerm_cosmosdb_account.example.name}"
}

View File

@ -0,0 +1,7 @@
output "cosmosdb_account_id" {
value = azurerm_cosmosdb_account.example.id
}
output "cosmosdb_sql_database_id" {
value = azurerm_cosmosdb_sql_database.example.id
}

View File

@ -0,0 +1,12 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=3.0.0"
}
}
}
provider "azurerm" {
features {}
}

View File

@ -0,0 +1,42 @@
variable "resource_group_name" {
type = string
description = "Resource group name"
}
variable "location" {
type = string
description = "Resource group location"
}
variable "cosmosdb_account_name" {
type = string
description = "Cosmos db account name"
}
variable "cosmosdb_account_location" {
type = string
description = "Cosmos db account location"
}
variable "cosmosdb_sqldb_name" {
type = string
description = "value"
}
variable "throughput" {
type = number
description = "Cosmos db database throughput"
validation {
condition = var.throughput >= 400 && var.throughput <= 1000000
error_message = "Cosmos db manual throughput should be equal to or greater than 400 and less than or equal to 1000000."
}
validation {
condition = var.throughput % 100 == 0
error_message = "Cosmos db throughput should be in increments of 100."
}
}
variable "sql_container_name" {
type = string
description = "SQL API container name."
}

View File

@ -0,0 +1,172 @@
# Cosmos db analytical storage with SQL DB
This template deploys a cosmos db account with sql db and analytical store enabled. A similar example can be created using the [azurerm/cosmosdb module](https://github.com/azure/terraform-azurerm-cosmosdb).
## Terraform resource types
- [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group)
- [azurerm_cosmosdb_account](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_account)
- [azurerm_cosmosdb_sql_database](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_sql_database)
- [azurerm_cosmosdb_sql_container](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_sql_container)
## Variables
| Name | Description |
|-|-|
| `resource_group_name` | Resource group name |
| `resource_group_location` | Resource group location |
| `cosmosdb_account_name` | Cosmos db account name |
| `cosmosdb_location` | Cosmos db primary location |
| `throughput` | DB manual throughput |
| `sql_container_name` | Name of sql container |
| `analytical_storage_ttl` | TTL of items in container |
## Example terraform.tfvars file
```
resource_group_name = "rg-cosmosdb-101"
location = "centralus"
cosmosdb_account_name = "cosmosdb-dev-centralus-101"
cosmosdb_account_location = "centralus"
cosmosdb_sqldb_name = "sqlapidb"
throughput = 400
sql_container_name = "example-container"
analytical_storage_ttl = 600
```
## Usage
```bash
>terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# azurerm_cosmosdb_account.example will be created
+ resource "azurerm_cosmosdb_account" "example" {
+ access_key_metadata_writes_enabled = true
+ analytical_storage_enabled = true
+ connection_strings = (sensitive value)
+ create_mode = (known after apply)
+ default_identity_type = "FirstPartyIdentity"
+ enable_automatic_failover = false
+ enable_free_tier = false
+ enable_multiple_write_locations = false
+ endpoint = (known after apply)
+ id = (known after apply)
+ is_virtual_network_filter_enabled = false
+ kind = "GlobalDocumentDB"
+ local_authentication_disabled = false
+ location = "centralus"
+ mongo_server_version = (known after apply)
+ name = "cosmosdb-dev-centralus-101"
+ network_acl_bypass_for_azure_services = false
+ offer_type = "Standard"
+ primary_key = (sensitive value)
+ primary_readonly_key = (sensitive value)
+ public_network_access_enabled = true
+ read_endpoints = (known after apply)
+ resource_group_name = "rg-cosmosdb-101"
+ secondary_key = (sensitive value)
+ secondary_readonly_key = (sensitive value)
+ write_endpoints = (known after apply)
+ analytical_storage {
+ schema_type = (known after apply)
}
+ backup {
+ interval_in_minutes = (known after apply)
+ retention_in_hours = (known after apply)
+ storage_redundancy = (known after apply)
+ type = (known after apply)
}
+ capabilities {
+ name = (known after apply)
}
+ capacity {
+ total_throughput_limit = (known after apply)
}
+ consistency_policy {
+ consistency_level = "BoundedStaleness"
+ max_interval_in_seconds = 300
+ max_staleness_prefix = 100000
}
+ geo_location {
+ failover_priority = 0
+ id = (known after apply)
+ location = "centralus"
+ zone_redundant = false
}
}
# azurerm_cosmosdb_sql_container.example will be created
+ resource "azurerm_cosmosdb_sql_container" "example" {
+ account_name = "cosmosdb-dev-centralus-101"
+ analytical_storage_ttl = 600
+ database_name = "sqlapidb"
+ default_ttl = (known after apply)
+ id = (known after apply)
+ name = "example-container"
+ partition_key_path = "/definition/id"
+ partition_key_version = 1
+ resource_group_name = "rg-cosmosdb-101"
+ throughput = 400
+ conflict_resolution_policy {
+ conflict_resolution_path = (known after apply)
+ conflict_resolution_procedure = (known after apply)
+ mode = (known after apply)
}
+ indexing_policy {
+ indexing_mode = "consistent"
+ excluded_path {
+ path = "/excluded/?"
}
+ included_path {
+ path = "/*"
}
+ included_path {
+ path = "/included/?"
}
}
+ unique_key {
+ paths = [
+ "/definition/idlong",
+ "/definition/idshort",
]
}
}
# azurerm_cosmosdb_sql_database.example will be created
+ resource "azurerm_cosmosdb_sql_database" "example" {
+ account_name = "cosmosdb-dev-centralus-101"
+ id = (known after apply)
+ name = "sqlapidb"
+ resource_group_name = "rg-cosmosdb-101"
+ throughput = 400
}
# azurerm_resource_group.example will be created
+ resource "azurerm_resource_group" "example" {
+ id = (known after apply)
+ location = "centralus"
+ name = "rg-cosmosdb-101"
}
Plan: 4 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ cosmosdb_account_id = (known after apply)
+ cosmosdb_sql_database_id = (known after apply)
```

View File

@ -0,0 +1,66 @@
resource "azurerm_resource_group" "example" {
name = var.resource_group_name
location = var.location
}
resource "azurerm_cosmosdb_account" "example" {
name = var.cosmosdb_account_name
location = var.cosmosdb_account_location
resource_group_name = azurerm_resource_group.example.name
offer_type = "Standard"
kind = "GlobalDocumentDB"
enable_automatic_failover = false
analytical_storage_enabled = true
geo_location {
location = var.location
failover_priority = 0
}
consistency_policy {
consistency_level = "BoundedStaleness"
max_interval_in_seconds = 300
max_staleness_prefix = 100000
}
depends_on = [
azurerm_resource_group.example
]
}
resource "azurerm_cosmosdb_sql_database" "example" {
name = var.cosmosdb_sqldb_name
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_cosmosdb_account.example.name
throughput = var.throughput
}
resource "azurerm_cosmosdb_sql_container" "example" {
name = var.sql_container_name
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_cosmosdb_account.example.name
database_name = azurerm_cosmosdb_sql_database.example.name
partition_key_path = "/definition/id"
partition_key_version = 1
throughput = 400
analytical_storage_ttl = var.analytical_storage_ttl
indexing_policy {
indexing_mode = "consistent"
included_path {
path = "/*"
}
included_path {
path = "/included/?"
}
excluded_path {
path = "/excluded/?"
}
}
unique_key {
paths = ["/definition/idlong", "/definition/idshort"]
}
}

View File

@ -0,0 +1,7 @@
output "cosmosdb_account_id" {
value = azurerm_cosmosdb_account.example.id
}
output "cosmosdb_sql_database_id" {
value = azurerm_cosmosdb_sql_database.example.id
}

View File

@ -0,0 +1,12 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=3.0.0"
}
}
}
provider "azurerm" {
features {}
}

View File

@ -0,0 +1,47 @@
variable "resource_group_name" {
type = string
description = "Resource group name"
}
variable "location" {
type = string
description = "Resource group location"
}
variable "cosmosdb_account_name" {
type = string
description = "Cosmos db account name"
}
variable "cosmosdb_account_location" {
type = string
description = "Cosmos db account location"
}
variable "cosmosdb_sqldb_name" {
type = string
description = "value"
}
variable "throughput" {
type = number
description = "Cosmos db database throughput"
validation {
condition = var.throughput >= 400 && var.throughput <= 1000000
error_message = "Cosmos db manual throughput should be equal to or greater than 400 and less than or equal to 1000000."
}
validation {
condition = var.throughput % 100 == 0
error_message = "Cosmos db throughput should be in increments of 100."
}
}
variable "sql_container_name" {
type = string
description = "SQL API container name."
}
variable "analytical_storage_ttl" {
type = number
description = "Analytical Storage TTL in seconds."
}

View File

@ -0,0 +1,175 @@
# Cosmos db autoscaling with SQL DB
This template deploys a cosmos db account with sql db and autoscaling enabled. A similar example can be created using the [azurerm/cosmosdb module](https://github.com/azure/terraform-azurerm-cosmosdb).
## Terraform resource types
- [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group)
- [azurerm_cosmosdb_account](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_account)
- [azurerm_cosmosdb_sql_database](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_sql_database)
- [azurerm_cosmosdb_sql_container](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_sql_container)
## Variables
| Name | Description |
|-|-|
| `resource_group_name` | Resource group name |
| `resource_group_location` | Resource group location |
| `cosmosdb_account_name` | Cosmos db account name |
| `cosmosdb_location` | Cosmos db primary location |
| `sql_container_name` | Name of sql container |
| `max_throughput` | DB Max throughput for autoscaling |
## Example terraform.tfvars file
```
resource_group_name = "rg-cosmosdb-101"
location = "centralus"
cosmosdb_account_name = "cosmosdb-dev-centralus-101"
cosmosdb_account_location = "centralus"
sql_container_name = "example-container"
cosmosdb_sqldb_name = "sqlapidb"
max_throughput = 4000
```
## Usage
```bash
>terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# azurerm_cosmosdb_account.example will be created
+ resource "azurerm_cosmosdb_account" "example" {
+ access_key_metadata_writes_enabled = true
+ analytical_storage_enabled = false
+ connection_strings = (sensitive value)
+ create_mode = (known after apply)
+ default_identity_type = "FirstPartyIdentity"
+ enable_automatic_failover = false
+ enable_free_tier = false
+ enable_multiple_write_locations = false
+ endpoint = (known after apply)
+ id = (known after apply)
+ is_virtual_network_filter_enabled = false
+ kind = "GlobalDocumentDB"
+ local_authentication_disabled = false
+ location = "centralus"
+ mongo_server_version = (known after apply)
+ name = "cosmosdb-dev-centralus-101"
+ network_acl_bypass_for_azure_services = false
+ offer_type = "Standard"
+ primary_key = (sensitive value)
+ primary_readonly_key = (sensitive value)
+ public_network_access_enabled = true
+ read_endpoints = (known after apply)
+ resource_group_name = "rg-cosmosdb-101"
+ secondary_key = (sensitive value)
+ secondary_readonly_key = (sensitive value)
+ write_endpoints = (known after apply)
+ analytical_storage {
+ schema_type = (known after apply)
}
+ backup {
+ interval_in_minutes = (known after apply)
+ retention_in_hours = (known after apply)
+ storage_redundancy = (known after apply)
+ type = (known after apply)
}
+ capabilities {
+ name = (known after apply)
}
+ capacity {
+ total_throughput_limit = (known after apply)
}
+ consistency_policy {
+ consistency_level = "BoundedStaleness"
+ max_interval_in_seconds = 300
+ max_staleness_prefix = 100000
}
+ geo_location {
+ failover_priority = 0
+ id = (known after apply)
+ location = "centralus"
+ zone_redundant = false
}
}
# azurerm_cosmosdb_sql_container.example will be created
+ resource "azurerm_cosmosdb_sql_container" "example" {
+ account_name = "cosmosdb-dev-centralus-101"
+ database_name = "sqlapidb"
+ default_ttl = (known after apply)
+ id = (known after apply)
+ name = "example-container"
+ partition_key_path = "/definition/id"
+ partition_key_version = 1
+ resource_group_name = "rg-cosmosdb-101"
+ throughput = (known after apply)
+ autoscale_settings {
+ max_throughput = 4000
}
+ conflict_resolution_policy {
+ conflict_resolution_path = (known after apply)
+ conflict_resolution_procedure = (known after apply)
+ mode = (known after apply)
}
+ indexing_policy {
+ indexing_mode = "consistent"
+ excluded_path {
+ path = "/excluded/?"
}
+ included_path {
+ path = "/*"
}
+ included_path {
+ path = "/included/?"
}
}
+ unique_key {
+ paths = [
+ "/definition/idlong",
+ "/definition/idshort",
]
}
}
# azurerm_cosmosdb_sql_database.example will be created
+ resource "azurerm_cosmosdb_sql_database" "example" {
+ account_name = "cosmosdb-dev-centralus-101"
+ id = (known after apply)
+ name = "sqlapidb"
+ resource_group_name = "rg-cosmosdb-101"
+ throughput = (known after apply)
+ autoscale_settings {
+ max_throughput = 4000
}
}
# azurerm_resource_group.example will be created
+ resource "azurerm_resource_group" "example" {
+ id = (known after apply)
+ location = "centralus"
+ name = "rg-cosmosdb-101"
}
Plan: 4 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ cosmosdb_account_id = (known after apply)
+ cosmosdb_sql_database_id = (known after apply)
```

View File

@ -0,0 +1,66 @@
resource "azurerm_resource_group" "example" {
name = var.resource_group_name
location = var.location
}
resource "azurerm_cosmosdb_account" "example" {
name = var.cosmosdb_account_name
location = var.cosmosdb_account_location
resource_group_name = azurerm_resource_group.example.name
offer_type = "Standard"
kind = "GlobalDocumentDB"
enable_automatic_failover = false
geo_location {
location = var.location
failover_priority = 0
}
consistency_policy {
consistency_level = "BoundedStaleness"
max_interval_in_seconds = 300
max_staleness_prefix = 100000
}
depends_on = [
azurerm_resource_group.example
]
}
resource "azurerm_cosmosdb_sql_database" "example" {
name = var.cosmosdb_sqldb_name
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_cosmosdb_account.example.name
autoscale_settings {
max_throughput = var.max_throughput
}
}
resource "azurerm_cosmosdb_sql_container" "example" {
name = var.sql_container_name
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_cosmosdb_account.example.name
database_name = azurerm_cosmosdb_sql_database.example.name
partition_key_path = "/definition/id"
partition_key_version = 1
autoscale_settings {
max_throughput = var.max_throughput
}
indexing_policy {
indexing_mode = "consistent"
included_path {
path = "/*"
}
included_path {
path = "/included/?"
}
excluded_path {
path = "/excluded/?"
}
}
unique_key {
paths = ["/definition/idlong", "/definition/idshort"]
}
}

View File

@ -0,0 +1,7 @@
output "cosmosdb_account_id" {
value = azurerm_cosmosdb_account.example.id
}
output "cosmosdb_sql_database_id" {
value = azurerm_cosmosdb_sql_database.example.id
}

View File

@ -0,0 +1,12 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=3.0.0"
}
}
}
provider "azurerm" {
features {}
}

View File

@ -0,0 +1,43 @@
variable "resource_group_name" {
type = string
description = "Resource group name"
}
variable "location" {
type = string
description = "Resource group location"
}
variable "cosmosdb_account_name" {
type = string
description = "Cosmos db account name"
}
variable "cosmosdb_account_location" {
type = string
description = "Cosmos db account location"
}
variable "cosmosdb_sqldb_name" {
type = string
description = "value"
}
variable "sql_container_name" {
type = string
description = "SQL API container name."
}
variable "max_throughput" {
type = number
description = "Cosmos db database max throughput"
validation {
condition = var.max_throughput >= 4000 && var.max_throughput <= 1000000
error_message = "Cosmos db autoscale max throughput should be equal to or greater than 4000 and less than or equal to 1000000."
}
validation {
condition = var.max_throughput % 100 == 0
error_message = "Cosmos db max throughput should be in increments of 100."
}
}

View File

@ -0,0 +1,168 @@
# Cosmos db free tier
This template deploys a cosmos db account with sql db and manual scaling in free tier. A similar example can be created using the [azurerm/cosmosdb module](https://github.com/azure/terraform-azurerm-cosmosdb).
## Terraform resource types
- [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group)
- [azurerm_cosmosdb_account](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_account)
- [azurerm_cosmosdb_sql_database](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_sql_database)
- [azurerm_cosmosdb_sql_container](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_sql_container)
## Variables
| Name | Description |
|-|-|
| `resource_group_name` | Resource group name |
| `resource_group_location` | Resource group location |
| `cosmosdb_account_name` | Cosmos db account name |
| `cosmosdb_location` | Cosmos db primary location |
| `sql_container_name` | Name of sql container |
| `throughput` | DB manual throughput |
## Example terraform.tfvars file
```
resource_group_name = "rg-cosmosdb-101"
location = "centralus"
cosmosdb_account_name = "cosmosdb-dev-centralus-101"
cosmosdb_account_location = "centralus"
cosmosdb_sqldb_name = "sqlapidb"
sql_container_name = "example-container"
throughput = 400
```
## Usage
```bash
>terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# azurerm_cosmosdb_account.example will be created
+ resource "azurerm_cosmosdb_account" "example" {
+ access_key_metadata_writes_enabled = true
+ analytical_storage_enabled = false
+ connection_strings = (sensitive value)
+ create_mode = (known after apply)
+ default_identity_type = "FirstPartyIdentity"
+ enable_automatic_failover = false
+ enable_free_tier = true
+ enable_multiple_write_locations = false
+ endpoint = (known after apply)
+ id = (known after apply)
+ is_virtual_network_filter_enabled = false
+ kind = "GlobalDocumentDB"
+ local_authentication_disabled = false
+ location = "centralus"
+ mongo_server_version = (known after apply)
+ name = "cosmosdb-dev-centralus-101"
+ network_acl_bypass_for_azure_services = false
+ offer_type = "Standard"
+ primary_key = (sensitive value)
+ primary_readonly_key = (sensitive value)
+ public_network_access_enabled = true
+ read_endpoints = (known after apply)
+ resource_group_name = "rg-cosmosdb-101"
+ secondary_key = (sensitive value)
+ secondary_readonly_key = (sensitive value)
+ write_endpoints = (known after apply)
+ analytical_storage {
+ schema_type = (known after apply)
}
+ backup {
+ interval_in_minutes = (known after apply)
+ retention_in_hours = (known after apply)
+ storage_redundancy = (known after apply)
+ type = (known after apply)
}
+ capabilities {
+ name = (known after apply)
}
+ capacity {
+ total_throughput_limit = (known after apply)
}
+ consistency_policy {
+ consistency_level = "BoundedStaleness"
+ max_interval_in_seconds = 300
+ max_staleness_prefix = 100000
}
+ geo_location {
+ failover_priority = 0
+ id = (known after apply)
+ location = "centralus"
+ zone_redundant = false
}
}
# azurerm_cosmosdb_sql_container.example will be created
+ resource "azurerm_cosmosdb_sql_container" "example" {
+ account_name = "cosmosdb-dev-centralus-101"
+ database_name = "sqlapidb"
+ default_ttl = (known after apply)
+ id = (known after apply)
+ name = "example-container"
+ partition_key_path = "/definition/id"
+ partition_key_version = 1
+ resource_group_name = "rg-cosmosdb-101"
+ throughput = 400
+ conflict_resolution_policy {
+ conflict_resolution_path = (known after apply)
+ conflict_resolution_procedure = (known after apply)
+ mode = (known after apply)
}
+ indexing_policy {
+ indexing_mode = "consistent"
+ excluded_path {
+ path = "/excluded/?"
}
+ included_path {
+ path = "/*"
}
+ included_path {
+ path = "/included/?"
}
}
+ unique_key {
+ paths = [
+ "/definition/idlong",
+ "/definition/idshort",
]
}
}
# azurerm_cosmosdb_sql_database.example will be created
+ resource "azurerm_cosmosdb_sql_database" "example" {
+ account_name = "cosmosdb-dev-centralus-101"
+ id = (known after apply)
+ name = "sqlapidb"
+ resource_group_name = "rg-cosmosdb-101"
+ throughput = 400
}
# azurerm_resource_group.example will be created
+ resource "azurerm_resource_group" "example" {
+ id = (known after apply)
+ location = "centralus"
+ name = "rg-cosmosdb-101"
}
Plan: 4 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ cosmosdb_account_id = (known after apply)
+ cosmosdb_sql_database_id = (known after apply)
```

View File

@ -0,0 +1,63 @@
resource "azurerm_resource_group" "example" {
name = var.resource_group_name
location = var.location
}
resource "azurerm_cosmosdb_account" "example" {
name = var.cosmosdb_account_name
location = var.cosmosdb_account_location
resource_group_name = azurerm_resource_group.example.name
offer_type = "Standard"
kind = "GlobalDocumentDB"
enable_automatic_failover = false
enable_free_tier = true
geo_location {
location = var.location
failover_priority = 0
}
consistency_policy {
consistency_level = "BoundedStaleness"
max_interval_in_seconds = 300
max_staleness_prefix = 100000
}
depends_on = [
azurerm_resource_group.example
]
}
resource "azurerm_cosmosdb_sql_database" "example" {
name = var.cosmosdb_sqldb_name
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_cosmosdb_account.example.name
throughput = var.throughput
}
resource "azurerm_cosmosdb_sql_container" "example" {
name = var.sql_container_name
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_cosmosdb_account.example.name
database_name = azurerm_cosmosdb_sql_database.example.name
partition_key_path = "/definition/id"
partition_key_version = 1
throughput = var.throughput
indexing_policy {
indexing_mode = "consistent"
included_path {
path = "/*"
}
included_path {
path = "/included/?"
}
excluded_path {
path = "/excluded/?"
}
}
unique_key {
paths = ["/definition/idlong", "/definition/idshort"]
}
}

Some files were not shown because too many files have changed in this diff Show More