From 415e3caa9780a31a20dfd78a75bb5e24f80f6602 Mon Sep 17 00:00:00 2001 From: Joey Lorich Date: Tue, 15 Oct 2019 13:03:36 -0600 Subject: [PATCH] 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 --- .gitignore | 580 +++++----- .gitmodules | 208 ++-- LICENSE | 42 +- README.md | 48 +- module/CONTRIBUTE.md | 74 +- quickstart/101-storage-static-website/main.tf | 13 + .../101-storage-static-website/readme.md | 147 +++ .../storage_account.tf | 14 + .../101-storage-static-website/variables.tf | 15 + .../app_service.tf | 31 + .../101-web-app-linux-container/main.tf | 8 + .../101-web-app-linux-container/readme.md | 207 ++++ .../101-web-app-linux-container/variables.tf | 35 + .../101-web-app-linux-java/app_service.tf | 29 + quickstart/101-web-app-linux-java/main.tf | 8 + quickstart/101-web-app-linux-java/readme.md | 210 ++++ .../101-web-app-linux-java/variables.tf | 35 + .../101-web-app-windows-dotnet/app_service.tf | 23 + quickstart/101-web-app-windows-dotnet/main.tf | 8 + .../101-web-app-windows-dotnet/readme.md | 199 ++++ .../101-web-app-windows-dotnet/variables.tf | 35 + quickstart/201-aks-acr-identity/acr.tf | 10 + quickstart/201-aks-acr-identity/aks.tf | 24 + quickstart/201-aks-acr-identity/azuread.tf | 30 + quickstart/201-aks-acr-identity/main.tf | 18 + quickstart/201-aks-acr-identity/readme.md | 226 ++++ quickstart/201-aks-acr-identity/variables.tf | 40 + .../readme.md} | 0 quickstart/201-aks-gpu-nodepool/readme.md | 31 + quickstart/201-aks-helm/aks.tf | 24 + quickstart/201-aks-helm/azuread.tf | 24 + quickstart/201-aks-helm/helm.tf | 20 + quickstart/201-aks-helm/kubernetes.tf | 35 + quickstart/201-aks-helm/main.tf | 18 + quickstart/201-aks-helm/readme.md | 244 +++++ quickstart/201-aks-helm/variables.tf | 40 + quickstart/201-aks-log-analytics/aks.tf | 27 + quickstart/201-aks-log-analytics/analytics.tf | 20 + quickstart/201-aks-log-analytics/azuread.tf | 24 + quickstart/201-aks-log-analytics/main.tf | 18 + quickstart/201-aks-log-analytics/readme.md | 238 +++++ quickstart/201-aks-log-analytics/variables.tf | 40 + .../201-aks-rbac-dashboard-admin/aks.tf | 24 + .../201-aks-rbac-dashboard-admin/azuread.tf | 24 + .../kubernetes.tf | 28 + .../201-aks-rbac-dashboard-admin/main.tf | 18 + .../201-aks-rbac-dashboard-admin/readme.md | 230 ++++ .../201-aks-rbac-dashboard-admin/variables.tf | 40 + .../201-azure-pipelines-ci-cd/readme.md | 18 + .../readme.md | 36 + quickstart/201-vmss-appgw-waf/readme.md | 36 + quickstart/201-web-app-docker-acr/acr.tf | 11 + .../201-web-app-docker-acr/app_service.tf | 27 + .../azurerm_role_assignment.tf | 5 + quickstart/201-web-app-docker-acr/main.tf | 11 + quickstart/201-web-app-docker-acr/readme.md | 237 +++++ .../201-web-app-docker-acr/variables.tf | 35 + .../201-web-app-postgres-keyvault/README.md | 0 .../main.tf | 10 +- .../mysql.tf | 56 +- .../output.tf | 30 +- .../providers.tf | 4 +- .../terraform.tfvars | 22 +- .../variables.tf | 130 +-- .../webapp.tf | 48 +- quickstart/201-web-app-windows-vnet/readme.md | 36 + quickstart/301-aks-enterprise/readme.md | 40 + quickstart/301-aks-windows-nodepool/readme.md | 31 + .../301-hub-spoke-network-3vm/readme.md | 33 + quickstart/301-service-fabric-apim/apim.tf | 58 + quickstart/301-service-fabric-apim/azuread.tf | 72 ++ .../301-service-fabric-apim/keyvault.tf | 168 +++ quickstart/301-service-fabric-apim/main.tf | 12 + quickstart/301-service-fabric-apim/network.tf | 100 ++ quickstart/301-service-fabric-apim/readme.md | 995 ++++++++++++++++++ .../301-service-fabric-apim/service_fabric.tf | 78 ++ .../301-service-fabric-apim/variables.tf | 55 + quickstart/301-service-fabric-apim/vmss.tf | 111 ++ quickstart/301-service-fabric/azuread.tf | 72 ++ quickstart/301-service-fabric/keyvault.tf | 168 +++ quickstart/301-service-fabric/main.tf | 12 + quickstart/301-service-fabric/network.tf | 100 ++ quickstart/301-service-fabric/readme.md | 992 +++++++++++++++++ .../301-service-fabric/service_fabric.tf | 78 ++ quickstart/301-service-fabric/variables.tf | 44 + quickstart/301-service-fabric/vmss.tf | 111 ++ quickstart/README.md | 45 + .../createUiDefinition.json | 356 +++---- .../vm-linux-terraform/mainTemplate.json | 676 ++++++------ 89 files changed, 7503 insertions(+), 1140 deletions(-) create mode 100644 quickstart/101-storage-static-website/main.tf create mode 100644 quickstart/101-storage-static-website/readme.md create mode 100644 quickstart/101-storage-static-website/storage_account.tf create mode 100644 quickstart/101-storage-static-website/variables.tf create mode 100644 quickstart/101-web-app-linux-container/app_service.tf create mode 100644 quickstart/101-web-app-linux-container/main.tf create mode 100644 quickstart/101-web-app-linux-container/readme.md create mode 100644 quickstart/101-web-app-linux-container/variables.tf create mode 100644 quickstart/101-web-app-linux-java/app_service.tf create mode 100644 quickstart/101-web-app-linux-java/main.tf create mode 100644 quickstart/101-web-app-linux-java/readme.md create mode 100644 quickstart/101-web-app-linux-java/variables.tf create mode 100644 quickstart/101-web-app-windows-dotnet/app_service.tf create mode 100644 quickstart/101-web-app-windows-dotnet/main.tf create mode 100644 quickstart/101-web-app-windows-dotnet/readme.md create mode 100644 quickstart/101-web-app-windows-dotnet/variables.tf create mode 100644 quickstart/201-aks-acr-identity/acr.tf create mode 100644 quickstart/201-aks-acr-identity/aks.tf create mode 100644 quickstart/201-aks-acr-identity/azuread.tf create mode 100644 quickstart/201-aks-acr-identity/main.tf create mode 100644 quickstart/201-aks-acr-identity/readme.md create mode 100644 quickstart/201-aks-acr-identity/variables.tf rename quickstart/{WebAppMySql/README.md => 201-aks-advanced-networking/readme.md} (100%) create mode 100644 quickstart/201-aks-gpu-nodepool/readme.md create mode 100644 quickstart/201-aks-helm/aks.tf create mode 100644 quickstart/201-aks-helm/azuread.tf create mode 100644 quickstart/201-aks-helm/helm.tf create mode 100644 quickstart/201-aks-helm/kubernetes.tf create mode 100644 quickstart/201-aks-helm/main.tf create mode 100644 quickstart/201-aks-helm/readme.md create mode 100644 quickstart/201-aks-helm/variables.tf create mode 100644 quickstart/201-aks-log-analytics/aks.tf create mode 100644 quickstart/201-aks-log-analytics/analytics.tf create mode 100644 quickstart/201-aks-log-analytics/azuread.tf create mode 100644 quickstart/201-aks-log-analytics/main.tf create mode 100644 quickstart/201-aks-log-analytics/readme.md create mode 100644 quickstart/201-aks-log-analytics/variables.tf create mode 100644 quickstart/201-aks-rbac-dashboard-admin/aks.tf create mode 100644 quickstart/201-aks-rbac-dashboard-admin/azuread.tf create mode 100644 quickstart/201-aks-rbac-dashboard-admin/kubernetes.tf create mode 100644 quickstart/201-aks-rbac-dashboard-admin/main.tf create mode 100644 quickstart/201-aks-rbac-dashboard-admin/readme.md create mode 100644 quickstart/201-aks-rbac-dashboard-admin/variables.tf create mode 100644 quickstart/201-azure-pipelines-ci-cd/readme.md create mode 100644 quickstart/201-storage-static-website-cdn-ssl/readme.md create mode 100644 quickstart/201-vmss-appgw-waf/readme.md create mode 100644 quickstart/201-web-app-docker-acr/acr.tf create mode 100644 quickstart/201-web-app-docker-acr/app_service.tf create mode 100644 quickstart/201-web-app-docker-acr/azurerm_role_assignment.tf create mode 100644 quickstart/201-web-app-docker-acr/main.tf create mode 100644 quickstart/201-web-app-docker-acr/readme.md create mode 100644 quickstart/201-web-app-docker-acr/variables.tf create mode 100644 quickstart/201-web-app-postgres-keyvault/README.md rename quickstart/{WebAppMySql => 201-web-app-postgres-keyvault}/main.tf (97%) rename quickstart/{WebAppMySql => 201-web-app-postgres-keyvault}/mysql.tf (97%) rename quickstart/{WebAppMySql => 201-web-app-postgres-keyvault}/output.tf (96%) rename quickstart/{WebAppMySql => 201-web-app-postgres-keyvault}/providers.tf (95%) rename quickstart/{WebAppMySql => 201-web-app-postgres-keyvault}/terraform.tfvars (95%) rename quickstart/{WebAppMySql => 201-web-app-postgres-keyvault}/variables.tf (95%) rename quickstart/{WebAppMySql => 201-web-app-postgres-keyvault}/webapp.tf (97%) create mode 100644 quickstart/201-web-app-windows-vnet/readme.md create mode 100644 quickstart/301-aks-enterprise/readme.md create mode 100644 quickstart/301-aks-windows-nodepool/readme.md create mode 100644 quickstart/301-hub-spoke-network-3vm/readme.md create mode 100644 quickstart/301-service-fabric-apim/apim.tf create mode 100644 quickstart/301-service-fabric-apim/azuread.tf create mode 100644 quickstart/301-service-fabric-apim/keyvault.tf create mode 100644 quickstart/301-service-fabric-apim/main.tf create mode 100644 quickstart/301-service-fabric-apim/network.tf create mode 100644 quickstart/301-service-fabric-apim/readme.md create mode 100644 quickstart/301-service-fabric-apim/service_fabric.tf create mode 100644 quickstart/301-service-fabric-apim/variables.tf create mode 100644 quickstart/301-service-fabric-apim/vmss.tf create mode 100644 quickstart/301-service-fabric/azuread.tf create mode 100644 quickstart/301-service-fabric/keyvault.tf create mode 100644 quickstart/301-service-fabric/main.tf create mode 100644 quickstart/301-service-fabric/network.tf create mode 100644 quickstart/301-service-fabric/readme.md create mode 100644 quickstart/301-service-fabric/service_fabric.tf create mode 100644 quickstart/301-service-fabric/variables.tf create mode 100644 quickstart/301-service-fabric/vmss.tf create mode 100644 quickstart/README.md diff --git a/.gitignore b/.gitignore index 940794e6..4026d69b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,288 +1,292 @@ -## 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 -.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 +## Ignore terraform provider and state files +*.terraform +*.tfstate + +## 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 +.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 diff --git a/.gitmodules b/.gitmodules index b42289aa..1e6a293a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,104 +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 +[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 diff --git a/LICENSE b/LICENSE index 21071075..4b1ad51b 100644 --- a/LICENSE +++ b/LICENSE @@ -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 diff --git a/README.md b/README.md index 25f0dcd1..8c8c70c3 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,24 @@ -# 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. +# 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. diff --git a/module/CONTRIBUTE.md b/module/CONTRIBUTE.md index 5b6328a5..0bcaf369 100644 --- a/module/CONTRIBUTE.md +++ b/module/CONTRIBUTE.md @@ -1,37 +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. - - - +# 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. + + + diff --git a/quickstart/101-storage-static-website/main.tf b/quickstart/101-storage-static-website/main.tf new file mode 100644 index 00000000..08f2559d --- /dev/null +++ b/quickstart/101-storage-static-website/main.tf @@ -0,0 +1,13 @@ +provider "azurerm" { + version = "=1.36.0" +} + +resource "azurerm_resource_group" "default" { + name = "${var.name}-${var.environment}-rg" + location = "westus" +} + +locals { + storage_account_name = "${var.dns_prefix}${var.name}${substr(var.environment, 0, 2)}" +} + diff --git a/quickstart/101-storage-static-website/readme.md b/quickstart/101-storage-static-website/readme.md new file mode 100644 index 00000000..d8b9235d --- /dev/null +++ b/quickstart/101-storage-static-website/readme.md @@ -0,0 +1,147 @@ +# Static website hosted on Azure Storage + +This template deploys an [Azure Storage Account](https://www.terraform.io/docs/providers/azurerm/r/storage_account.html) with static website hosting enabled. As this feature is not natively supported throuhg the ARM SDK and hence Terraform, a local-provisioner step is used to enable it with the Azure CLI. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group all resources are deployed into | +| `azurerm_storage_account` | The storage account used to host the website | + +## Variables + +| Name | Description | +|-|-| +| `name` | Name of the deployment | +| `environment` | The depolyment environment name (used for postfixing resource names) | +| `dns_prefix` | A prefix for globally-unique dns-based resources | +| `location` | The Azure Region to deploy these resources in | + + +## Example + +```bash +> terraform plan +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + + +------------------------------------------------------------------------ + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azurerm_resource_group.default will be created + + resource "azurerm_resource_group" "default" { + + id = (known after apply) + + location = "westus" + + name = "demo-tfquickstart-dev-rg" + + tags = (known after apply) + } + + # azurerm_storage_account.default will be created + + resource "azurerm_storage_account" "default" { + + access_tier = (known after apply) + + account_encryption_source = "Microsoft.Storage" + + account_kind = "StorageV2" + + account_replication_type = "LRS" + + account_tier = "Standard" + + account_type = (known after apply) + + enable_advanced_threat_protection = false + + enable_blob_encryption = true + + enable_file_encryption = true + + enable_https_traffic_only = true + + id = (known after apply) + + is_hns_enabled = false + + location = "westus2" + + name = "tfquickstartdemode" + + primary_access_key = (sensitive value) + + primary_blob_connection_string = (sensitive value) + + primary_blob_endpoint = (known after apply) + + primary_blob_host = (known after apply) + + primary_connection_string = (sensitive value) + + primary_dfs_endpoint = (known after apply) + + primary_dfs_host = (known after apply) + + primary_file_endpoint = (known after apply) + + primary_file_host = (known after apply) + + primary_location = (known after apply) + + primary_queue_endpoint = (known after apply) + + primary_queue_host = (known after apply) + + primary_table_endpoint = (known after apply) + + primary_table_host = (known after apply) + + primary_web_endpoint = (known after apply) + + primary_web_host = (known after apply) + + resource_group_name = "demo-dev-rg" + + secondary_access_key = (sensitive value) + + secondary_blob_connection_string = (sensitive value) + + secondary_blob_endpoint = (known after apply) + + secondary_blob_host = (known after apply) + + secondary_connection_string = (sensitive value) + + secondary_dfs_endpoint = (known after apply) + + secondary_dfs_host = (known after apply) + + secondary_file_endpoint = (known after apply) + + secondary_file_host = (known after apply) + + secondary_location = (known after apply) + + secondary_queue_endpoint = (known after apply) + + secondary_queue_host = (known after apply) + + secondary_table_endpoint = (known after apply) + + secondary_table_host = (known after apply) + + secondary_web_endpoint = (known after apply) + + secondary_web_host = (known after apply) + + tags = (known after apply) + + + identity { + + principal_id = (known after apply) + + tenant_id = (known after apply) + + type = (known after apply) + } + + + network_rules { + + bypass = (known after apply) + + default_action = (known after apply) + + ip_rules = (known after apply) + + virtual_network_subnet_ids = (known after apply) + } + + + queue_properties { + + cors_rule { + + allowed_headers = (known after apply) + + allowed_methods = (known after apply) + + allowed_origins = (known after apply) + + exposed_headers = (known after apply) + + max_age_in_seconds = (known after apply) + } + + + hour_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + + + logging { + + delete = (known after apply) + + read = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + + write = (known after apply) + } + + + minute_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + } + } + +Plan: 2 to add, 0 to change, 0 to destroy. + +------------------------------------------------------------------------ +``` \ No newline at end of file diff --git a/quickstart/101-storage-static-website/storage_account.tf b/quickstart/101-storage-static-website/storage_account.tf new file mode 100644 index 00000000..84feae01 --- /dev/null +++ b/quickstart/101-storage-static-website/storage_account.tf @@ -0,0 +1,14 @@ + +resource "azurerm_storage_account" "default" { + name = local.storage_account_name + resource_group_name = azurerm_resource_group.default.name + location = "westus2" + account_kind = "StorageV2" + account_tier = "Standard" + account_replication_type = "LRS" + enable_https_traffic_only = true + + provisioner "local-exec" { + command = "az storage blob service-properties update --account-name ${azurerm_storage_account.default.name} --static-website --index-document index.html --404-document 404.html" + } +} \ No newline at end of file diff --git a/quickstart/101-storage-static-website/variables.tf b/quickstart/101-storage-static-website/variables.tf new file mode 100644 index 00000000..cb6f0ac0 --- /dev/null +++ b/quickstart/101-storage-static-website/variables.tf @@ -0,0 +1,15 @@ +variable "environment" { + default = "dev" +} + +variable "name" { + default = "demo-tfquickstart" +} + +variable "location" { + default = "West US 2" +} + +variable "dns_prefix" { + default = "tfq" +} \ No newline at end of file diff --git a/quickstart/101-web-app-linux-container/app_service.tf b/quickstart/101-web-app-linux-container/app_service.tf new file mode 100644 index 00000000..7cd4e9a7 --- /dev/null +++ b/quickstart/101-web-app-linux-container/app_service.tf @@ -0,0 +1,31 @@ + +resource "azurerm_app_service_plan" "default" { + name = "${var.name}-plan" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + kind = "Linux" + + # Reserved must be set to true for Linux App Service Plans + reserved = true + + sku { + tier = "${var.plan_tier}" + size = "${var.plan_sku}" + } +} + +resource "azurerm_app_service" "default" { + name = "${var.dns_prefix}-${var.name}-${var.environment}-app" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + app_service_plan_id = "${azurerm_app_service_plan.default.id}" + + site_config { + always_on = true + linux_fx_version = "DOCKER|nginxdemos/hello" + } + + identity { + type = "SystemAssigned" + } +} diff --git a/quickstart/101-web-app-linux-container/main.tf b/quickstart/101-web-app-linux-container/main.tf new file mode 100644 index 00000000..f029cc2f --- /dev/null +++ b/quickstart/101-web-app-linux-container/main.tf @@ -0,0 +1,8 @@ +provider "azurerm" { + version = "=1.36.0" +} + +resource "azurerm_resource_group" "default" { + name = "${var.name}-${var.environment}-rg" + location = "${var.location}" +} diff --git a/quickstart/101-web-app-linux-container/readme.md b/quickstart/101-web-app-linux-container/readme.md new file mode 100644 index 00000000..328c969e --- /dev/null +++ b/quickstart/101-web-app-linux-container/readme.md @@ -0,0 +1,207 @@ +# Linux Web App for a containerized application + + +This template deploys an [Azure App Service](https://www.terraform.io/docs/providers/azurerm/r/app_service.html) running Linux configured for a containerized application. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group all resources are deployed into | +| `azurerm_app_service_plan` | The underlying plan that the web app will run on | +| `azurerm_app_service` | The Linux web app | + +## Variables + +| Name | Description | +|-|-| +| `name` | Name of the deployment | +| `environment` | The depolyment environment name (used for postfixing resource names) | +| `prefix` | A prefix for globally-unique dns-based resources | +| `location` | The Azure Region to deploy these resources in | +| `plan_tier` | The App Service Plan tier to deploy | +| `plan_sku` | The App Service Plan SKU to deploy| + + +## Example + +```bash +> terraform plan +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + + +------------------------------------------------------------------------ + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azurerm_app_service.default will be created + + resource "azurerm_app_service" "default" { + + app_service_plan_id = (known after apply) + + app_settings = (known after apply) + + client_affinity_enabled = (known after apply) + + default_site_hostname = (known after apply) + + enabled = true + + https_only = false + + id = (known after apply) + + location = "westus2" + + name = "tfq-demo-tfquickstart-dev-app" + + outbound_ip_addresses = (known after apply) + + possible_outbound_ip_addresses = (known after apply) + + resource_group_name = "demo-tfquickstart-dev-rg" + + site_credential = (known after apply) + + source_control = (known after apply) + + tags = (known after apply) + + + auth_settings { + + additional_login_params = (known after apply) + + allowed_external_redirect_urls = (known after apply) + + default_provider = (known after apply) + + enabled = (known after apply) + + issuer = (known after apply) + + runtime_version = (known after apply) + + token_refresh_extension_hours = (known after apply) + + token_store_enabled = (known after apply) + + unauthenticated_client_action = (known after apply) + + + active_directory { + + allowed_audiences = (known after apply) + + client_id = (known after apply) + + client_secret = (sensitive value) + } + + + facebook { + + app_id = (known after apply) + + app_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + google { + + client_id = (known after apply) + + client_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + microsoft { + + client_id = (known after apply) + + client_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + twitter { + + consumer_key = (known after apply) + + consumer_secret = (sensitive value) + } + } + + + connection_string { + + name = (known after apply) + + type = (known after apply) + + value = (sensitive value) + } + + + identity { + + identity_ids = (known after apply) + + principal_id = (known after apply) + + tenant_id = (known after apply) + + type = (known after apply) + } + + + logs { + + application_logs { + + azure_blob_storage { + + level = (known after apply) + + retention_in_days = (known after apply) + + sas_url = (sensitive value) + } + } + + + http_logs { + + azure_blob_storage { + + retention_in_days = (known after apply) + + sas_url = (sensitive value) + } + + + file_system { + + retention_in_days = (known after apply) + + retention_in_mb = (known after apply) + } + } + } + + + site_config { + + always_on = true + + dotnet_framework_version = "v4.0" + + ftps_state = (known after apply) + + http2_enabled = false + + ip_restriction = (known after apply) + + linux_fx_version = "DOCKER|nginxdemos/hello" + + local_mysql_enabled = (known after apply) + + managed_pipeline_mode = (known after apply) + + min_tls_version = (known after apply) + + remote_debugging_enabled = false + + remote_debugging_version = (known after apply) + + scm_type = "None" + + websockets_enabled = (known after apply) + + windows_fx_version = (known after apply) + + + cors { + + allowed_origins = (known after apply) + + support_credentials = (known after apply) + } + } + + + storage_account { + + access_key = (sensitive value) + + account_name = (known after apply) + + mount_path = (known after apply) + + name = (known after apply) + + share_name = (known after apply) + + type = (known after apply) + } + } + + # azurerm_app_service_plan.default will be created + + resource "azurerm_app_service_plan" "default" { + + app_service_environment_id = (known after apply) + + id = (known after apply) + + kind = "Linux" + + location = "westus2" + + maximum_elastic_worker_count = (known after apply) + + maximum_number_of_workers = (known after apply) + + name = "demo-tfquickstart-plan" + + per_site_scaling = (known after apply) + + reserved = true + + resource_group_name = "demo-tfquickstart-dev-rg" + + tags = (known after apply) + + + properties { + + app_service_environment_id = (known after apply) + + per_site_scaling = (known after apply) + + reserved = (known after apply) + } + + + sku { + + capacity = (known after apply) + + size = "S1" + + tier = "Standard" + } + } + + # azurerm_resource_group.default will be created + + resource "azurerm_resource_group" "default" { + + id = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-dev-rg" + + tags = (known after apply) + } + +Plan: 3 to add, 0 to change, 0 to destroy. + +------------------------------------------------------------------------ +``` diff --git a/quickstart/101-web-app-linux-container/variables.tf b/quickstart/101-web-app-linux-container/variables.tf new file mode 100644 index 00000000..4c9a825b --- /dev/null +++ b/quickstart/101-web-app-linux-container/variables.tf @@ -0,0 +1,35 @@ +variable "name" { + type = "string" + description = "Location of the azure resource group." + default = "demo-tfquickstart" +} + +variable "environment" { + type = "string" + description = "Name of the deployment environment" + default = "dev" +} + +variable "location" { + type = "string" + description = "Location to deploy the resoruce group" + default = "West US 2" +} + +variable "dns_prefix" { + type = "string" + description = "A prefix for any dns based resources" + default = "tfq" +} + +variable "plan_tier" { + type = "string" + description = "The tier of app service plan to create" + default = "Standard" +} + +variable "plan_sku" { + type = "string" + description = "The sku of app service plan to create" + default = "S1" +} diff --git a/quickstart/101-web-app-linux-java/app_service.tf b/quickstart/101-web-app-linux-java/app_service.tf new file mode 100644 index 00000000..1c375731 --- /dev/null +++ b/quickstart/101-web-app-linux-java/app_service.tf @@ -0,0 +1,29 @@ + +resource "azurerm_app_service_plan" "default" { + name = "${var.name}-plan" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + kind = "Linux" + + # Reserved must be set to true for Linux App Service Plans + reserved = true + + sku { + tier = "${var.plan_tier}" + size = "${var.plan_sku}" + } +} + +resource "azurerm_app_service" "default" { + name = "${var.dns_prefix}-${var.name}-${var.environment}-app" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + app_service_plan_id = "${azurerm_app_service_plan.default.id}" + + site_config { + always_on = true + java_version = "1.8" + java_container = "tomcat" + java_container_version = "9.0" + } +} diff --git a/quickstart/101-web-app-linux-java/main.tf b/quickstart/101-web-app-linux-java/main.tf new file mode 100644 index 00000000..f029cc2f --- /dev/null +++ b/quickstart/101-web-app-linux-java/main.tf @@ -0,0 +1,8 @@ +provider "azurerm" { + version = "=1.36.0" +} + +resource "azurerm_resource_group" "default" { + name = "${var.name}-${var.environment}-rg" + location = "${var.location}" +} diff --git a/quickstart/101-web-app-linux-java/readme.md b/quickstart/101-web-app-linux-java/readme.md new file mode 100644 index 00000000..fb8d8e29 --- /dev/null +++ b/quickstart/101-web-app-linux-java/readme.md @@ -0,0 +1,210 @@ +# Linux Web App for a Java/Tomcat application + + +This template deploys an [Azure App Service](https://www.terraform.io/docs/providers/azurerm/r/app_service.html) running Linux configured for a Java application hosted with Tomcat. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group all resources are deployed into | +| `azurerm_app_service_plan` | The underlying plan that the web app will run on | +| `azurerm_app_service` | The Linux web app | + +## Variables + +| Name | Description | +|-|-| +| `name` | Name of the deployment | +| `environment` | The depolyment environment name (used for postfixing resource names) | +| `dns_prefix` | A prefix for globally-unique dns-based resources | +| `location` | The Azure Region to deploy these resources in | +| `plan_tier` | The App Service Plan tier to deploy | +| `plan_sku` | The App Service Plan SKU to deploy| + + +## Example + +```bash +> terraform plan +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + + +------------------------------------------------------------------------ + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azurerm_app_service.default will be created + + resource "azurerm_app_service" "default" { + + app_service_plan_id = (known after apply) + + app_settings = (known after apply) + + client_affinity_enabled = (known after apply) + + default_site_hostname = (known after apply) + + enabled = true + + https_only = false + + id = (known after apply) + + location = "westus2" + + name = "tfq-demo-tfquickstart-dev-app" + + outbound_ip_addresses = (known after apply) + + possible_outbound_ip_addresses = (known after apply) + + resource_group_name = "demo-tfquickstart-dev-rg" + + site_credential = (known after apply) + + source_control = (known after apply) + + tags = (known after apply) + + + auth_settings { + + additional_login_params = (known after apply) + + allowed_external_redirect_urls = (known after apply) + + default_provider = (known after apply) + + enabled = (known after apply) + + issuer = (known after apply) + + runtime_version = (known after apply) + + token_refresh_extension_hours = (known after apply) + + token_store_enabled = (known after apply) + + unauthenticated_client_action = (known after apply) + + + active_directory { + + allowed_audiences = (known after apply) + + client_id = (known after apply) + + client_secret = (sensitive value) + } + + + facebook { + + app_id = (known after apply) + + app_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + google { + + client_id = (known after apply) + + client_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + microsoft { + + client_id = (known after apply) + + client_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + twitter { + + consumer_key = (known after apply) + + consumer_secret = (sensitive value) + } + } + + + connection_string { + + name = (known after apply) + + type = (known after apply) + + value = (sensitive value) + } + + + identity { + + identity_ids = (known after apply) + + principal_id = (known after apply) + + tenant_id = (known after apply) + + type = (known after apply) + } + + + logs { + + application_logs { + + azure_blob_storage { + + level = (known after apply) + + retention_in_days = (known after apply) + + sas_url = (sensitive value) + } + } + + + http_logs { + + azure_blob_storage { + + retention_in_days = (known after apply) + + sas_url = (sensitive value) + } + + + file_system { + + retention_in_days = (known after apply) + + retention_in_mb = (known after apply) + } + } + } + + + site_config { + + always_on = true + + dotnet_framework_version = "v4.0" + + ftps_state = (known after apply) + + http2_enabled = false + + ip_restriction = (known after apply) + + java_container = "tomcat" + + java_container_version = "9.0" + + java_version = "1.8" + + linux_fx_version = (known after apply) + + local_mysql_enabled = (known after apply) + + managed_pipeline_mode = (known after apply) + + min_tls_version = (known after apply) + + remote_debugging_enabled = false + + remote_debugging_version = (known after apply) + + scm_type = "None" + + websockets_enabled = (known after apply) + + windows_fx_version = (known after apply) + + + cors { + + allowed_origins = (known after apply) + + support_credentials = (known after apply) + } + } + + + storage_account { + + access_key = (sensitive value) + + account_name = (known after apply) + + mount_path = (known after apply) + + name = (known after apply) + + share_name = (known after apply) + + type = (known after apply) + } + } + + # azurerm_app_service_plan.default will be created + + resource "azurerm_app_service_plan" "default" { + + app_service_environment_id = (known after apply) + + id = (known after apply) + + kind = "Linux" + + location = "westus2" + + maximum_elastic_worker_count = (known after apply) + + maximum_number_of_workers = (known after apply) + + name = "demo-tfquickstart-plan" + + per_site_scaling = (known after apply) + + reserved = true + + resource_group_name = "demo-tfquickstart-dev-rg" + + tags = (known after apply) + + + properties { + + app_service_environment_id = (known after apply) + + per_site_scaling = (known after apply) + + reserved = (known after apply) + } + + + sku { + + capacity = (known after apply) + + size = "S1" + + tier = "Standard" + } + } + + # azurerm_resource_group.default will be created + + resource "azurerm_resource_group" "default" { + + id = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-dev-rg" + + tags = (known after apply) + } + +Plan: 3 to add, 0 to change, 0 to destroy. + +------------------------------------------------------------------------ +``` \ No newline at end of file diff --git a/quickstart/101-web-app-linux-java/variables.tf b/quickstart/101-web-app-linux-java/variables.tf new file mode 100644 index 00000000..4c9a825b --- /dev/null +++ b/quickstart/101-web-app-linux-java/variables.tf @@ -0,0 +1,35 @@ +variable "name" { + type = "string" + description = "Location of the azure resource group." + default = "demo-tfquickstart" +} + +variable "environment" { + type = "string" + description = "Name of the deployment environment" + default = "dev" +} + +variable "location" { + type = "string" + description = "Location to deploy the resoruce group" + default = "West US 2" +} + +variable "dns_prefix" { + type = "string" + description = "A prefix for any dns based resources" + default = "tfq" +} + +variable "plan_tier" { + type = "string" + description = "The tier of app service plan to create" + default = "Standard" +} + +variable "plan_sku" { + type = "string" + description = "The sku of app service plan to create" + default = "S1" +} diff --git a/quickstart/101-web-app-windows-dotnet/app_service.tf b/quickstart/101-web-app-windows-dotnet/app_service.tf new file mode 100644 index 00000000..51a80232 --- /dev/null +++ b/quickstart/101-web-app-windows-dotnet/app_service.tf @@ -0,0 +1,23 @@ +resource "azurerm_app_service_plan" "default" { + name = "${var.name}-plan" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + kind = "Windows" + + sku { + tier = "${var.plan_tier}" + size = "${var.plan_sku}" + } +} + +resource "azurerm_app_service" "default" { + name = "${var.dns_prefix}-${var.name}-aspnet-${var.environment}-app" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + app_service_plan_id = "${azurerm_app_service_plan.default.id}" + + site_config { + always_on = true + dotnet_framework_version = "v4.0" + } +} diff --git a/quickstart/101-web-app-windows-dotnet/main.tf b/quickstart/101-web-app-windows-dotnet/main.tf new file mode 100644 index 00000000..f029cc2f --- /dev/null +++ b/quickstart/101-web-app-windows-dotnet/main.tf @@ -0,0 +1,8 @@ +provider "azurerm" { + version = "=1.36.0" +} + +resource "azurerm_resource_group" "default" { + name = "${var.name}-${var.environment}-rg" + location = "${var.location}" +} diff --git a/quickstart/101-web-app-windows-dotnet/readme.md b/quickstart/101-web-app-windows-dotnet/readme.md new file mode 100644 index 00000000..2d00effa --- /dev/null +++ b/quickstart/101-web-app-windows-dotnet/readme.md @@ -0,0 +1,199 @@ +# Windows Web App for a .NET Application + + +This template deploys an [Azure App Service](https://www.terraform.io/docs/providers/azurerm/r/app_service.html) running Windows configured for a .NET Framework 4.6.2 application. + +## Variables + +| Name | Description | +|-|-| +| name | Name of the deployment | +| environment | The depolyment environment name (used for postfixing resource names) | +| dns_prefix | A prefix for globally-unique dns-based resources | +| location | The Azure Region to deploy these resources in | +| plan_tier | The App Service Plan tier to deploy | +| plan_sku | The App Service Plan SKU to deploy| + + +## Usage + +```bash +> terraform plan +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + + +------------------------------------------------------------------------ + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azurerm_app_service.default will be created + + resource "azurerm_app_service" "default" { + + app_service_plan_id = (known after apply) + + app_settings = (known after apply) + + client_affinity_enabled = (known after apply) + + default_site_hostname = (known after apply) + + enabled = true + + https_only = false + + id = (known after apply) + + location = "westus2" + + name = "tfq-demo-tfquickstart-aspnet-dev-app" + + outbound_ip_addresses = (known after apply) + + possible_outbound_ip_addresses = (known after apply) + + resource_group_name = "demo-tfquickstart-dev-rg" + + site_credential = (known after apply) + + source_control = (known after apply) + + tags = (known after apply) + + + auth_settings { + + additional_login_params = (known after apply) + + allowed_external_redirect_urls = (known after apply) + + default_provider = (known after apply) + + enabled = (known after apply) + + issuer = (known after apply) + + runtime_version = (known after apply) + + token_refresh_extension_hours = (known after apply) + + token_store_enabled = (known after apply) + + unauthenticated_client_action = (known after apply) + + + active_directory { + + allowed_audiences = (known after apply) + + client_id = (known after apply) + + client_secret = (sensitive value) + } + + + facebook { + + app_id = (known after apply) + + app_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + google { + + client_id = (known after apply) + + client_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + microsoft { + + client_id = (known after apply) + + client_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + twitter { + + consumer_key = (known after apply) + + consumer_secret = (sensitive value) + } + } + + + connection_string { + + name = (known after apply) + + type = (known after apply) + + value = (sensitive value) + } + + + identity { + + identity_ids = (known after apply) + + principal_id = (known after apply) + + tenant_id = (known after apply) + + type = (known after apply) + } + + + logs { + + application_logs { + + azure_blob_storage { + + level = (known after apply) + + retention_in_days = (known after apply) + + sas_url = (sensitive value) + } + } + + + http_logs { + + azure_blob_storage { + + retention_in_days = (known after apply) + + sas_url = (sensitive value) + } + + + file_system { + + retention_in_days = (known after apply) + + retention_in_mb = (known after apply) + } + } + } + + + site_config { + + always_on = true + + dotnet_framework_version = "v4.0" + + ftps_state = (known after apply) + + http2_enabled = false + + ip_restriction = (known after apply) + + linux_fx_version = (known after apply) + + local_mysql_enabled = (known after apply) + + managed_pipeline_mode = (known after apply) + + min_tls_version = (known after apply) + + remote_debugging_enabled = false + + remote_debugging_version = (known after apply) + + scm_type = "None" + + websockets_enabled = (known after apply) + + windows_fx_version = (known after apply) + + + cors { + + allowed_origins = (known after apply) + + support_credentials = (known after apply) + } + } + + + storage_account { + + access_key = (sensitive value) + + account_name = (known after apply) + + mount_path = (known after apply) + + name = (known after apply) + + share_name = (known after apply) + + type = (known after apply) + } + } + + # azurerm_app_service_plan.default will be created + + resource "azurerm_app_service_plan" "default" { + + app_service_environment_id = (known after apply) + + id = (known after apply) + + kind = "Windows" + + location = "westus2" + + maximum_elastic_worker_count = (known after apply) + + maximum_number_of_workers = (known after apply) + + name = "demo-tfquickstart-plan" + + per_site_scaling = (known after apply) + + reserved = (known after apply) + + resource_group_name = "demo-tfquickstart-dev-rg" + + tags = (known after apply) + + + properties { + + app_service_environment_id = (known after apply) + + per_site_scaling = (known after apply) + + reserved = (known after apply) + } + + + sku { + + capacity = (known after apply) + + size = "S1" + + tier = "Standard" + } + } + + # azurerm_resource_group.default will be created + + resource "azurerm_resource_group" "default" { + + id = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-dev-rg" + + tags = (known after apply) + } + +Plan: 3 to add, 0 to change, 0 to destroy. + +------------------------------------------------------------------------ +`` \ No newline at end of file diff --git a/quickstart/101-web-app-windows-dotnet/variables.tf b/quickstart/101-web-app-windows-dotnet/variables.tf new file mode 100644 index 00000000..4c9a825b --- /dev/null +++ b/quickstart/101-web-app-windows-dotnet/variables.tf @@ -0,0 +1,35 @@ +variable "name" { + type = "string" + description = "Location of the azure resource group." + default = "demo-tfquickstart" +} + +variable "environment" { + type = "string" + description = "Name of the deployment environment" + default = "dev" +} + +variable "location" { + type = "string" + description = "Location to deploy the resoruce group" + default = "West US 2" +} + +variable "dns_prefix" { + type = "string" + description = "A prefix for any dns based resources" + default = "tfq" +} + +variable "plan_tier" { + type = "string" + description = "The tier of app service plan to create" + default = "Standard" +} + +variable "plan_sku" { + type = "string" + description = "The sku of app service plan to create" + default = "S1" +} diff --git a/quickstart/201-aks-acr-identity/acr.tf b/quickstart/201-aks-acr-identity/acr.tf new file mode 100644 index 00000000..00b2edd7 --- /dev/null +++ b/quickstart/201-aks-acr-identity/acr.tf @@ -0,0 +1,10 @@ +locals { + acr_name = "${replace(var.dns_prefix, "-", "")}${replace(var.name, "-", "")}acr" +} +resource "azurerm_container_registry" "default" { + name = "${local.acr_name}" + resource_group_name = "${azurerm_resource_group.default.name}" + location = "${azurerm_resource_group.default.location}" + sku = "Standard" + admin_enabled = false +} \ No newline at end of file diff --git a/quickstart/201-aks-acr-identity/aks.tf b/quickstart/201-aks-acr-identity/aks.tf new file mode 100644 index 00000000..cd31ab21 --- /dev/null +++ b/quickstart/201-aks-acr-identity/aks.tf @@ -0,0 +1,24 @@ +resource "azurerm_kubernetes_cluster" "default" { + name = "${var.name}-aks" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + dns_prefix = "${var.dns_prefix}-${var.name}-aks-${var.environment}" + depends_on = ["azurerm_role_assignment.aks_network", "azurerm_role_assignment.aks_acr"] + + agent_pool_profile { + name = "default" + count = "${var.node_count}" + vm_size = "${var.node_type}" + os_type = "Linux" + os_disk_size_gb = 30 + } + + service_principal { + client_id = "${azuread_application.default.application_id}" + client_secret = "${azuread_service_principal_password.default.value}" + } + + role_based_access_control { + enabled = true + } +} \ No newline at end of file diff --git a/quickstart/201-aks-acr-identity/azuread.tf b/quickstart/201-aks-acr-identity/azuread.tf new file mode 100644 index 00000000..2e94e968 --- /dev/null +++ b/quickstart/201-aks-acr-identity/azuread.tf @@ -0,0 +1,30 @@ +resource "azuread_application" "default" { + name = "${var.name}-${var.environment}" +} + +resource "azuread_service_principal" "default" { + application_id = "${azuread_application.default.application_id}" +} + +resource "random_string" "password" { + length = 32 + special = true +} + +resource "azuread_service_principal_password" "default" { + service_principal_id = "${azuread_service_principal.default.id}" + value = "${random_string.password.result}" + end_date = "2099-01-01T01:00:00Z" +} + +resource "azurerm_role_assignment" "aks_network" { + scope = "${data.azurerm_subscription.current.id}/resourceGroups/${azurerm_resource_group.default.name}" + role_definition_name = "Network Contributor" + principal_id = "${azuread_service_principal.default.id}" +} + +resource "azurerm_role_assignment" "aks_acr" { + scope = "${data.azurerm_subscription.current.id}/resourceGroups/${azurerm_resource_group.default.name}/providers/Microsoft.ContainerRegistry/registries/${azurerm_container_registry.default.name}" + role_definition_name = "Reader" + principal_id = "${azuread_service_principal.default.id}" +} \ No newline at end of file diff --git a/quickstart/201-aks-acr-identity/main.tf b/quickstart/201-aks-acr-identity/main.tf new file mode 100644 index 00000000..8e57b9e5 --- /dev/null +++ b/quickstart/201-aks-acr-identity/main.tf @@ -0,0 +1,18 @@ +# The Azure Active Resource Manager Terraform provider +provider "azurerm" { + version = "=1.36.0" +} + +# The Azure Active Directory Terraform provider +provider "azuread" { + version = "=0.6.0" +} + +# Reference to the current subscription. Used when creating role assignments +data "azurerm_subscription" "current" {} + +# The main resource group for this deployment +resource "azurerm_resource_group" "default" { + name = "${var.name}-${var.environment}-rg" + location = "${var.location}" +} diff --git a/quickstart/201-aks-acr-identity/readme.md b/quickstart/201-aks-acr-identity/readme.md new file mode 100644 index 00000000..2bca85b1 --- /dev/null +++ b/quickstart/201-aks-acr-identity/readme.md @@ -0,0 +1,226 @@ +# AKC + ACR with Managed Identity + +This template deploys an Azure Kubernetes Service cluster with a user-assigned Identity along with an Azure Container Registry. The identity of the AKS cluster has an assigned reader role to the ACR instance so AKS can pull containers without needing to have a Docker username and password configured. + +## Variables + +| Name | Description | +|-|-| +| name | Name of the deployment | +| environment | The depolyment environment name (used for postfixing resource names) | +| location | The Azure Region to deploy these resources in | +| vm_sku | The SKU of the VMs to deploy for AKS | +| dns_prefix | A DNS Prefix to use in the AKS Cluster | + + +## Example + +```bash +> terraform plan +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + +data.azurerm_subscription.current: Refreshing state... + +------------------------------------------------------------------------ + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azuread_application.default will be created + + resource "azuread_application" "default" { + + application_id = (known after apply) + + homepage = (known after apply) + + id = (known after apply) + + identifier_uris = (known after apply) + + name = "demo-tfquickstart-dev" + + object_id = (known after apply) + + public_client = (known after apply) + + reply_urls = (known after apply) + + type = "webapp/api" + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal.default will be created + + resource "azuread_service_principal" "default" { + + application_id = (known after apply) + + display_name = (known after apply) + + id = (known after apply) + + object_id = (known after apply) + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal_password.default will be created + + resource "azuread_service_principal_password" "default" { + + end_date = "2099-01-01T01:00:00Z" + + id = (known after apply) + + key_id = (known after apply) + + service_principal_id = (known after apply) + + start_date = (known after apply) + + value = (sensitive value) + } + + # azurerm_container_registry.default will be created + + resource "azurerm_container_registry" "default" { + + admin_enabled = false + + admin_password = (sensitive value) + + admin_username = (known after apply) + + id = (known after apply) + + location = "westus2" + + login_server = (known after apply) + + name = "tfqdemotfquickstartacr" + + network_rule_set = (known after apply) + + resource_group_name = "demo-tfquickstart-dev-rg" + + sku = "Standard" + + tags = (known after apply) + } + + # azurerm_kubernetes_cluster.default will be created + + resource "azurerm_kubernetes_cluster" "default" { + + dns_prefix = "tfq-demo-tfquickstart-aks-dev" + + enable_pod_security_policy = (known after apply) + + fqdn = (known after apply) + + id = (known after apply) + + kube_admin_config = (known after apply) + + kube_admin_config_raw = (sensitive value) + + kube_config = (known after apply) + + kube_config_raw = (sensitive value) + + kubernetes_version = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-aks" + + node_resource_group = (known after apply) + + resource_group_name = "demo-tfquickstart-dev-rg" + + tags = (known after apply) + + + addon_profile { + + aci_connector_linux { + + enabled = (known after apply) + + subnet_name = (known after apply) + } + + + azure_policy { + + enabled = (known after apply) + } + + + http_application_routing { + + enabled = (known after apply) + + http_application_routing_zone_name = (known after apply) + } + + + kube_dashboard { + + enabled = (known after apply) + } + + + oms_agent { + + enabled = (known after apply) + + log_analytics_workspace_id = (known after apply) + } + } + + + agent_pool_profile { + + count = 3 + + dns_prefix = (known after apply) + + fqdn = (known after apply) + + max_pods = (known after apply) + + name = "default" + + os_disk_size_gb = 30 + + os_type = "Linux" + + type = "AvailabilitySet" + + vm_size = "Standard_D1_v2" + } + + + network_profile { + + dns_service_ip = (known after apply) + + docker_bridge_cidr = (known after apply) + + load_balancer_sku = (known after apply) + + network_plugin = (known after apply) + + network_policy = (known after apply) + + pod_cidr = (known after apply) + + service_cidr = (known after apply) + } + + + role_based_access_control { + + enabled = true + } + + + service_principal { + + client_id = (known after apply) + + client_secret = (sensitive value) + } + } + + # azurerm_resource_group.default will be created + + resource "azurerm_resource_group" "default" { + + id = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-dev-rg" + + tags = (known after apply) + } + + # azurerm_role_assignment.aks_acr will be created + + resource "azurerm_role_assignment" "aks_acr" { + + id = (known after apply) + + name = (known after apply) + + principal_id = (known after apply) + + principal_type = (known after apply) + + role_definition_id = (known after apply) + + role_definition_name = "Reader" + + scope = "/subscriptions/b0e04a4a-a321-4b66-b8fd-13715262ba3c/resourceGroups/demo-tfquickstart-dev-rg/providers/Microsoft.ContainerRegistry/registries/tfqdemotfquickstartacr" + + skip_service_principal_aad_check = (known after apply) + } + + # azurerm_role_assignment.aks_network will be created + + resource "azurerm_role_assignment" "aks_network" { + + id = (known after apply) + + name = (known after apply) + + principal_id = (known after apply) + + principal_type = (known after apply) + + role_definition_id = (known after apply) + + role_definition_name = "Network Contributor" + + scope = "/subscriptions/b0e04a4a-a321-4b66-b8fd-13715262ba3c/resourceGroups/demo-tfquickstart-dev-rg" + + skip_service_principal_aad_check = (known after apply) + } + + # random_string.password will be created + + resource "random_string" "password" { + + id = (known after apply) + + length = 32 + + lower = true + + min_lower = 0 + + min_numeric = 0 + + min_special = 0 + + min_upper = 0 + + number = true + + result = (known after apply) + + special = true + + upper = true + } + +Plan: 9 to add, 0 to change, 0 to destroy. + +------------------------------------------------------------------------ +``` \ No newline at end of file diff --git a/quickstart/201-aks-acr-identity/variables.tf b/quickstart/201-aks-acr-identity/variables.tf new file mode 100644 index 00000000..b9d3b197 --- /dev/null +++ b/quickstart/201-aks-acr-identity/variables.tf @@ -0,0 +1,40 @@ +// Naming +variable "name" { + type = "string" + description = "Location of the azure resource group." + default = "demo-tfquickstart" +} + +variable "environment" { + type = "string" + description = "Name of the deployment environment" + default = "dev" +} + +// Resource information + +variable "location" { + type = "string" + description = "Location of the azure resource group." + default = "WestUS2" +} + +// Node type information + +variable "node_count" { + type = "string" + description = "The number of K8S nodes to provision." + default = 3 +} + +variable "node_type" { + type = "string" + description = "The size of each node." + default = "Standard_D1_v2" +} + +variable "dns_prefix" { + type = "string" + description = "DNS Prefix" + default = "tfq" +} diff --git a/quickstart/WebAppMySql/README.md b/quickstart/201-aks-advanced-networking/readme.md similarity index 100% rename from quickstart/WebAppMySql/README.md rename to quickstart/201-aks-advanced-networking/readme.md diff --git a/quickstart/201-aks-gpu-nodepool/readme.md b/quickstart/201-aks-gpu-nodepool/readme.md new file mode 100644 index 00000000..596bd0bc --- /dev/null +++ b/quickstart/201-aks-gpu-nodepool/readme.md @@ -0,0 +1,31 @@ +# AKS with a GPU Nodepool + +Sometimes we need multiple node types with AKS. This template deploys an Azure Kubernetes Service cluster with a basic VM pool as well as a node pool of VMs that have GPUs attached. + +## Variables + +| Name | Description | +|-|-| +| name | Name of the deployment | +| environment | The depolyment environment name (used for postfixing resource names) | +| location | The Azure Region to deploy these resources in | +| vm_sku | The SKU of the VMs to deploy for AKS | +| vm_gpu_sku | The SKU of VMs to deploy for the AKS GPU Nodepool" +| prefix | A DNS Prefix to use in the AKS Cluster | + + +## Usage + +```bash +terraform plan \ + -var 'name=demo-dotnet' \ + -var 'environment=staging' \ + -var 'location=West US 2' + -var 'prefix=tfquickstard' \ + -var 'vm_sku=ds1v2' \ + -out demo.tfplan + +terraform apply demo.tfplan +``` + +\* Example shown with [Bash](https://www.gnu.org/software/bash/). For [Powershell](https://docs.microsoft.com/en-us/powershell/) replace backslashes with backticks. \ No newline at end of file diff --git a/quickstart/201-aks-helm/aks.tf b/quickstart/201-aks-helm/aks.tf new file mode 100644 index 00000000..de617e27 --- /dev/null +++ b/quickstart/201-aks-helm/aks.tf @@ -0,0 +1,24 @@ +resource "azurerm_kubernetes_cluster" "default" { + name = "${var.name}-aks" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + dns_prefix = "${var.dns_prefix}-${var.name}-aks-${var.environment}" + depends_on = ["azurerm_role_assignment.default"] + + agent_pool_profile { + name = "default" + count = "${var.node_count}" + vm_size = "${var.node_type}" + os_type = "Linux" + os_disk_size_gb = 30 + } + + service_principal { + client_id = "${azuread_application.default.application_id}" + client_secret = "${azuread_service_principal_password.default.value}" + } + + role_based_access_control { + enabled = true + } +} \ No newline at end of file diff --git a/quickstart/201-aks-helm/azuread.tf b/quickstart/201-aks-helm/azuread.tf new file mode 100644 index 00000000..de8cbd40 --- /dev/null +++ b/quickstart/201-aks-helm/azuread.tf @@ -0,0 +1,24 @@ +resource "azuread_application" "default" { + name = "${var.name}-${var.environment}" +} + +resource "azuread_service_principal" "default" { + application_id = "${azuread_application.default.application_id}" +} + +resource "random_string" "password" { + length = 32 + special = true +} + +resource "azuread_service_principal_password" "default" { + service_principal_id = "${azuread_service_principal.default.id}" + value = "${random_string.password.result}" + end_date = "2099-01-01T01:00:00Z" +} + +resource "azurerm_role_assignment" "default" { + scope = "${data.azurerm_subscription.current.id}/resourceGroups/${azurerm_resource_group.default.name}" + role_definition_name = "Network Contributor" + principal_id = "${azuread_service_principal.default.id}" +} \ No newline at end of file diff --git a/quickstart/201-aks-helm/helm.tf b/quickstart/201-aks-helm/helm.tf new file mode 100644 index 00000000..ea0cec34 --- /dev/null +++ b/quickstart/201-aks-helm/helm.tf @@ -0,0 +1,20 @@ +# Define the helm provider to use the AKS cluster +provider "helm" { + kubernetes { + host = "${azurerm_kubernetes_cluster.default.kube_config.0.host}" + + client_certificate = "${base64decode(azurerm_kubernetes_cluster.default.kube_config.0.client_certificate)}" + client_key = "${base64decode(azurerm_kubernetes_cluster.default.kube_config.0.client_key)}" + cluster_ca_certificate = "${base64decode(azurerm_kubernetes_cluster.default.kube_config.0.cluster_ca_certificate)}" + } + + service_account = "tiller" +} + +# Install a sample ghost blog +resource "helm_release" "ghost" { + name = "ghost-blog" + chart = "bitnami/ghost" + + depends_on = ["kubernetes_cluster_role_binding.tiller"] +} \ No newline at end of file diff --git a/quickstart/201-aks-helm/kubernetes.tf b/quickstart/201-aks-helm/kubernetes.tf new file mode 100644 index 00000000..72f74858 --- /dev/null +++ b/quickstart/201-aks-helm/kubernetes.tf @@ -0,0 +1,35 @@ +# Define Kubernetes provider to use the AKS cluster +provider "kubernetes" { + host = "${azurerm_kubernetes_cluster.default.kube_config.0.host}" + + client_certificate = "${base64decode(azurerm_kubernetes_cluster.default.kube_config.0.client_certificate)}" + client_key = "${base64decode(azurerm_kubernetes_cluster.default.kube_config.0.client_key)}" + cluster_ca_certificate = "${base64decode(azurerm_kubernetes_cluster.default.kube_config.0.cluster_ca_certificate)}" +} + +# Create a service account for the Helm Tiller +resource "kubernetes_service_account" "tiller" { + metadata { + name = "tiller" + namespace = "kube-system" + } +} + +# Grant cluster-admin rights to the Tiller Service Account +resource "kubernetes_cluster_role_binding" "tiller" { + metadata { + name = "${kubernetes_service_account.tiller.metadata.0.name}" + } + + role_ref { + api_group = "rbac.authorization.k8s.io" + kind = "ClusterRole" + name = "cluster-admin" + } + + subject { + kind = "ServiceAccount" + name = "${kubernetes_service_account.tiller.metadata.0.name}" + namespace = "kube-system" + } +} diff --git a/quickstart/201-aks-helm/main.tf b/quickstart/201-aks-helm/main.tf new file mode 100644 index 00000000..a6cbe998 --- /dev/null +++ b/quickstart/201-aks-helm/main.tf @@ -0,0 +1,18 @@ +# The Azure Active Resource Manager Terraform provider +provider "azurerm" { + version = "=1.36.1" +} + +# The Azure Active Directory Terraform provider +provider "azuread" { + version = "=0.6.0" +} + +# Reference to the current subscription. Used when creating role assignments +data "azurerm_subscription" "current" {} + +# The main resource group for this deployment +resource "azurerm_resource_group" "default" { + name = "${var.name}-${var.environment}-rg" + location = "${var.location}" +} diff --git a/quickstart/201-aks-helm/readme.md b/quickstart/201-aks-helm/readme.md new file mode 100644 index 00000000..3625f9af --- /dev/null +++ b/quickstart/201-aks-helm/readme.md @@ -0,0 +1,244 @@ +# AKS with Helm + +This template deploys an Azure Kubernetes Service cluster then leverages the Kubernetes provider to configure Helm (v2) to manage deployed packages. Once stood up a basic blog demo is deployed. + +## Variables + +| Name | Description | +|-|-| +| name | Name of the deployment | +| environment | The depolyment environment name (used for postfixing resource names) | +| prefix | A prefix for globally-unique dns-based resources | +| location | The Azure Region to deploy these resources in | +| node_type | The type of node to deploy on (e.g. d1v2) | +| node_count | The number of nodes to deploy | +| dns_prefix | A unique dns prefix | + + +## Sample + +```bash +> terraform plan +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + +data.azurerm_subscription.current: Refreshing state... + +------------------------------------------------------------------------ + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azuread_application.default will be created + + resource "azuread_application" "default" { + + application_id = (known after apply) + + homepage = (known after apply) + + id = (known after apply) + + identifier_uris = (known after apply) + + name = "quickstart-aks-dev" + + object_id = (known after apply) + + public_client = (known after apply) + + reply_urls = (known after apply) + + type = "webapp/api" + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal.default will be created + + resource "azuread_service_principal" "default" { + + application_id = (known after apply) + + display_name = (known after apply) + + id = (known after apply) + + object_id = (known after apply) + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal_password.default will be created + + resource "azuread_service_principal_password" "default" { + + end_date = "2099-01-01T01:00:00Z" + + id = (known after apply) + + key_id = (known after apply) + + service_principal_id = (known after apply) + + start_date = (known after apply) + + value = (sensitive value) + } + + # azurerm_kubernetes_cluster.default will be created + + resource "azurerm_kubernetes_cluster" "default" { + + dns_prefix = "tfquickstart-quickstart-aks-aks-dev" + + enable_pod_security_policy = (known after apply) + + fqdn = (known after apply) + + id = (known after apply) + + kube_admin_config = (known after apply) + + kube_admin_config_raw = (sensitive value) + + kube_config = (known after apply) + + kube_config_raw = (sensitive value) + + kubernetes_version = (known after apply) + + location = "westus2" + + name = "quickstart-aks-aks" + + node_resource_group = (known after apply) + + resource_group_name = "quickstart-aks-dev-rg" + + tags = (known after apply) + + + addon_profile { + + aci_connector_linux { + + enabled = (known after apply) + + subnet_name = (known after apply) + } + + + azure_policy { + + enabled = (known after apply) + } + + + http_application_routing { + + enabled = (known after apply) + + http_application_routing_zone_name = (known after apply) + } + + + kube_dashboard { + + enabled = (known after apply) + } + + + oms_agent { + + enabled = (known after apply) + + log_analytics_workspace_id = (known after apply) + } + } + + + agent_pool_profile { + + count = 3 + + dns_prefix = (known after apply) + + fqdn = (known after apply) + + max_pods = (known after apply) + + name = "default" + + os_disk_size_gb = 30 + + os_type = "Linux" + + type = "AvailabilitySet" + + vm_size = "Standard_D1_v2" + } + + + network_profile { + + dns_service_ip = (known after apply) + + docker_bridge_cidr = (known after apply) + + load_balancer_sku = (known after apply) + + network_plugin = (known after apply) + + network_policy = (known after apply) + + pod_cidr = (known after apply) + + service_cidr = (known after apply) + } + + + role_based_access_control { + + enabled = true + } + + + service_principal { + + client_id = (known after apply) + + client_secret = (sensitive value) + } + } + + # azurerm_resource_group.default will be created + + resource "azurerm_resource_group" "default" { + + id = (known after apply) + + location = "westus2" + + name = "quickstart-aks-dev-rg" + + tags = (known after apply) + } + + # azurerm_role_assignment.default will be created + + resource "azurerm_role_assignment" "default" { + + id = (known after apply) + + name = (known after apply) + + principal_id = (known after apply) + + principal_type = (known after apply) + + role_definition_id = (known after apply) + + role_definition_name = "Network Contributor" + + scope = "/subscriptions/b0e04a4a-a321-4b66-b8fd-13715262ba3c/resourceGroups/quickstart-aks-dev-rg" + + skip_service_principal_aad_check = (known after apply) + } + + # kubernetes_cluster_role_binding.tiller will be created + + resource "kubernetes_cluster_role_binding" "tiller" { + + id = (known after apply) + + + metadata { + + generation = (known after apply) + + name = "tiller" + + resource_version = (known after apply) + + self_link = (known after apply) + + uid = (known after apply) + } + + + role_ref { + + api_group = "rbac.authorization.k8s.io" + + kind = "ClusterRole" + + name = "cluster-admin" + } + + + subject { + + api_group = (known after apply) + + kind = "ServiceAccount" + + name = "tiller" + + namespace = "kube-system" + } + } + + # kubernetes_service_account.tiller will be created + + resource "kubernetes_service_account" "tiller" { + + default_secret_name = (known after apply) + + id = (known after apply) + + + metadata { + + generation = (known after apply) + + name = "tiller" + + namespace = "kube-system" + + resource_version = (known after apply) + + self_link = (known after apply) + + uid = (known after apply) + } + } + + # random_string.password will be created + + resource "random_string" "password" { + + id = (known after apply) + + length = 32 + + lower = true + + min_lower = 0 + + min_numeric = 0 + + min_special = 0 + + min_upper = 0 + + number = true + + result = (known after apply) + + special = true + + upper = true + } + +Plan: 9 to add, 0 to change, 0 to destroy. + +------------------------------------------------------------------------ +``` + +\* Example shown with [Bash](https://www.gnu.org/software/bash/). For [Powershell](https://docs.microsoft.com/en-us/powershell/) replace backslashes with backticks. \ No newline at end of file diff --git a/quickstart/201-aks-helm/variables.tf b/quickstart/201-aks-helm/variables.tf new file mode 100644 index 00000000..06a7c398 --- /dev/null +++ b/quickstart/201-aks-helm/variables.tf @@ -0,0 +1,40 @@ +// Naming +variable "name" { + type = "string" + description = "Location of the azure resource group." + default = "quickstart-aks" +} + +variable "environment" { + type = "string" + description = "Name of the deployment environment" + default = "dev" +} + +// Resource information + +variable "location" { + type = "string" + description = "Location of the azure resource group." + default = "WestUS2" +} + +// Node type information + +variable "node_count" { + type = "string" + description = "The number of K8S nodes to provision." + default = 3 +} + +variable "node_type" { + type = "string" + description = "The size of each node." + default = "Standard_D1_v2" +} + +variable "dns_prefix" { + type = "string" + description = "DNS Prefix" + default = "tfquickstart" +} diff --git a/quickstart/201-aks-log-analytics/aks.tf b/quickstart/201-aks-log-analytics/aks.tf new file mode 100644 index 00000000..57d7089a --- /dev/null +++ b/quickstart/201-aks-log-analytics/aks.tf @@ -0,0 +1,27 @@ +resource "azurerm_kubernetes_cluster" "default" { + name = "${var.name}-aks" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + dns_prefix = "${var.dns_prefix}-${var.name}-aks-${var.environment}" + depends_on = ["azurerm_role_assignment.default"] + + agent_pool_profile { + name = "default" + count = "${var.node_count}" + vm_size = "${var.node_type}" + os_type = "Linux" + os_disk_size_gb = 30 + } + + service_principal { + client_id = "${azuread_application.default.application_id}" + client_secret = "${azuread_service_principal_password.default.value}" + } + + addon_profile { + oms_agent { + enabled = true + log_analytics_workspace_id = "${azurerm_log_analytics_workspace.default.id}" + } + } +} \ No newline at end of file diff --git a/quickstart/201-aks-log-analytics/analytics.tf b/quickstart/201-aks-log-analytics/analytics.tf new file mode 100644 index 00000000..bd990332 --- /dev/null +++ b/quickstart/201-aks-log-analytics/analytics.tf @@ -0,0 +1,20 @@ +resource "azurerm_log_analytics_workspace" "default" { + name = "${var.name}-${var.environment}-law" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + sku = "PerGB2018" + retention_in_days = 30 +} + +resource "azurerm_log_analytics_solution" "default" { + solution_name = "ContainerInsights" + location = "${azurerm_log_analytics_workspace.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + workspace_resource_id = "${azurerm_log_analytics_workspace.default.id}" + workspace_name = "${azurerm_log_analytics_workspace.default.name}" + + plan { + publisher = "Microsoft" + product = "OMSGallery/ContainerInsights" + } +} \ No newline at end of file diff --git a/quickstart/201-aks-log-analytics/azuread.tf b/quickstart/201-aks-log-analytics/azuread.tf new file mode 100644 index 00000000..de8cbd40 --- /dev/null +++ b/quickstart/201-aks-log-analytics/azuread.tf @@ -0,0 +1,24 @@ +resource "azuread_application" "default" { + name = "${var.name}-${var.environment}" +} + +resource "azuread_service_principal" "default" { + application_id = "${azuread_application.default.application_id}" +} + +resource "random_string" "password" { + length = 32 + special = true +} + +resource "azuread_service_principal_password" "default" { + service_principal_id = "${azuread_service_principal.default.id}" + value = "${random_string.password.result}" + end_date = "2099-01-01T01:00:00Z" +} + +resource "azurerm_role_assignment" "default" { + scope = "${data.azurerm_subscription.current.id}/resourceGroups/${azurerm_resource_group.default.name}" + role_definition_name = "Network Contributor" + principal_id = "${azuread_service_principal.default.id}" +} \ No newline at end of file diff --git a/quickstart/201-aks-log-analytics/main.tf b/quickstart/201-aks-log-analytics/main.tf new file mode 100644 index 00000000..a6cbe998 --- /dev/null +++ b/quickstart/201-aks-log-analytics/main.tf @@ -0,0 +1,18 @@ +# The Azure Active Resource Manager Terraform provider +provider "azurerm" { + version = "=1.36.1" +} + +# The Azure Active Directory Terraform provider +provider "azuread" { + version = "=0.6.0" +} + +# Reference to the current subscription. Used when creating role assignments +data "azurerm_subscription" "current" {} + +# The main resource group for this deployment +resource "azurerm_resource_group" "default" { + name = "${var.name}-${var.environment}-rg" + location = "${var.location}" +} diff --git a/quickstart/201-aks-log-analytics/readme.md b/quickstart/201-aks-log-analytics/readme.md new file mode 100644 index 00000000..d1bf4121 --- /dev/null +++ b/quickstart/201-aks-log-analytics/readme.md @@ -0,0 +1,238 @@ +# Azure Kubernetes Service + + +This template deploys an [Azure Kubernetes Service](https://www.terraform.io/docs/providers/azurerm/r/kubernetes_cluster.html) instance which sends system and container logs to Azure Log Analytics, which can be visualized with the Container Monitoring solution. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group all resources are deployed into | +| `azurerm_kubernetes_cluster` |The Azure Kubernetes Serice cluster | +| `azurerm_log_analytics_workspace` | A workspace to write cluster logs to | +| `azurerm_log_analytics_solution` | Enables the container monitoring solution for Log ANalytics| +| `azuread_application` |The application Identity the AKS cluster will use | +| `random_string` | A random string which will be saved and used with the service principal | +| `azuread_service_principal` |The service principal the AKS cluster will use | +| `azuread_service_principal_password` | The password for the Service principal | + + +## Variables + +| Name | Description | +|-|-| +| name | Name of the deployment | +| environment | The depolyment environment name (used for postfixing resource names) | +| prefix | A prefix for globally-unique dns-based resources | +| location | The Azure Region to deploy these resources in | +| node_type | The type of node to deploy on (e.g. d1v2) | +| node_count | The number of nodes to deploy | +| dns_prefix | A unique dns prefix | + + + +## Example + +```bash +> terraform plan +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + +data.azurerm_subscription.current: Refreshing state... + +------------------------------------------------------------------------ + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azuread_application.default will be created + + resource "azuread_application" "default" { + + application_id = (known after apply) + + homepage = (known after apply) + + id = (known after apply) + + identifier_uris = (known after apply) + + name = "quickstart-aks-dev" + + object_id = (known after apply) + + public_client = (known after apply) + + reply_urls = (known after apply) + + type = "webapp/api" + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal.default will be created + + resource "azuread_service_principal" "default" { + + application_id = (known after apply) + + display_name = (known after apply) + + id = (known after apply) + + object_id = (known after apply) + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal_password.default will be created + + resource "azuread_service_principal_password" "default" { + + end_date = "2099-01-01T01:00:00Z" + + id = (known after apply) + + key_id = (known after apply) + + service_principal_id = (known after apply) + + start_date = (known after apply) + + value = (sensitive value) + } + + # azurerm_kubernetes_cluster.default will be created + + resource "azurerm_kubernetes_cluster" "default" { + + dns_prefix = "tfquickstart-quickstart-aks-aks-dev" + + enable_pod_security_policy = (known after apply) + + fqdn = (known after apply) + + id = (known after apply) + + kube_admin_config = (known after apply) + + kube_admin_config_raw = (sensitive value) + + kube_config = (known after apply) + + kube_config_raw = (sensitive value) + + kubernetes_version = (known after apply) + + location = "westus2" + + name = "quickstart-aks-aks" + + node_resource_group = (known after apply) + + resource_group_name = "quickstart-aks-dev-rg" + + tags = (known after apply) + + + addon_profile { + + + oms_agent { + + enabled = true + + log_analytics_workspace_id = (known after apply) + } + } + + + agent_pool_profile { + + count = 3 + + dns_prefix = (known after apply) + + fqdn = (known after apply) + + max_pods = (known after apply) + + name = "default" + + os_disk_size_gb = 30 + + os_type = "Linux" + + type = "AvailabilitySet" + + vm_size = "Standard_D1_v2" + } + + + network_profile { + + dns_service_ip = (known after apply) + + docker_bridge_cidr = (known after apply) + + load_balancer_sku = (known after apply) + + network_plugin = (known after apply) + + network_policy = (known after apply) + + pod_cidr = (known after apply) + + service_cidr = (known after apply) + } + + + role_based_access_control { + + enabled = (known after apply) + + + azure_active_directory { + + client_app_id = (known after apply) + + server_app_id = (known after apply) + + server_app_secret = (sensitive value) + + tenant_id = (known after apply) + } + } + + + service_principal { + + client_id = (known after apply) + + client_secret = (sensitive value) + } + } + + # azurerm_log_analytics_solution.default will be created + + resource "azurerm_log_analytics_solution" "default" { + + id = (known after apply) + + location = "westus2" + + resource_group_name = "quickstart-aks-dev-rg" + + solution_name = "ContainerInsights" + + workspace_name = "quickstart-aks-dev-law" + + workspace_resource_id = (known after apply) + + + plan { + + name = (known after apply) + + product = "OMSGallery/ContainerInsights" + + publisher = "Microsoft" + } + } + + # azurerm_log_analytics_workspace.default will be created + + resource "azurerm_log_analytics_workspace" "default" { + + id = (known after apply) + + location = "westus2" + + name = "quickstart-aks-dev-law" + + portal_url = (known after apply) + + primary_shared_key = (sensitive value) + + resource_group_name = "quickstart-aks-dev-rg" + + retention_in_days = 30 + + secondary_shared_key = (sensitive value) + + sku = "PerGB2018" + + tags = (known after apply) + + workspace_id = (known after apply) + } + + # azurerm_resource_group.default will be created + + resource "azurerm_resource_group" "default" { + + id = (known after apply) + + location = "westus2" + + name = "quickstart-aks-dev-rg" + + tags = (known after apply) + } + + # azurerm_role_assignment.default will be created + + resource "azurerm_role_assignment" "default" { + + id = (known after apply) + + name = (known after apply) + + principal_id = (known after apply) + + principal_type = (known after apply) + + role_definition_id = (known after apply) + + role_definition_name = "Network Contributor" + + scope = "/subscriptions/b0e04a4a-a321-4b66-b8fd-13715262ba3c/resourceGroups/quickstart-aks-dev-rg" + + skip_service_principal_aad_check = (known after apply) + } + + # random_string.password will be created + + resource "random_string" "password" { + + id = (known after apply) + + length = 32 + + lower = true + + min_lower = 0 + + min_numeric = 0 + + min_special = 0 + + min_upper = 0 + + number = true + + result = (known after apply) + + special = true + + upper = true + } + +Plan: 9 to add, 0 to change, 0 to destroy. + +------------------------------------------------------------------------ +``` diff --git a/quickstart/201-aks-log-analytics/variables.tf b/quickstart/201-aks-log-analytics/variables.tf new file mode 100644 index 00000000..06a7c398 --- /dev/null +++ b/quickstart/201-aks-log-analytics/variables.tf @@ -0,0 +1,40 @@ +// Naming +variable "name" { + type = "string" + description = "Location of the azure resource group." + default = "quickstart-aks" +} + +variable "environment" { + type = "string" + description = "Name of the deployment environment" + default = "dev" +} + +// Resource information + +variable "location" { + type = "string" + description = "Location of the azure resource group." + default = "WestUS2" +} + +// Node type information + +variable "node_count" { + type = "string" + description = "The number of K8S nodes to provision." + default = 3 +} + +variable "node_type" { + type = "string" + description = "The size of each node." + default = "Standard_D1_v2" +} + +variable "dns_prefix" { + type = "string" + description = "DNS Prefix" + default = "tfquickstart" +} diff --git a/quickstart/201-aks-rbac-dashboard-admin/aks.tf b/quickstart/201-aks-rbac-dashboard-admin/aks.tf new file mode 100644 index 00000000..de617e27 --- /dev/null +++ b/quickstart/201-aks-rbac-dashboard-admin/aks.tf @@ -0,0 +1,24 @@ +resource "azurerm_kubernetes_cluster" "default" { + name = "${var.name}-aks" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + dns_prefix = "${var.dns_prefix}-${var.name}-aks-${var.environment}" + depends_on = ["azurerm_role_assignment.default"] + + agent_pool_profile { + name = "default" + count = "${var.node_count}" + vm_size = "${var.node_type}" + os_type = "Linux" + os_disk_size_gb = 30 + } + + service_principal { + client_id = "${azuread_application.default.application_id}" + client_secret = "${azuread_service_principal_password.default.value}" + } + + role_based_access_control { + enabled = true + } +} \ No newline at end of file diff --git a/quickstart/201-aks-rbac-dashboard-admin/azuread.tf b/quickstart/201-aks-rbac-dashboard-admin/azuread.tf new file mode 100644 index 00000000..de8cbd40 --- /dev/null +++ b/quickstart/201-aks-rbac-dashboard-admin/azuread.tf @@ -0,0 +1,24 @@ +resource "azuread_application" "default" { + name = "${var.name}-${var.environment}" +} + +resource "azuread_service_principal" "default" { + application_id = "${azuread_application.default.application_id}" +} + +resource "random_string" "password" { + length = 32 + special = true +} + +resource "azuread_service_principal_password" "default" { + service_principal_id = "${azuread_service_principal.default.id}" + value = "${random_string.password.result}" + end_date = "2099-01-01T01:00:00Z" +} + +resource "azurerm_role_assignment" "default" { + scope = "${data.azurerm_subscription.current.id}/resourceGroups/${azurerm_resource_group.default.name}" + role_definition_name = "Network Contributor" + principal_id = "${azuread_service_principal.default.id}" +} \ No newline at end of file diff --git a/quickstart/201-aks-rbac-dashboard-admin/kubernetes.tf b/quickstart/201-aks-rbac-dashboard-admin/kubernetes.tf new file mode 100644 index 00000000..ba6724c7 --- /dev/null +++ b/quickstart/201-aks-rbac-dashboard-admin/kubernetes.tf @@ -0,0 +1,28 @@ +# Define Kubernetes provider to use the AKS cluster +provider "kubernetes" { + host = "${azurerm_kubernetes_cluster.default.kube_config.0.host}" + + client_certificate = "${base64decode(azurerm_kubernetes_cluster.default.kube_config.0.client_certificate)}" + client_key = "${base64decode(azurerm_kubernetes_cluster.default.kube_config.0.client_key)}" + cluster_ca_certificate = "${base64decode(azurerm_kubernetes_cluster.default.kube_config.0.cluster_ca_certificate)}" +} + +# Grant cluster-admin rights to the kubernetes-dashboard account. +# THIS IS NOT RECOMMENDED IN PRODUTION +resource "kubernetes_cluster_role_binding" "dashboard" { + metadata { + name = "kubernetes-dashboard" + } + + role_ref { + api_group = "rbac.authorization.k8s.io" + kind = "ClusterRole" + name = "cluster-admin" + } + + subject { + kind = "ServiceAccount" + name = "kubernetes-dashboard" + namespace = "kube-system" + } +} diff --git a/quickstart/201-aks-rbac-dashboard-admin/main.tf b/quickstart/201-aks-rbac-dashboard-admin/main.tf new file mode 100644 index 00000000..a6cbe998 --- /dev/null +++ b/quickstart/201-aks-rbac-dashboard-admin/main.tf @@ -0,0 +1,18 @@ +# The Azure Active Resource Manager Terraform provider +provider "azurerm" { + version = "=1.36.1" +} + +# The Azure Active Directory Terraform provider +provider "azuread" { + version = "=0.6.0" +} + +# Reference to the current subscription. Used when creating role assignments +data "azurerm_subscription" "current" {} + +# The main resource group for this deployment +resource "azurerm_resource_group" "default" { + name = "${var.name}-${var.environment}-rg" + location = "${var.location}" +} diff --git a/quickstart/201-aks-rbac-dashboard-admin/readme.md b/quickstart/201-aks-rbac-dashboard-admin/readme.md new file mode 100644 index 00000000..4bab7756 --- /dev/null +++ b/quickstart/201-aks-rbac-dashboard-admin/readme.md @@ -0,0 +1,230 @@ +# Azure Kubernetes Service + + +This template deploys an [Azure Kubernetes Service](https://www.terraform.io/docs/providers/azurerm/r/kubernetes_cluster.html) instance with Role Based Access Control (RBAC) enabled. With this, by default the robust Kubernetes dashboard has no rights to view or make changes to the cluster. In this template we leverage the Kubernetes provider to provision a role binding for the Dashboard accoutn to give it `cluster-admin` rights - something we shoudl not do in production but can be very useful in development. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group all resources are deployed into | +| `azurerm_kubernetes_cluster` |The Azure Kubernetes Serice cluster | +| `azuread_application` |The application Identity the AKS cluster will use | +| `random_string` | A random string which will be saved and used with the service principal | +| `azuread_service_principal` |The service principal the AKS cluster will use | +| `azuread_service_principal_password` | The password for the Service principal | + + +## Variables + +| Name | Description | +|-|-| +| name | Name of the deployment | +| environment | The depolyment environment name (used for postfixing resource names) | +| prefix | A prefix for globally-unique dns-based resources | +| location | The Azure Region to deploy these resources in | +| node_type | The type of node to deploy on (e.g. d1v2) | +| node_count | The number of nodes to deploy | +| dns_prefix | A unique dns prefix | + + + +## Example + +```bash +> terraform plan + +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + +data.azurerm_subscription.current: Refreshing state... + +------------------------------------------------------------------------ + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azuread_application.default will be created + + resource "azuread_application" "default" { + + application_id = (known after apply) + + homepage = (known after apply) + + id = (known after apply) + + identifier_uris = (known after apply) + + name = "quickstart-aks-dev" + + object_id = (known after apply) + + public_client = (known after apply) + + reply_urls = (known after apply) + + type = "webapp/api" + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal.default will be created + + resource "azuread_service_principal" "default" { + + application_id = (known after apply) + + display_name = (known after apply) + + id = (known after apply) + + object_id = (known after apply) + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal_password.default will be created + + resource "azuread_service_principal_password" "default" { + + end_date = "2099-01-01T01:00:00Z" + + id = (known after apply) + + key_id = (known after apply) + + service_principal_id = (known after apply) + + start_date = (known after apply) + + value = (sensitive value) + } + + # azurerm_kubernetes_cluster.default will be created + + resource "azurerm_kubernetes_cluster" "default" { + + dns_prefix = "tfquickstart-quickstart-aks-aks-dev" + + enable_pod_security_policy = (known after apply) + + fqdn = (known after apply) + + id = (known after apply) + + kube_admin_config = (known after apply) + + kube_admin_config_raw = (sensitive value) + + kube_config = (known after apply) + + kube_config_raw = (sensitive value) + + kubernetes_version = (known after apply) + + location = "westus2" + + name = "quickstart-aks-aks" + + node_resource_group = (known after apply) + + resource_group_name = "quickstart-aks-dev-rg" + + tags = (known after apply) + + + addon_profile { + + + oms_agent { + + enabled = true + + log_analytics_workspace_id = (known after apply) + } + } + + + agent_pool_profile { + + count = 3 + + dns_prefix = (known after apply) + + fqdn = (known after apply) + + max_pods = (known after apply) + + name = "default" + + os_disk_size_gb = 30 + + os_type = "Linux" + + type = "AvailabilitySet" + + vm_size = "Standard_D1_v2" + } + + + network_profile { + + dns_service_ip = (known after apply) + + docker_bridge_cidr = (known after apply) + + load_balancer_sku = (known after apply) + + network_plugin = (known after apply) + + network_policy = (known after apply) + + pod_cidr = (known after apply) + + service_cidr = (known after apply) + } + + + role_based_access_control { + + enabled = true + } + + + service_principal { + + client_id = (known after apply) + + client_secret = (sensitive value) + } + } + + # azurerm_log_analytics_solution.default will be created + + resource "azurerm_log_analytics_solution" "default" { + + id = (known after apply) + + location = "westus2" + + resource_group_name = "quickstart-aks-dev-rg" + + solution_name = "ContainerInsights" + + workspace_name = "quickstart-aks-dev-law" + + workspace_resource_id = (known after apply) + + + plan { + + name = (known after apply) + + product = "OMSGallery/ContainerInsights" + + publisher = "Microsoft" + } + } + + # azurerm_log_analytics_workspace.default will be created + + resource "azurerm_log_analytics_workspace" "default" { + + id = (known after apply) + + location = "westus2" + + name = "quickstart-aks-dev-law" + + portal_url = (known after apply) + + primary_shared_key = (sensitive value) + + resource_group_name = "quickstart-aks-dev-rg" + + retention_in_days = 30 + + secondary_shared_key = (sensitive value) + + sku = "PerGB2018" + + tags = (known after apply) + + workspace_id = (known after apply) + } + + # azurerm_resource_group.default will be created + + resource "azurerm_resource_group" "default" { + + id = (known after apply) + + location = "westus2" + + name = "quickstart-aks-dev-rg" + + tags = (known after apply) + } + + # azurerm_role_assignment.default will be created + + resource "azurerm_role_assignment" "default" { + + id = (known after apply) + + name = (known after apply) + + principal_id = (known after apply) + + principal_type = (known after apply) + + role_definition_id = (known after apply) + + role_definition_name = "Network Contributor" + + scope = "/subscriptions/b0e04a4a-a321-4b66-b8fd-13715262ba3c/resourceGroups/quickstart-aks-dev-rg" + + skip_service_principal_aad_check = (known after apply) + } + + # random_string.password will be created + + resource "random_string" "password" { + + id = (known after apply) + + length = 32 + + lower = true + + min_lower = 0 + + min_numeric = 0 + + min_special = 0 + + min_upper = 0 + + number = true + + result = (known after apply) + + special = true + + upper = true + } + +Plan: 9 to add, 0 to change, 0 to destroy. + +------------------------------------------------------------------------ +``` diff --git a/quickstart/201-aks-rbac-dashboard-admin/variables.tf b/quickstart/201-aks-rbac-dashboard-admin/variables.tf new file mode 100644 index 00000000..06a7c398 --- /dev/null +++ b/quickstart/201-aks-rbac-dashboard-admin/variables.tf @@ -0,0 +1,40 @@ +// Naming +variable "name" { + type = "string" + description = "Location of the azure resource group." + default = "quickstart-aks" +} + +variable "environment" { + type = "string" + description = "Name of the deployment environment" + default = "dev" +} + +// Resource information + +variable "location" { + type = "string" + description = "Location of the azure resource group." + default = "WestUS2" +} + +// Node type information + +variable "node_count" { + type = "string" + description = "The number of K8S nodes to provision." + default = 3 +} + +variable "node_type" { + type = "string" + description = "The size of each node." + default = "Standard_D1_v2" +} + +variable "dns_prefix" { + type = "string" + description = "DNS Prefix" + default = "tfquickstart" +} diff --git a/quickstart/201-azure-pipelines-ci-cd/readme.md b/quickstart/201-azure-pipelines-ci-cd/readme.md new file mode 100644 index 00000000..1f6a3e85 --- /dev/null +++ b/quickstart/201-azure-pipelines-ci-cd/readme.md @@ -0,0 +1,18 @@ +# Azure Pipelines Multi-Stage CI/CD + +This template deploys a basic Azure Web App leveraging CI/CD through Azure Pipelines to a single environment + +## Variables + +| Name | Description | +|-|-| +| name | Name of the deployment | +| environment | The depolyment environment name (used for postfixing resource names) | +| location | The Azure Region to deploy these resources in | +| plan_sku | The SKU of the App Service Plan to host the webapp | +| prefix | A DNS Prefix to use in the AKS Cluster | + + +## Usage + +Set up a Pipeline in Azure Pipelines pointing to azure-pipelines.yml. diff --git a/quickstart/201-storage-static-website-cdn-ssl/readme.md b/quickstart/201-storage-static-website-cdn-ssl/readme.md new file mode 100644 index 00000000..e43355b2 --- /dev/null +++ b/quickstart/201-storage-static-website-cdn-ssl/readme.md @@ -0,0 +1,36 @@ +# CDN + static website hosted on Azure Storage + + +This template deploys a static website hosted on an [Azure Storage Account](https://www.terraform.io/docs/providers/azurerm/r/storage_account.html) fronted by a CDN configured to support SSL. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group all resources are deployed into | +| `azurerm_storage_account` | The storage account used to host the website | + +## Variables + +| Name | Description | +|-|-| +| `name` | Name of the deployment | +| `environment` | The depolyment environment name (used for postfixing resource names) | +| `prefix` | A prefix for globally-unique dns-based resources | +| `location` | The Azure Region to deploy these resources in | + + +## Usage + +```bash +terraform plan \ + -var 'name=demo-docker' \ + -var 'environment=staging' \ + -var 'location=West US 2' + -var 'prefix=tfquickstard' \ + -out demo.tfplan + +terraform apply demo.tfplan +``` + +\* Example shown with [Bash](https://www.gnu.org/software/bash/). For [Powershell](https://docs.microsoft.com/en-us/powershell/) replace backslashes with backticks. \ No newline at end of file diff --git a/quickstart/201-vmss-appgw-waf/readme.md b/quickstart/201-vmss-appgw-waf/readme.md new file mode 100644 index 00000000..37ca8076 --- /dev/null +++ b/quickstart/201-vmss-appgw-waf/readme.md @@ -0,0 +1,36 @@ +# Scalable Virtual Machine behind a Web Application Firewall + +This template deploys a Virtual Machine Scale Set fronted by an Azure Application Gateway that has the Web Application Firewall (WAF) enabled. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group all resources are deployed into | +| `azurerm_virtual_machine_scale_set` | The storage account used to host the website | +| `azurerm_application_gateway` | The storage account used to host the website | + +## Variables + +| Name | Description | +|-|-| +| `name` | Name of the deployment | +| `environment` | The depolyment environment name (used for postfixing resource names) | +| `prefix` | A prefix for globally-unique dns-based resources | +| `location` | The Azure Region to deploy these resources in | + + +## Usage + +```bash +terraform plan \ + -var 'name=demo-docker' \ + -var 'environment=staging' \ + -var 'location=West US 2' + -var 'prefix=tfquickstard' \ + -out demo.tfplan + +terraform apply demo.tfplan +``` + +\* Example shown with [Bash](https://www.gnu.org/software/bash/). For [Powershell](https://docs.microsoft.com/en-us/powershell/) replace backslashes with backticks. \ No newline at end of file diff --git a/quickstart/201-web-app-docker-acr/acr.tf b/quickstart/201-web-app-docker-acr/acr.tf new file mode 100644 index 00000000..3c0c5ced --- /dev/null +++ b/quickstart/201-web-app-docker-acr/acr.tf @@ -0,0 +1,11 @@ +locals { + acr_name = "${replace(var.dns_prefix, "-", "")}${replace(var.name, "-", "")}acr" +} + +resource "azurerm_container_registry" "default" { + name = "${local.acr_name}" + resource_group_name = "${azurerm_resource_group.default.name}" + location = "${azurerm_resource_group.default.location}" + sku = "Standard" + admin_enabled = false +} \ No newline at end of file diff --git a/quickstart/201-web-app-docker-acr/app_service.tf b/quickstart/201-web-app-docker-acr/app_service.tf new file mode 100644 index 00000000..5c907495 --- /dev/null +++ b/quickstart/201-web-app-docker-acr/app_service.tf @@ -0,0 +1,27 @@ + +resource "azurerm_app_service_plan" "default" { + name = "${var.name}-plan" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + kind = "Linux" + + # Reserved must be set to true for Linux App Service Plans + reserved = true + + sku { + tier = "${var.plan_tier}" + size = "${var.plan_sku}" + } +} + +resource "azurerm_app_service" "default" { + name = "${var.dns_prefix}-${var.name}-${var.environment}-app" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + app_service_plan_id = "${azurerm_app_service_plan.default.id}" + + site_config { + always_on = true + linux_fx_version = "DOCKER|nginxdemos/hello" + } +} diff --git a/quickstart/201-web-app-docker-acr/azurerm_role_assignment.tf b/quickstart/201-web-app-docker-acr/azurerm_role_assignment.tf new file mode 100644 index 00000000..fa6a3e35 --- /dev/null +++ b/quickstart/201-web-app-docker-acr/azurerm_role_assignment.tf @@ -0,0 +1,5 @@ +resource "azurerm_role_assignment" "acr" { + scope = "${data.azurerm_subscription.current.id}/resourceGroups/${azurerm_resource_group.default.name}/providers/Microsoft.Web/serverFarms/${azurerm_app_service.default.name}" + role_definition_name = "Reader" + principal_id = "${azurerm_app_service.default.identity[0].principal_id}" +} \ No newline at end of file diff --git a/quickstart/201-web-app-docker-acr/main.tf b/quickstart/201-web-app-docker-acr/main.tf new file mode 100644 index 00000000..acaf6e4b --- /dev/null +++ b/quickstart/201-web-app-docker-acr/main.tf @@ -0,0 +1,11 @@ +provider "azurerm" { + version = "=1.36.1" +} + +# Reference to the current subscription. Used when creating role assignments +data "azurerm_subscription" "current" {} + +resource "azurerm_resource_group" "default" { + name = "${var.name}-${var.environment}-rg" + location = "${var.location}" +} diff --git a/quickstart/201-web-app-docker-acr/readme.md b/quickstart/201-web-app-docker-acr/readme.md new file mode 100644 index 00000000..ed913b2f --- /dev/null +++ b/quickstart/201-web-app-docker-acr/readme.md @@ -0,0 +1,237 @@ +# Containerized Web App with an Azure Container Registry + + +This template deploys an [Azure App Service](https://www.terraform.io/docs/providers/azurerm/r/app_service.html) with a system-assigned identity running Linux configured for a containerized application. This template also deploys an Azure Container Registry and grants read access to the Web App. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group all resources are deployed into | +| `azurerm_app_service_plan` | The underlying plan that the web app will run on | +| `azurerm_app_service` | The Linux web app | +| `azurerm_container_registry` | The Azure Container Registry instance | +| `azurerm_role_assignment` | The role assignment between the container registry and the app service | + +## Variables + +| Name | Description | +|-|-| +| `name` | Name of the deployment | +| `environment` | The depolyment environment name (used for postfixing resource names) | +| `dns_prefix` | A prefix for globally-unique dns-based resources | +| `location` | The Azure Region to deploy these resources in | +| `plan_tier` | The App Service Plan tier to deploy | +| `plan_sku` | The App Service Plan SKU to deploy| + + +## Example + +```bash +> terraform plan +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + +data.azurerm_subscription.current: Refreshing state... + +------------------------------------------------------------------------ + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azurerm_app_service.default will be created + + resource "azurerm_app_service" "default" { + + app_service_plan_id = (known after apply) + + app_settings = (known after apply) + + client_affinity_enabled = (known after apply) + + default_site_hostname = (known after apply) + + enabled = true + + https_only = false + + id = (known after apply) + + location = "westus2" + + name = "tfq-demo-tfquickstart-dev-app" + + outbound_ip_addresses = (known after apply) + + possible_outbound_ip_addresses = (known after apply) + + resource_group_name = "demo-tfquickstart-dev-rg" + + site_credential = (known after apply) + + source_control = (known after apply) + + tags = (known after apply) + + + auth_settings { + + additional_login_params = (known after apply) + + allowed_external_redirect_urls = (known after apply) + + default_provider = (known after apply) + + enabled = (known after apply) + + issuer = (known after apply) + + runtime_version = (known after apply) + + token_refresh_extension_hours = (known after apply) + + token_store_enabled = (known after apply) + + unauthenticated_client_action = (known after apply) + + + active_directory { + + allowed_audiences = (known after apply) + + client_id = (known after apply) + + client_secret = (sensitive value) + } + + + facebook { + + app_id = (known after apply) + + app_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + google { + + client_id = (known after apply) + + client_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + microsoft { + + client_id = (known after apply) + + client_secret = (sensitive value) + + oauth_scopes = (known after apply) + } + + + twitter { + + consumer_key = (known after apply) + + consumer_secret = (sensitive value) + } + } + + + connection_string { + + name = (known after apply) + + type = (known after apply) + + value = (sensitive value) + } + + + identity { + + identity_ids = (known after apply) + + principal_id = (known after apply) + + tenant_id = (known after apply) + + type = (known after apply) + } + + + logs { + + application_logs { + + azure_blob_storage { + + level = (known after apply) + + retention_in_days = (known after apply) + + sas_url = (sensitive value) + } + } + + + http_logs { + + azure_blob_storage { + + retention_in_days = (known after apply) + + sas_url = (sensitive value) + } + + + file_system { + + retention_in_days = (known after apply) + + retention_in_mb = (known after apply) + } + } + } + + + site_config { + + always_on = true + + dotnet_framework_version = "v4.0" + + ftps_state = (known after apply) + + http2_enabled = false + + ip_restriction = (known after apply) + + linux_fx_version = "DOCKER|nginxdemos/hello" + + local_mysql_enabled = (known after apply) + + managed_pipeline_mode = (known after apply) + + min_tls_version = (known after apply) + + remote_debugging_enabled = false + + remote_debugging_version = (known after apply) + + scm_type = "None" + + websockets_enabled = (known after apply) + + windows_fx_version = (known after apply) + + + cors { + + allowed_origins = (known after apply) + + support_credentials = (known after apply) + } + } + + + storage_account { + + access_key = (sensitive value) + + account_name = (known after apply) + + mount_path = (known after apply) + + name = (known after apply) + + share_name = (known after apply) + + type = (known after apply) + } + } + + # azurerm_app_service_plan.default will be created + + resource "azurerm_app_service_plan" "default" { + + app_service_environment_id = (known after apply) + + id = (known after apply) + + kind = "Linux" + + location = "westus2" + + maximum_elastic_worker_count = (known after apply) + + maximum_number_of_workers = (known after apply) + + name = "demo-tfquickstart-plan" + + per_site_scaling = (known after apply) + + reserved = true + + resource_group_name = "demo-tfquickstart-dev-rg" + + tags = (known after apply) + + + properties { + + app_service_environment_id = (known after apply) + + per_site_scaling = (known after apply) + + reserved = (known after apply) + } + + + sku { + + capacity = (known after apply) + + size = "S1" + + tier = "Standard" + } + } + + # azurerm_container_registry.default will be created + + resource "azurerm_container_registry" "default" { + + admin_enabled = false + + admin_password = (sensitive value) + + admin_username = (known after apply) + + id = (known after apply) + + location = "westus2" + + login_server = (known after apply) + + name = "tfqdemotfquickstartacr" + + network_rule_set = (known after apply) + + resource_group_name = "demo-tfquickstart-dev-rg" + + sku = "Standard" + + tags = (known after apply) + } + + # azurerm_resource_group.default will be created + + resource "azurerm_resource_group" "default" { + + id = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-dev-rg" + + tags = (known after apply) + } + + # azurerm_role_assignment.acr will be created + + resource "azurerm_role_assignment" "acr" { + + id = (known after apply) + + name = (known after apply) + + principal_id = (known after apply) + + principal_type = (known after apply) + + role_definition_id = (known after apply) + + role_definition_name = "Reader" + + scope = "/subscriptions/b0e04a4a-a321-4b66-b8fd-13715262ba3c/resourceGroups/demo-tfquickstart-dev-rg/providers/Microsoft.Web/serverFarms/tfq-demo-tfquickstart-dev-app" + + skip_service_principal_aad_check = (known after apply) + } + +Plan: 5 to add, 0 to change, 0 to destroy. + +------------------------------------------------------------------------ +``` diff --git a/quickstart/201-web-app-docker-acr/variables.tf b/quickstart/201-web-app-docker-acr/variables.tf new file mode 100644 index 00000000..4c9a825b --- /dev/null +++ b/quickstart/201-web-app-docker-acr/variables.tf @@ -0,0 +1,35 @@ +variable "name" { + type = "string" + description = "Location of the azure resource group." + default = "demo-tfquickstart" +} + +variable "environment" { + type = "string" + description = "Name of the deployment environment" + default = "dev" +} + +variable "location" { + type = "string" + description = "Location to deploy the resoruce group" + default = "West US 2" +} + +variable "dns_prefix" { + type = "string" + description = "A prefix for any dns based resources" + default = "tfq" +} + +variable "plan_tier" { + type = "string" + description = "The tier of app service plan to create" + default = "Standard" +} + +variable "plan_sku" { + type = "string" + description = "The sku of app service plan to create" + default = "S1" +} diff --git a/quickstart/201-web-app-postgres-keyvault/README.md b/quickstart/201-web-app-postgres-keyvault/README.md new file mode 100644 index 00000000..e69de29b diff --git a/quickstart/WebAppMySql/main.tf b/quickstart/201-web-app-postgres-keyvault/main.tf similarity index 97% rename from quickstart/WebAppMySql/main.tf rename to quickstart/201-web-app-postgres-keyvault/main.tf index 7dfd86a8..a301216e 100644 --- a/quickstart/WebAppMySql/main.tf +++ b/quickstart/201-web-app-postgres-keyvault/main.tf @@ -1,5 +1,5 @@ -resource "azurerm_resource_group" "webAppMySqlRg" { - name = "${var.rg}" - location = "${var.loc}" - tags = "${var.tags}" -} +resource "azurerm_resource_group" "webAppMySqlRg" { + name = "${var.rg}" + location = "${var.loc}" + tags = "${var.tags}" +} diff --git a/quickstart/WebAppMySql/mysql.tf b/quickstart/201-web-app-postgres-keyvault/mysql.tf similarity index 97% rename from quickstart/WebAppMySql/mysql.tf rename to quickstart/201-web-app-postgres-keyvault/mysql.tf index 8c424e48..73d0eec0 100644 --- a/quickstart/WebAppMySql/mysql.tf +++ b/quickstart/201-web-app-postgres-keyvault/mysql.tf @@ -1,29 +1,29 @@ -resource "azurerm_mysql_server" "webAppBackend" { - name = "${var.siteName}pgserver" - location = "${azurerm_resource_group.webAppMySqlRg.location}" - resource_group_name = "${azurerm_resource_group.webAppMySqlRg.name}" - tags = "${azurerm_resource_group.webAppMySqlRg.tags}" - - administrator_login = "${var.administratorLogin}" - administrator_login_password = "${var.administratorLoginPassword}" - version = "${var.mysqlVersion}" - ssl_enforcement = "Disabled" - sku { - name = "${var.databaseSkuName}" - capacity = "${var.databaseDTU}" - tier = "${var.databaseSkuTier}" - family = "${var.databaseSkuFamily}" - } - storage_profile { - storage_mb = "${var.databaseSkuSizeMB}" - } -} - -resource "azurerm_mysql_database" "webAppBackend" { - name = "${var.siteName}database" - resource_group_name = "${azurerm_resource_group.webAppMySqlRg.name}" - - server_name = "${azurerm_mysql_server.webAppBackend.name}" - charset = "utf8" - collation = "utf8_unicode_ci" +resource "azurerm_mysql_server" "webAppBackend" { + name = "${var.siteName}pgserver" + location = "${azurerm_resource_group.webAppMySqlRg.location}" + resource_group_name = "${azurerm_resource_group.webAppMySqlRg.name}" + tags = "${azurerm_resource_group.webAppMySqlRg.tags}" + + administrator_login = "${var.administratorLogin}" + administrator_login_password = "${var.administratorLoginPassword}" + version = "${var.mysqlVersion}" + ssl_enforcement = "Disabled" + sku { + name = "${var.databaseSkuName}" + capacity = "${var.databaseDTU}" + tier = "${var.databaseSkuTier}" + family = "${var.databaseSkuFamily}" + } + storage_profile { + storage_mb = "${var.databaseSkuSizeMB}" + } +} + +resource "azurerm_mysql_database" "webAppBackend" { + name = "${var.siteName}database" + resource_group_name = "${azurerm_resource_group.webAppMySqlRg.name}" + + server_name = "${azurerm_mysql_server.webAppBackend.name}" + charset = "utf8" + collation = "utf8_unicode_ci" } \ No newline at end of file diff --git a/quickstart/WebAppMySql/output.tf b/quickstart/201-web-app-postgres-keyvault/output.tf similarity index 96% rename from quickstart/WebAppMySql/output.tf rename to quickstart/201-web-app-postgres-keyvault/output.tf index 04c8be83..3a0f203e 100644 --- a/quickstart/WebAppMySql/output.tf +++ b/quickstart/201-web-app-postgres-keyvault/output.tf @@ -1,15 +1,15 @@ -output "webAppUrl" { - value = "${azurerm_app_service.webAppFrontend.default_site_hostname}" -} - -output "databaseName" { - value = "${azurerm_mysql_database.webAppBackend.name}" -} - -output "databaseServerName" { - value = "${azurerm_mysql_server.webAppBackend.fqdn}" -} - -output "appServicePlanName" { - value = "${azurerm_app_service_plan.webAppFrontend.name}" -} +output "webAppUrl" { + value = "${azurerm_app_service.webAppFrontend.default_site_hostname}" +} + +output "databaseName" { + value = "${azurerm_mysql_database.webAppBackend.name}" +} + +output "databaseServerName" { + value = "${azurerm_mysql_server.webAppBackend.fqdn}" +} + +output "appServicePlanName" { + value = "${azurerm_app_service_plan.webAppFrontend.name}" +} diff --git a/quickstart/WebAppMySql/providers.tf b/quickstart/201-web-app-postgres-keyvault/providers.tf similarity index 95% rename from quickstart/WebAppMySql/providers.tf rename to quickstart/201-web-app-postgres-keyvault/providers.tf index 7e54e2f8..3d733e28 100644 --- a/quickstart/WebAppMySql/providers.tf +++ b/quickstart/201-web-app-postgres-keyvault/providers.tf @@ -1,3 +1,3 @@ -provider "azurerm" { - version = "~>1.17" +provider "azurerm" { + version = "~>1.17" } \ No newline at end of file diff --git a/quickstart/WebAppMySql/terraform.tfvars b/quickstart/201-web-app-postgres-keyvault/terraform.tfvars similarity index 95% rename from quickstart/WebAppMySql/terraform.tfvars rename to quickstart/201-web-app-postgres-keyvault/terraform.tfvars index 5f018616..63898d17 100644 --- a/quickstart/WebAppMySql/terraform.tfvars +++ b/quickstart/201-web-app-postgres-keyvault/terraform.tfvars @@ -1,12 +1,12 @@ -rg = "mcg623webAppMysql" -loc = "eastus2" -tags = { - type = "sample" - services = "MySql, WebApp, Azure database" -} - -administratorLogin = "markg" -siteName = "mcgecd69mysql" - -servicePlanTier = "Standard" +rg = "mcg623webAppMysql" +loc = "eastus2" +tags = { + type = "sample" + services = "MySql, WebApp, Azure database" +} + +administratorLogin = "markg" +siteName = "mcgecd69mysql" + +servicePlanTier = "Standard" servicePlanSize = "S1" \ No newline at end of file diff --git a/quickstart/WebAppMySql/variables.tf b/quickstart/201-web-app-postgres-keyvault/variables.tf similarity index 95% rename from quickstart/WebAppMySql/variables.tf rename to quickstart/201-web-app-postgres-keyvault/variables.tf index a1df8a02..42a0d171 100644 --- a/quickstart/WebAppMySql/variables.tf +++ b/quickstart/201-web-app-postgres-keyvault/variables.tf @@ -1,65 +1,65 @@ -variable "rg" { - description = "Azure resource group for all resources." -} - -variable "siteName" { - description = "Name of azure web app" -} - -variable "tags" { - description = "Azure Tags for all resources." - default = {} -} - - -variable "administratorLogin" { - description = "Database administrator login name" -} - -variable "administratorLoginPassword" { - description = "Database administrator password" -} - -variable "databaseDTU" { - description = "Azure database for MySQL pricing tier" - default = 2 -} - -variable "databaseSkuName" { - description = "Azure database for MySQL sku name" - default = "GP_Gen4_2" -} - -variable "databaseSkuFamily" { - description = "Azure database for MySQL sku family" - default = "Gen4" -} - - -variable "databaseSkuSizeMB" { - description = "Azure database for MySQL Sku Size" - default = 5120 -} - -variable "databaseSkuTier" { - description = "Azure database for MySQL pricing tier" - default = "GeneralPurpose" -} - -variable "mysqlVersion" { - description = "MySQL version" - default = "5.6" -} - -variable "loc" { - description = "Location for all resources." - default = "eastus2" -} - -variable "servicePlanTier" { - description = "Azure managed application service plan pricing tier" -} - -variable "servicePlanSize" { - description = "Azure managed application service plan instance size" -} +variable "rg" { + description = "Azure resource group for all resources." +} + +variable "siteName" { + description = "Name of azure web app" +} + +variable "tags" { + description = "Azure Tags for all resources." + default = {} +} + + +variable "administratorLogin" { + description = "Database administrator login name" +} + +variable "administratorLoginPassword" { + description = "Database administrator password" +} + +variable "databaseDTU" { + description = "Azure database for MySQL pricing tier" + default = 2 +} + +variable "databaseSkuName" { + description = "Azure database for MySQL sku name" + default = "GP_Gen4_2" +} + +variable "databaseSkuFamily" { + description = "Azure database for MySQL sku family" + default = "Gen4" +} + + +variable "databaseSkuSizeMB" { + description = "Azure database for MySQL Sku Size" + default = 5120 +} + +variable "databaseSkuTier" { + description = "Azure database for MySQL pricing tier" + default = "GeneralPurpose" +} + +variable "mysqlVersion" { + description = "MySQL version" + default = "5.6" +} + +variable "loc" { + description = "Location for all resources." + default = "eastus2" +} + +variable "servicePlanTier" { + description = "Azure managed application service plan pricing tier" +} + +variable "servicePlanSize" { + description = "Azure managed application service plan instance size" +} diff --git a/quickstart/WebAppMySql/webapp.tf b/quickstart/201-web-app-postgres-keyvault/webapp.tf similarity index 97% rename from quickstart/WebAppMySql/webapp.tf rename to quickstart/201-web-app-postgres-keyvault/webapp.tf index 2e29d67a..416eab5e 100644 --- a/quickstart/WebAppMySql/webapp.tf +++ b/quickstart/201-web-app-postgres-keyvault/webapp.tf @@ -1,25 +1,25 @@ -resource "azurerm_app_service_plan" "webAppFrontend" { - name = "${var.siteName}serviceplan" - resource_group_name = "${azurerm_resource_group.webAppMySqlRg.name}" - location = "${azurerm_resource_group.webAppMySqlRg.location}" - tags = "${azurerm_resource_group.webAppMySqlRg.tags}" - - sku { - tier = "${var.servicePlanTier}" - size = "${var.servicePlanSize}" - } -} - -resource "azurerm_app_service" "webAppFrontend" { - name = "${var.siteName}" - location = "${azurerm_resource_group.webAppMySqlRg.location}" - resource_group_name = "${azurerm_resource_group.webAppMySqlRg.name}" - tags = "${azurerm_resource_group.webAppMySqlRg.tags}" - - app_service_plan_id = "${azurerm_app_service_plan.webAppFrontend.id}" - connection_string { - name = "DefaultConnect" - type = "MySql" - value = "Database=${azurerm_mysql_database.webAppBackend.name};Data Source=${azurerm_mysql_server.webAppBackend.fqdn};User Id=${var.administratorLogin}@${azurerm_mysql_server.webAppBackend.name};Password=${var.administratorLoginPassword}" - } +resource "azurerm_app_service_plan" "webAppFrontend" { + name = "${var.siteName}serviceplan" + resource_group_name = "${azurerm_resource_group.webAppMySqlRg.name}" + location = "${azurerm_resource_group.webAppMySqlRg.location}" + tags = "${azurerm_resource_group.webAppMySqlRg.tags}" + + sku { + tier = "${var.servicePlanTier}" + size = "${var.servicePlanSize}" + } +} + +resource "azurerm_app_service" "webAppFrontend" { + name = "${var.siteName}" + location = "${azurerm_resource_group.webAppMySqlRg.location}" + resource_group_name = "${azurerm_resource_group.webAppMySqlRg.name}" + tags = "${azurerm_resource_group.webAppMySqlRg.tags}" + + app_service_plan_id = "${azurerm_app_service_plan.webAppFrontend.id}" + connection_string { + name = "DefaultConnect" + type = "MySql" + value = "Database=${azurerm_mysql_database.webAppBackend.name};Data Source=${azurerm_mysql_server.webAppBackend.fqdn};User Id=${var.administratorLogin}@${azurerm_mysql_server.webAppBackend.name};Password=${var.administratorLoginPassword}" + } } \ No newline at end of file diff --git a/quickstart/201-web-app-windows-vnet/readme.md b/quickstart/201-web-app-windows-vnet/readme.md new file mode 100644 index 00000000..d9014e22 --- /dev/null +++ b/quickstart/201-web-app-windows-vnet/readme.md @@ -0,0 +1,36 @@ +# Windows Web App for a .NET Application in a VNET + + +This template deploys an [Azure App Service](https://www.terraform.io/docs/providers/azurerm/r/app_service.html) running Windows configured for a .NET Framework 4.6.2 application. This app service is attached to a private Virtual Network. + +## Variables + +| Name | Description | +|-|-| +| name | Name of the deployment | +| environment | The depolyment environment name (used for postfixing resource names) | +| prefix | A prefix for globally-unique dns-based resources | +| location | The Azure Region to deploy these resources in | +| plan_tier | The App Service Plan tier to deploy | +| plan_sku | The App Service Plan SKU to deploy| +| vnet_address_range | The address range of the Virtual Network to create | +| subnet_address_space | The address spcae of VNet to reserve for non App Service deployments | +| subnet_appsvc_space | The address space in the VNet to reserve for App Service deployments| + + +## Usage + +```bash +terraform plan \ + -var 'name=demo-dotnet' \ + -var 'environment=staging' \ + -var 'location=West US 2' + -var 'prefix=tfquickstard' \ + -var 'plan_tier=standard' \ + -var 'plan_sku=s1' \ + -out demo.tfplan + +terraform apply demo.tfplan +``` + +\* Example shown with [Bash](https://www.gnu.org/software/bash/). For [Powershell](https://docs.microsoft.com/en-us/powershell/) replace backslashes with backticks. \ No newline at end of file diff --git a/quickstart/301-aks-enterprise/readme.md b/quickstart/301-aks-enterprise/readme.md new file mode 100644 index 00000000..9c5ed663 --- /dev/null +++ b/quickstart/301-aks-enterprise/readme.md @@ -0,0 +1,40 @@ +# Enterprise Azure Kubernetes Service + +This template deploys an Azure Kubernetes Service cluster configured for common enterprise usage. The AKS Cluster is deployed inside a private network, with all ingress fronted by an Azure Application Gateway with a Web Application Firewall enabled. an Azure Container Reigstery instance is also deployed, and Managed Identity is leveraged to enable read access to the ACR instance from AKS. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group all resources are deployed into | +| `azurerm_app_service_plan` | The underlying plan that the web app will run on | +| `azurerm_app_service` | The Linux web app | + +## Variables + +| Name | Description | +|-|-| +| `name` | Name of the deployment | +| `environment` | The depolyment environment name (used for postfixing resource names) | +| `prefix` | A prefix for globally-unique dns-based resources | +| `location` | The Azure Region to deploy these resources in | +| `plan_tier` | The App Service Plan tier to deploy | +| `plan_sku` | The App Service Plan SKU to deploy| + + +## Usage + +```bash +terraform plan \ + -var 'name=demo-docker' \ + -var 'environment=staging' \ + -var 'location=West US 2' + -var 'prefix=tfquickstard' \ + -var 'plan_tier=standard' \ + -var 'plan_sku=s1' \ + -out demo.tfplan + +terraform apply demo.tfplan +``` + +\* Example shown with [Bash](https://www.gnu.org/software/bash/). For [Powershell](https://docs.microsoft.com/en-us/powershell/) replace backslashes with backticks. \ No newline at end of file diff --git a/quickstart/301-aks-windows-nodepool/readme.md b/quickstart/301-aks-windows-nodepool/readme.md new file mode 100644 index 00000000..64cda286 --- /dev/null +++ b/quickstart/301-aks-windows-nodepool/readme.md @@ -0,0 +1,31 @@ +# Azure Kubernetes Service with Windows + +Sometimes we need multiple node types with AKS. This template deploys an Azure Kubernetes Service cluster with a basic VM pool as well as a node pool of VMs that have GPUs attached. + +## Variables + +| Name | Description | +|-|-| +| name | Name of the deployment | +| environment | The depolyment environment name (used for postfixing resource names) | +| location | The Azure Region to deploy these resources in | +| vm_sku | The SKU of the VMs to deploy for AKS | +| vm_gpu_sku | The SKU of VMs to deploy for the AKS GPU Nodepool" +| prefix | A DNS Prefix to use in the AKS Cluster | + + +## Usage + +```bash +terraform plan \ + -var 'name=demo-dotnet' \ + -var 'environment=staging' \ + -var 'location=West US 2' + -var 'prefix=tfquickstard' \ + -var 'vm_sku=ds1v2' \ + -out demo.tfplan + +terraform apply demo.tfplan +``` + +\* Example shown with [Bash](https://www.gnu.org/software/bash/). For [Powershell](https://docs.microsoft.com/en-us/powershell/) replace backslashes with backticks. \ No newline at end of file diff --git a/quickstart/301-hub-spoke-network-3vm/readme.md b/quickstart/301-hub-spoke-network-3vm/readme.md new file mode 100644 index 00000000..1a7f32e6 --- /dev/null +++ b/quickstart/301-hub-spoke-network-3vm/readme.md @@ -0,0 +1,33 @@ +# Hub and Spoke networking with 3 VMs + + +This template deploys three Virtual Networks peered in a Hub and Spoke topology (one hub and two spokes). A Linux Virtual Machine is deploy to each network with SSH enabled so connectivity between each network can be verified after deployment. + +## Variables + +| Name | Description | +|-|-| +| name | Name of the deployment | +| environment | The depolyment environment name (used for postfixing resource names) | +| location | The Azure Region to deploy these resources in | +| vm_sku | The App Service Plan SKU to deploy| +| vnet_hub_name | The address range of the Virtual Network to create | +| vnet_spoke1_name | The address spcae of VNet to reserve for non App Service deployments | +| vnet_spoke2_name | The address space in the VNet to reserve for App Service deployments| + + +## Usage + +```bash +terraform plan \ + -var 'name=demo-dotnet' \ + -var 'environment=staging' \ + -var 'location=West US 2' + -var 'prefix=tfquickstard' \ + -var 'vm_sku=ds1v2' \ + -out demo.tfplan + +terraform apply demo.tfplan +``` + +\* Example shown with [Bash](https://www.gnu.org/software/bash/). For [Powershell](https://docs.microsoft.com/en-us/powershell/) replace backslashes with backticks. \ No newline at end of file diff --git a/quickstart/301-service-fabric-apim/apim.tf b/quickstart/301-service-fabric-apim/apim.tf new file mode 100644 index 00000000..15e9e426 --- /dev/null +++ b/quickstart/301-service-fabric-apim/apim.tf @@ -0,0 +1,58 @@ +resource "azurerm_api_management" "default" { + name = "${var.dns_prefix}-${var.name}-${var.environment}-apim" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + publisher_name = "${var.api_publisher_name}" + publisher_email = "${var.api_publisher_email}" + + sku { + name = "Developer" + capacity = 1 + } + + # Ignore certificate changes in the future + lifecycle { + ignore_changes = [ + "certificate" + ] + } + + # certificate { + # encoded_certificate = "${base64encode(tls_private_key.client.private_key_pem)}" + # certificate_password = "" + # store_name = "Root" + # } +} + +resource "azurerm_api_management_api" "default" { + name = "demo" + resource_group_name = "${azurerm_resource_group.default.name}" + api_management_name = "${azurerm_api_management.default.name}" + revision = "1" + display_name = "Demo API" + path = "" + protocols = ["https"] +} + +resource "azurerm_api_management_backend" "sf" { + name = "service-fabric-backend" + resource_group_name = "${azurerm_resource_group.default.name}" + api_management_name = "${azurerm_api_management.default.name}" + protocol = "http" + url = "fabric:/fake/service" + resource_id = "${azurerm_service_fabric_cluster.default.management_endpoint}" + + service_fabric_cluster { + client_certificate_thumbprint = "${azurerm_key_vault_certificate.client.thumbprint}" + server_certificate_thumbprints = ["${azurerm_key_vault_certificate.cluster.thumbprint}"] + management_endpoints = ["${azurerm_service_fabric_cluster.default.management_endpoint}"] + max_partition_resolution_retries = 3 + } +} + +resource "azurerm_application_insights" "default" { + name = "${var.name}-${var.environment}-ai" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.default.name}" + application_type = "web" +} \ No newline at end of file diff --git a/quickstart/301-service-fabric-apim/azuread.tf b/quickstart/301-service-fabric-apim/azuread.tf new file mode 100644 index 00000000..2b9b78b2 --- /dev/null +++ b/quickstart/301-service-fabric-apim/azuread.tf @@ -0,0 +1,72 @@ +# Service Fabric Cluster +resource "azuread_application" "cluster" { + name = "${var.name}-cluster-${var.environment}" +} + +resource "azuread_service_principal" "cluster" { + application_id = "${azuread_application.cluster.application_id}" +} + +resource "random_string" "cluster_password" { + length = 32 + special = true +} + +resource "azuread_service_principal_password" "cluster" { + service_principal_id = "${azuread_service_principal.cluster.id}" + value = "${random_string.cluster_password.result}" + end_date = "2099-01-01T01:00:00Z" +} + +# Service Fabric Client +resource "azuread_application" "client" { + name = "${var.name}-client-${var.environment}" + reply_urls = ["https://${azurerm_public_ip.sf.fqdn}:19080/Explorer/index.html"] + + app_role { + allowed_member_types = [ + "User", + ] + + description = "Admins can manage roles and perform all task actions" + display_name = "Admin" + is_enabled = true + value = "Admin" + } + + app_role { + allowed_member_types = [ + "User", + ] + + description = "ReadOnly roles have limited query access" + display_name = "ReadOnly" + is_enabled = true + value = "User" + } + + required_resource_access { + resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph API + + # DELEGATED PERMISSIONS: "Sign in and read user profile": + resource_access { + id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" + type = "Scope" + } + } +} + +resource "azuread_service_principal" "client" { + application_id = "${azuread_application.client.application_id}" +} + +resource "random_string" "client_password" { + length = 32 + special = true +} + +resource "azuread_service_principal_password" "client" { + service_principal_id = "${azuread_service_principal.client.id}" + value = "${random_string.client_password.result}" + end_date = "2099-01-01T01:00:00Z" +} diff --git a/quickstart/301-service-fabric-apim/keyvault.tf b/quickstart/301-service-fabric-apim/keyvault.tf new file mode 100644 index 00000000..36a78f31 --- /dev/null +++ b/quickstart/301-service-fabric-apim/keyvault.tf @@ -0,0 +1,168 @@ +resource "azurerm_key_vault" "cluster" { + name = "${var.dns_prefix}-${substr(var.name,0,12)}-${var.environment_short}-kv" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + enabled_for_deployment = true + enabled_for_disk_encryption = true + enabled_for_template_deployment = true + sku_name = "standard" + + access_policy { + tenant_id = "${data.azurerm_subscription.current.tenant_id}" + object_id = "${var.client_object_id}" + + certificate_permissions = [ + "create", + "delete", + "deleteissuers", + "get", + "getissuers", + "import", + "list", + "listissuers", + "managecontacts", + "manageissuers", + "setissuers", + "update", + ] + + key_permissions = [ + "backup", + "create", + "decrypt", + "delete", + "encrypt", + "get", + "import", + "list", + "purge", + "recover", + "restore", + "sign", + "unwrapKey", + "update", + "verify", + "wrapKey", + ] + + secret_permissions = [ + "backup", + "delete", + "get", + "list", + "purge", + "recover", + "restore", + "set", + ] + } +} + +resource "azurerm_key_vault_certificate" "cluster" { + name = "service-fabric-cluster" + key_vault_id = "${azurerm_key_vault.cluster.id}" + + certificate_policy { + issuer_parameters { + name = "Self" + } + + key_properties { + exportable = true + key_size = 2048 + key_type = "RSA" + reuse_key = true + } + + lifetime_action { + action { + action_type = "AutoRenew" + } + + trigger { + days_before_expiry = 30 + } + } + + secret_properties { + content_type = "application/x-pkcs12" + } + + x509_certificate_properties { + # Server Authentication = 1.3.6.1.5.5.7.3.1 + # Client Authentication = 1.3.6.1.5.5.7.3.2 + extended_key_usage = ["1.3.6.1.5.5.7.3.1"] + + key_usage = [ + "cRLSign", + "dataEncipherment", + "digitalSignature", + "keyAgreement", + "keyCertSign", + "keyEncipherment", + ] + + subject_alternative_names { + dns_names = ["sfdemosandbox.denvermtc.net"] + } + + subject = "CN=mtcdenver" + validity_in_months = 12 + } + } +} + +resource "azurerm_key_vault_certificate" "client" { + name = "service-fabric-client" + key_vault_id = "${azurerm_key_vault.cluster.id}" + + certificate_policy { + issuer_parameters { + name = "Self" + } + + key_properties { + exportable = true + key_size = 2048 + key_type = "RSA" + reuse_key = true + } + + lifetime_action { + action { + action_type = "AutoRenew" + } + + trigger { + days_before_expiry = 30 + } + } + + secret_properties { + content_type = "application/x-pkcs12" + } + + x509_certificate_properties { + # Server Authentication = 1.3.6.1.5.5.7.3.1 + # Client Authentication = 1.3.6.1.5.5.7.3.2 + extended_key_usage = ["1.3.6.1.5.5.7.3.1"] + + key_usage = [ + "cRLSign", + "dataEncipherment", + "digitalSignature", + "keyAgreement", + "keyCertSign", + "keyEncipherment", + ] + + subject_alternative_names { + dns_names = ["sfdemosandbox.denvermtc.net"] + } + + subject = "CN=mtcdenver" + validity_in_months = 12 + } + } +} diff --git a/quickstart/301-service-fabric-apim/main.tf b/quickstart/301-service-fabric-apim/main.tf new file mode 100644 index 00000000..66ff3720 --- /dev/null +++ b/quickstart/301-service-fabric-apim/main.tf @@ -0,0 +1,12 @@ +data "azurerm_subscription" "current" {} + +data "azurerm_client_config" "current" {} + +provider "azurerm" { + version = "=1.36.1" +} + +resource "azurerm_resource_group" "default" { + name = "${var.name}-${var.environment}-rg" + location = "${var.location}" +} diff --git a/quickstart/301-service-fabric-apim/network.tf b/quickstart/301-service-fabric-apim/network.tf new file mode 100644 index 00000000..93ea4350 --- /dev/null +++ b/quickstart/301-service-fabric-apim/network.tf @@ -0,0 +1,100 @@ +locals { + feip_config_name = "${var.name}-lb-fe-ipconfig" +} + +resource "azurerm_virtual_network" "default" { + name = "${var.name}-vnet" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" +} + +resource "azurerm_subnet" "default" { + name = "${var.name}-default-subnet" + resource_group_name = "${azurerm_resource_group.default.name}" + virtual_network_name = "${azurerm_virtual_network.default.name}" + address_prefix = "10.0.0.0/24" +} + +resource "azurerm_subnet" "sf" { + name = "${var.name}-sf-subnet" + resource_group_name = "${azurerm_resource_group.default.name}" + virtual_network_name = "${azurerm_virtual_network.default.name}" + address_prefix = "10.0.1.0/24" +} + +resource "azurerm_public_ip" "sf" { + name = "${var.name}-pip" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + allocation_method = "Dynamic" + domain_name_label = "${var.dns_prefix}-${var.name}-${var.environment_short}-sf" +} + +resource "azurerm_lb" "sf" { + name = "${var.name}-lb" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + + frontend_ip_configuration { + name = "${local.feip_config_name}" + public_ip_address_id = "${azurerm_public_ip.sf.id}" + } +} + +resource "azurerm_lb_nat_pool" "sf" { + name = "${var.name}-nat-pool" + resource_group_name = "${azurerm_resource_group.default.name}" + loadbalancer_id = "${azurerm_lb.sf.id}" + count = "1" + protocol = "Tcp" + frontend_port_start = 3389 + frontend_port_end = 4500 + backend_port = 3389 + frontend_ip_configuration_name = "${local.feip_config_name}" +} + +resource "azurerm_lb_backend_address_pool" "sf" { + resource_group_name = "${azurerm_resource_group.default.name}" + loadbalancer_id = "${azurerm_lb.sf.id}" + name = "ServiceFabricAddressPool" +} + +# Probes +resource "azurerm_lb_probe" "fabric_gateway" { + resource_group_name = "${azurerm_resource_group.default.name}" + loadbalancer_id = "${azurerm_lb.sf.id}" + name = "${var.name}-probe-19000" + port = 19000 +} + +resource "azurerm_lb_probe" "http" { + resource_group_name = "${azurerm_resource_group.default.name}" + loadbalancer_id = "${azurerm_lb.sf.id}" + name = "${var.name}-probe-19080" + port = 19080 +} + +resource "azurerm_lb_rule" "http" { + resource_group_name = "${azurerm_resource_group.default.name}" + loadbalancer_id = "${azurerm_lb.sf.id}" + backend_address_pool_id = "${azurerm_lb_backend_address_pool.sf.id}" + probe_id = "${azurerm_lb_probe.http.id}" + name = "http" + protocol = "Tcp" + frontend_port = 19080 + backend_port = 19080 + frontend_ip_configuration_name = "${local.feip_config_name}" +} + +resource "azurerm_lb_rule" "fabric_gateway" { + resource_group_name = "${azurerm_resource_group.default.name}" + loadbalancer_id = "${azurerm_lb.sf.id}" + backend_address_pool_id = "${azurerm_lb_backend_address_pool.sf.id}" + probe_id = "${azurerm_lb_probe.fabric_gateway.id}" + name = "fabric_gateway" + protocol = "Tcp" + frontend_port = 19000 + backend_port = 19000 + frontend_ip_configuration_name = "${local.feip_config_name}" +} diff --git a/quickstart/301-service-fabric-apim/readme.md b/quickstart/301-service-fabric-apim/readme.md new file mode 100644 index 00000000..023796ce --- /dev/null +++ b/quickstart/301-service-fabric-apim/readme.md @@ -0,0 +1,995 @@ +# Service Fabric with APIM. + +This template deploys a fully operational Service Fabric cluster running on Windows Virtual Machines in a private Virtual Network. Azure API Management is deployed as a front end gateway with internal Service Fabric services as the backend. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group all resources are deployed into | +| `azuread_application` | The Service Fabric cluster application | +| `azuread_service_principal` | A Service Principal for the Service Fabric Client | +| `azuread_service_principal` | A Service principal for the Service Fabric Cluster | +| `azurerm_key_vault` | | +| `azurerm_key_vault_certificate` | The Cluster Management Certificate | +| `azurerm_key_vault_certificate` | The Client App Certificate | +| `azurerm_lb` | A load balancer that sits in from of the VMs | +| `azurerm_public_ip` | A public IP for the cluster | +| `azurerm_service_fabric_cluster` | The Service Fabric cluster | +| `azurerm_storage_account` | A storage Account for the cluster | +| `azurerm_storage_account` | A Storage Account for the cluster VMs | +| `azurerm_virtual_network` | A Virtual Network for the cluster Nodes | +| `azurerm_subnet` | A Subnet for the cluster nodes | +| `azurerm_subnet` | A Default subnet for other endpoints that may talk with the cluster | `azurerm_subnet` | A subnet for APIM endpoints | +| `azurerm_virtual_machine_scale_set` | The actual cluster nodes | +| `random_string` | The client certificate password | +| `random_string` | The cluster certificate passwords | +| `azurerm_api_management` | The APIM instnace | +| `azurerm_application_insights` | Application Insights for APIM | + +## Variables + +| Name | Description | +|-|-| +| `name` | Name of the deployment | +| `environment` | The depolyment environment name (used for postfixing resource names) | +| `environment_short` | A 3 or 4 letter string to represent the environment | +| `dns_prefix` | A prefix for globally-unique dns-based resources | +| `cluster_size` | How many nodes to deploy | +| `admin_username` | The Administrator username for the nodes | +| `admin_password` | The Administrator password for the nodes | +| `client_object_id` | A pre-created Client for SF from AAD | +| `api_publisher_name` | The listed APIM publisher name | +| `api_publisher_email` | he listed APIM publisher email | + +## Notes + - On first run you will have to add yourself to the access policy for keyvault as terraform has no way to know what your client ID is to create the policy dynamically unless you're running as a service principal (which I don't have currently configured to look for). Just go to KeyVault, add an access policy for yourself, and run terraform apply again. + - NOTE: Vnet support in terraform for APIm does not yet exist - this script creates the network but you must manually join it to the vnet after + - Cert references between KeyVault and APIM are not automatic since the format is different. Download client cert from keyvault and do the following to add a password to the key so you can import from the APIM portal: + ``` + openssl pkcs12 -in mycert.pfx -out temp.pem + openssl pkcs12 -export -out mycert2.pfx -in temp.pem + +## Example + +```bash +> terraform plan +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + +data.azurerm_client_config.current: Refreshing state... +data.azurerm_subscription.current: Refreshing state... + +------------------------------------------------------------------------ + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azuread_application.client will be created + + resource "azuread_application" "client" { + + application_id = (known after apply) + + homepage = (known after apply) + + id = (known after apply) + + identifier_uris = (known after apply) + + name = "demo-tfquickstart-client-sandbox" + + object_id = (known after apply) + + public_client = (known after apply) + + reply_urls = (known after apply) + + type = "webapp/api" + + + app_role { + + allowed_member_types = [ + + "User", + ] + + description = "Admins can manage roles and perform all task actions" + + display_name = "Admin" + + id = (known after apply) + + is_enabled = true + + value = "Admin" + } + + app_role { + + allowed_member_types = [ + + "User", + ] + + description = "ReadOnly roles have limited query access" + + display_name = "ReadOnly" + + id = (known after apply) + + is_enabled = true + + value = "User" + } + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + + + required_resource_access { + + resource_app_id = "00000003-0000-0000-c000-000000000000" + + + resource_access { + + id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" + + type = "Scope" + } + } + } + + # azuread_application.cluster will be created + + resource "azuread_application" "cluster" { + + application_id = (known after apply) + + homepage = (known after apply) + + id = (known after apply) + + identifier_uris = (known after apply) + + name = "demo-tfquickstart-cluster-sandbox" + + object_id = (known after apply) + + public_client = (known after apply) + + reply_urls = (known after apply) + + type = "webapp/api" + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal.client will be created + + resource "azuread_service_principal" "client" { + + application_id = (known after apply) + + display_name = (known after apply) + + id = (known after apply) + + object_id = (known after apply) + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal.cluster will be created + + resource "azuread_service_principal" "cluster" { + + application_id = (known after apply) + + display_name = (known after apply) + + id = (known after apply) + + object_id = (known after apply) + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal_password.client will be created + + resource "azuread_service_principal_password" "client" { + + end_date = "2099-01-01T01:00:00Z" + + id = (known after apply) + + key_id = (known after apply) + + service_principal_id = (known after apply) + + start_date = (known after apply) + + value = (sensitive value) + } + + # azuread_service_principal_password.cluster will be created + + resource "azuread_service_principal_password" "cluster" { + + end_date = "2099-01-01T01:00:00Z" + + id = (known after apply) + + key_id = (known after apply) + + service_principal_id = (known after apply) + + start_date = (known after apply) + + value = (sensitive value) + } + + # azurerm_key_vault.cluster will be created + + resource "azurerm_key_vault" "cluster" { + + access_policy = [ + + { + + application_id = null + + certificate_permissions = [ + + "create", + + "delete", + + "deleteissuers", + + "get", + + "getissuers", + + "import", + + "list", + + "listissuers", + + "managecontacts", + + "manageissuers", + + "setissuers", + + "update", + ] + + key_permissions = [ + + "backup", + + "create", + + "decrypt", + + "delete", + + "encrypt", + + "get", + + "import", + + "list", + + "purge", + + "recover", + + "restore", + + "sign", + + "unwrapKey", + + "update", + + "verify", + + "wrapKey", + ] + + object_id = "0938d8bc-3351-4bcc-ddb5-113c2218ff0d" + + secret_permissions = [ + + "backup", + + "delete", + + "get", + + "list", + + "purge", + + "recover", + + "restore", + + "set", + ] + + storage_permissions = null + + tenant_id = "72f988bf-86f1-41af-91ab-2d7cd011db47" + }, + ] + + enabled_for_deployment = true + + enabled_for_disk_encryption = true + + enabled_for_template_deployment = true + + id = (known after apply) + + location = "westus2" + + name = "tfq-demo-tfquick-sbx-kv" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + sku_name = "standard" + + tags = (known after apply) + + tenant_id = "72f988bf-86f1-41af-91ab-2d7cd011db47" + + vault_uri = (known after apply) + + + sku { + + name = (known after apply) + } + } + + # azurerm_key_vault_certificate.client will be created + + resource "azurerm_key_vault_certificate" "client" { + + certificate_data = (known after apply) + + id = (known after apply) + + key_vault_id = (known after apply) + + name = "service-fabric-client" + + secret_id = (known after apply) + + tags = (known after apply) + + thumbprint = (known after apply) + + vault_uri = (known after apply) + + version = (known after apply) + + + certificate_policy { + + issuer_parameters { + + name = "Self" + } + + + key_properties { + + exportable = true + + key_size = 2048 + + key_type = "RSA" + + reuse_key = true + } + + + lifetime_action { + + action { + + action_type = "AutoRenew" + } + + + trigger { + + days_before_expiry = 30 + } + } + + + secret_properties { + + content_type = "application/x-pkcs12" + } + + + x509_certificate_properties { + + extended_key_usage = [ + + "1.3.6.1.5.5.7.3.1", + ] + + key_usage = [ + + "cRLSign", + + "dataEncipherment", + + "digitalSignature", + + "keyAgreement", + + "keyCertSign", + + "keyEncipherment", + ] + + subject = "CN=mtcdenver" + + validity_in_months = 12 + + + subject_alternative_names { + + dns_names = [ + + "sfdemosandbox.denvermtc.net", + ] + } + } + } + } + + # azurerm_key_vault_certificate.cluster will be created + + resource "azurerm_key_vault_certificate" "cluster" { + + certificate_data = (known after apply) + + id = (known after apply) + + key_vault_id = (known after apply) + + name = "service-fabric-cluster" + + secret_id = (known after apply) + + tags = (known after apply) + + thumbprint = (known after apply) + + vault_uri = (known after apply) + + version = (known after apply) + + + certificate_policy { + + issuer_parameters { + + name = "Self" + } + + + key_properties { + + exportable = true + + key_size = 2048 + + key_type = "RSA" + + reuse_key = true + } + + + lifetime_action { + + action { + + action_type = "AutoRenew" + } + + + trigger { + + days_before_expiry = 30 + } + } + + + secret_properties { + + content_type = "application/x-pkcs12" + } + + + x509_certificate_properties { + + extended_key_usage = [ + + "1.3.6.1.5.5.7.3.1", + ] + + key_usage = [ + + "cRLSign", + + "dataEncipherment", + + "digitalSignature", + + "keyAgreement", + + "keyCertSign", + + "keyEncipherment", + ] + + subject = "CN=mtcdenver" + + validity_in_months = 12 + + + subject_alternative_names { + + dns_names = [ + + "sfdemosandbox.denvermtc.net", + ] + } + } + } + } + + # azurerm_lb.sf will be created + + resource "azurerm_lb" "sf" { + + id = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-lb" + + private_ip_address = (known after apply) + + private_ip_addresses = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + sku = "Basic" + + tags = (known after apply) + + + frontend_ip_configuration { + + inbound_nat_rules = (known after apply) + + load_balancer_rules = (known after apply) + + name = "demo-tfquickstart-lb-fe-ipconfig" + + outbound_rules = (known after apply) + + private_ip_address = (known after apply) + + private_ip_address_allocation = (known after apply) + + public_ip_address_id = (known after apply) + + public_ip_prefix_id = (known after apply) + + subnet_id = (known after apply) + } + } + + # azurerm_lb_backend_address_pool.sf will be created + + resource "azurerm_lb_backend_address_pool" "sf" { + + backend_ip_configurations = (known after apply) + + id = (known after apply) + + load_balancing_rules = (known after apply) + + loadbalancer_id = (known after apply) + + name = "ServiceFabricAddressPool" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_lb_nat_pool.sf[0] will be created + + resource "azurerm_lb_nat_pool" "sf" { + + backend_port = 3389 + + frontend_ip_configuration_id = (known after apply) + + frontend_ip_configuration_name = "demo-tfquickstart-lb-fe-ipconfig" + + frontend_port_end = 4500 + + frontend_port_start = 3389 + + id = (known after apply) + + loadbalancer_id = (known after apply) + + name = "demo-tfquickstart-nat-pool" + + protocol = "tcp" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_lb_probe.fabric_gateway will be created + + resource "azurerm_lb_probe" "fabric_gateway" { + + id = (known after apply) + + interval_in_seconds = 15 + + load_balancer_rules = (known after apply) + + loadbalancer_id = (known after apply) + + name = "demo-tfquickstart-probe-19000" + + number_of_probes = 2 + + port = 19000 + + protocol = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_lb_probe.http will be created + + resource "azurerm_lb_probe" "http" { + + id = (known after apply) + + interval_in_seconds = 15 + + load_balancer_rules = (known after apply) + + loadbalancer_id = (known after apply) + + name = "demo-tfquickstart-probe-19080" + + number_of_probes = 2 + + port = 19080 + + protocol = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_lb_rule.fabric_gateway will be created + + resource "azurerm_lb_rule" "fabric_gateway" { + + backend_address_pool_id = (known after apply) + + backend_port = 19000 + + disable_outbound_snat = false + + enable_floating_ip = false + + frontend_ip_configuration_id = (known after apply) + + frontend_ip_configuration_name = "demo-tfquickstart-lb-fe-ipconfig" + + frontend_port = 19000 + + id = (known after apply) + + idle_timeout_in_minutes = (known after apply) + + load_distribution = (known after apply) + + loadbalancer_id = (known after apply) + + name = "fabric_gateway" + + probe_id = (known after apply) + + protocol = "tcp" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_lb_rule.http will be created + + resource "azurerm_lb_rule" "http" { + + backend_address_pool_id = (known after apply) + + backend_port = 19080 + + disable_outbound_snat = false + + enable_floating_ip = false + + frontend_ip_configuration_id = (known after apply) + + frontend_ip_configuration_name = "demo-tfquickstart-lb-fe-ipconfig" + + frontend_port = 19080 + + id = (known after apply) + + idle_timeout_in_minutes = (known after apply) + + load_distribution = (known after apply) + + loadbalancer_id = (known after apply) + + name = "http" + + probe_id = (known after apply) + + protocol = "tcp" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_public_ip.sf will be created + + resource "azurerm_public_ip" "sf" { + + allocation_method = "Dynamic" + + domain_name_label = "tfq-demo-tfquickstart-sbx-sf" + + fqdn = (known after apply) + + id = (known after apply) + + idle_timeout_in_minutes = 4 + + ip_address = (known after apply) + + ip_version = "IPv4" + + location = "westus2" + + name = "demo-tfquickstart-pip" + + public_ip_address_allocation = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + sku = "Basic" + + tags = (known after apply) + } + + # azurerm_resource_group.default will be created + + resource "azurerm_resource_group" "default" { + + id = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-sandbox-rg" + + tags = (known after apply) + } + + # azurerm_service_fabric_cluster.default will be created + + resource "azurerm_service_fabric_cluster" "default" { + + add_on_features = [ + + "DnsService", + ] + + cluster_code_version = (known after apply) + + cluster_endpoint = (known after apply) + + id = (known after apply) + + location = "westus2" + + management_endpoint = (known after apply) + + name = "demo-tfquickstart-sf" + + reliability_level = "Bronze" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + tags = (known after apply) + + upgrade_mode = "Automatic" + + vm_image = "Windows" + + + azure_active_directory { + + client_application_id = (known after apply) + + cluster_application_id = (known after apply) + + tenant_id = "72f988bf-86f1-41af-91ab-2d7cd011db47" + } + + + certificate { + + thumbprint = (known after apply) + + thumbprint_secondary = (known after apply) + + x509_store_name = "My" + } + + + client_certificate_thumbprint { + + is_admin = true + + thumbprint = (known after apply) + } + + + diagnostics_config { + + blob_endpoint = (known after apply) + + protected_account_key_name = "StorageAccountKey1" + + queue_endpoint = (known after apply) + + storage_account_name = "tfqdemotfquickstartsfsbx" + + table_endpoint = (known after apply) + } + + + fabric_settings { + + name = "Security" + + parameters = { + + "ClusterProtectionLevel" = "EncryptAndSign" + } + } + + fabric_settings { + + name = "ClusterManager" + + parameters = { + + "EnableDefaultServicesUpgrade" = "True" + } + } + + + node_type { + + client_endpoint_port = 19000 + + durability_level = "Bronze" + + http_endpoint_port = 19080 + + instance_count = 3 + + is_primary = true + + name = "default" + + + application_ports { + + end_port = 30000 + + start_port = 20000 + } + + + ephemeral_ports { + + end_port = 65534 + + start_port = 49152 + } + } + } + + # azurerm_storage_account.sf will be created + + resource "azurerm_storage_account" "sf" { + + access_tier = (known after apply) + + account_encryption_source = "Microsoft.Storage" + + account_kind = "Storage" + + account_replication_type = "LRS" + + account_tier = "Standard" + + account_type = (known after apply) + + enable_advanced_threat_protection = false + + enable_blob_encryption = true + + enable_file_encryption = true + + id = (known after apply) + + is_hns_enabled = false + + location = "westus2" + + name = "tfqdemotfquickstartsfsbx" + + primary_access_key = (sensitive value) + + primary_blob_connection_string = (sensitive value) + + primary_blob_endpoint = (known after apply) + + primary_blob_host = (known after apply) + + primary_connection_string = (sensitive value) + + primary_dfs_endpoint = (known after apply) + + primary_dfs_host = (known after apply) + + primary_file_endpoint = (known after apply) + + primary_file_host = (known after apply) + + primary_location = (known after apply) + + primary_queue_endpoint = (known after apply) + + primary_queue_host = (known after apply) + + primary_table_endpoint = (known after apply) + + primary_table_host = (known after apply) + + primary_web_endpoint = (known after apply) + + primary_web_host = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + secondary_access_key = (sensitive value) + + secondary_blob_connection_string = (sensitive value) + + secondary_blob_endpoint = (known after apply) + + secondary_blob_host = (known after apply) + + secondary_connection_string = (sensitive value) + + secondary_dfs_endpoint = (known after apply) + + secondary_dfs_host = (known after apply) + + secondary_file_endpoint = (known after apply) + + secondary_file_host = (known after apply) + + secondary_location = (known after apply) + + secondary_queue_endpoint = (known after apply) + + secondary_queue_host = (known after apply) + + secondary_table_endpoint = (known after apply) + + secondary_table_host = (known after apply) + + secondary_web_endpoint = (known after apply) + + secondary_web_host = (known after apply) + + tags = (known after apply) + + + identity { + + principal_id = (known after apply) + + tenant_id = (known after apply) + + type = (known after apply) + } + + + network_rules { + + bypass = (known after apply) + + default_action = (known after apply) + + ip_rules = (known after apply) + + virtual_network_subnet_ids = (known after apply) + } + + + queue_properties { + + cors_rule { + + allowed_headers = (known after apply) + + allowed_methods = (known after apply) + + allowed_origins = (known after apply) + + exposed_headers = (known after apply) + + max_age_in_seconds = (known after apply) + } + + + hour_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + + + logging { + + delete = (known after apply) + + read = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + + write = (known after apply) + } + + + minute_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + } + } + + # azurerm_storage_account.vmss will be created + + resource "azurerm_storage_account" "vmss" { + + access_tier = (known after apply) + + account_encryption_source = "Microsoft.Storage" + + account_kind = "Storage" + + account_replication_type = "LRS" + + account_tier = "Standard" + + account_type = (known after apply) + + enable_advanced_threat_protection = false + + enable_blob_encryption = true + + enable_file_encryption = true + + id = (known after apply) + + is_hns_enabled = false + + location = "westus2" + + name = "tfqdemotfquicksvmsssbx" + + primary_access_key = (sensitive value) + + primary_blob_connection_string = (sensitive value) + + primary_blob_endpoint = (known after apply) + + primary_blob_host = (known after apply) + + primary_connection_string = (sensitive value) + + primary_dfs_endpoint = (known after apply) + + primary_dfs_host = (known after apply) + + primary_file_endpoint = (known after apply) + + primary_file_host = (known after apply) + + primary_location = (known after apply) + + primary_queue_endpoint = (known after apply) + + primary_queue_host = (known after apply) + + primary_table_endpoint = (known after apply) + + primary_table_host = (known after apply) + + primary_web_endpoint = (known after apply) + + primary_web_host = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + secondary_access_key = (sensitive value) + + secondary_blob_connection_string = (sensitive value) + + secondary_blob_endpoint = (known after apply) + + secondary_blob_host = (known after apply) + + secondary_connection_string = (sensitive value) + + secondary_dfs_endpoint = (known after apply) + + secondary_dfs_host = (known after apply) + + secondary_file_endpoint = (known after apply) + + secondary_file_host = (known after apply) + + secondary_location = (known after apply) + + secondary_queue_endpoint = (known after apply) + + secondary_queue_host = (known after apply) + + secondary_table_endpoint = (known after apply) + + secondary_table_host = (known after apply) + + secondary_web_endpoint = (known after apply) + + secondary_web_host = (known after apply) + + tags = (known after apply) + + + identity { + + principal_id = (known after apply) + + tenant_id = (known after apply) + + type = (known after apply) + } + + + network_rules { + + bypass = (known after apply) + + default_action = (known after apply) + + ip_rules = (known after apply) + + virtual_network_subnet_ids = (known after apply) + } + + + queue_properties { + + cors_rule { + + allowed_headers = (known after apply) + + allowed_methods = (known after apply) + + allowed_origins = (known after apply) + + exposed_headers = (known after apply) + + max_age_in_seconds = (known after apply) + } + + + hour_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + + + logging { + + delete = (known after apply) + + read = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + + write = (known after apply) + } + + + minute_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + } + } + + # azurerm_subnet.apim will be created + + resource "azurerm_subnet" "apim" { + + address_prefix = "10.0.2.0/24" + + id = (known after apply) + + ip_configurations = (known after apply) + + name = "demo-tfquickstart-apim-subnet" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + virtual_network_name = "demo-tfquickstart-vnet" + } + + # azurerm_subnet.default will be created + + resource "azurerm_subnet" "default" { + + address_prefix = "10.0.0.0/24" + + id = (known after apply) + + ip_configurations = (known after apply) + + name = "demo-tfquickstart-default-subnet" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + virtual_network_name = "demo-tfquickstart-vnet" + } + + # azurerm_subnet.sf will be created + + resource "azurerm_subnet" "sf" { + + address_prefix = "10.0.1.0/24" + + id = (known after apply) + + ip_configurations = (known after apply) + + name = "demo-tfquickstart-sf-subnet" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + virtual_network_name = "demo-tfquickstart-vnet" + } + + # azurerm_virtual_machine_scale_set.default will be created + + resource "azurerm_virtual_machine_scale_set" "default" { + + automatic_os_upgrade = false + + id = (known after apply) + + license_type = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-vmss" + + overprovision = false + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + single_placement_group = true + + tags = (known after apply) + + upgrade_policy_mode = "Automatic" + + + boot_diagnostics { + + enabled = true + + storage_uri = (known after apply) + } + + + extension { + + name = "ServiceFabricNodeVmExt_vmDefault" + + protected_settings = (sensitive value) + + provision_after_extensions = [] + + publisher = "Microsoft.Azure.ServiceFabric" + + settings = (known after apply) + + type = "ServiceFabricNode" + + type_handler_version = "1.0" + } + + + identity { + + identity_ids = (known after apply) + + principal_id = (known after apply) + + type = (known after apply) + } + + + network_profile { + + ip_forwarding = false + + name = "NetworkProfile" + + primary = true + + + ip_configuration { + + application_gateway_backend_address_pool_ids = [] + + application_security_group_ids = [] + + load_balancer_backend_address_pool_ids = (known after apply) + + load_balancer_inbound_nat_rules_ids = (known after apply) + + name = "IPConfiguration" + + primary = true + + subnet_id = (known after apply) + } + } + + + os_profile { + + admin_password = (sensitive value) + + admin_username = "tfquickstart" + + computer_name_prefix = "sfvm" + } + + + os_profile_linux_config { + + disable_password_authentication = (known after apply) + + + ssh_keys { + + key_data = (known after apply) + + path = (known after apply) + } + } + + + os_profile_secrets { + + source_vault_id = (known after apply) + + + vault_certificates { + + certificate_store = "My" + + certificate_url = (known after apply) + } + } + + + os_profile_windows_config { + + enable_automatic_upgrades = true + + provision_vm_agent = true + } + + + sku { + + capacity = 3 + + name = "Standard_D1_v2" + + tier = "Standard" + } + + + storage_profile_data_disk { + + caching = "ReadWrite" + + create_option = "Empty" + + disk_size_gb = 10 + + lun = 0 + + managed_disk_type = (known after apply) + } + + + storage_profile_image_reference { + + offer = "WindowsServer" + + publisher = "MicrosoftWindowsServer" + + sku = "2019-Datacenter-with-Containers" + + version = "latest" + } + + + storage_profile_os_disk { + + caching = "ReadWrite" + + create_option = "FromImage" + + managed_disk_type = "Standard_LRS" + + vhd_containers = [] + } + } + + # azurerm_virtual_network.default will be created + + resource "azurerm_virtual_network" "default" { + + address_space = [ + + "10.0.0.0/16", + ] + + id = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-vnet" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + tags = (known after apply) + + + subnet { + + address_prefix = (known after apply) + + id = (known after apply) + + name = (known after apply) + + security_group = (known after apply) + } + } + + # random_string.client_password will be created + + resource "random_string" "client_password" { + + id = (known after apply) + + length = 32 + + lower = true + + min_lower = 0 + + min_numeric = 0 + + min_special = 0 + + min_upper = 0 + + number = true + + result = (known after apply) + + special = true + + upper = true + } + + # random_string.cluster_password will be created + + resource "random_string" "cluster_password" { + + id = (known after apply) + + length = 32 + + lower = true + + min_lower = 0 + + min_numeric = 0 + + min_special = 0 + + min_upper = 0 + + number = true + + result = (known after apply) + + special = true + + upper = true + } + +Plan: 28 to add, 0 to change, 0 to destroy. + +------------------------------------------------------------------------ +``` diff --git a/quickstart/301-service-fabric-apim/service_fabric.tf b/quickstart/301-service-fabric-apim/service_fabric.tf new file mode 100644 index 00000000..affb76b9 --- /dev/null +++ b/quickstart/301-service-fabric-apim/service_fabric.tf @@ -0,0 +1,78 @@ +resource "azurerm_storage_account" "sf" { + name = "${var.dns_prefix}${substr(replace(var.name, "-", ""), 0, 16)}sf${var.environment_short}" + resource_group_name = "${azurerm_resource_group.default.name}" + location = "${azurerm_resource_group.default.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_service_fabric_cluster" "default" { + name = "${var.name}-sf" + resource_group_name = "${azurerm_resource_group.default.name}" + location = "${azurerm_resource_group.default.location}" + reliability_level = "Bronze" + vm_image = "Windows" + management_endpoint = "https://${azurerm_public_ip.sf.fqdn}:19080" + upgrade_mode = "Automatic" + + add_on_features = ["DnsService"] + + node_type { + name = "default" + instance_count = 3 + is_primary = true + client_endpoint_port = 19000 + http_endpoint_port = 19080 + + application_ports { + start_port = 20000 + end_port = 30000 + } + + ephemeral_ports { + start_port = 49152 # possibly open client ports + end_port = 65534 + } + } + + azure_active_directory { + tenant_id = "${data.azurerm_subscription.current.tenant_id}" + cluster_application_id = "${azuread_application.client.application_id}" + client_application_id = "${azuread_application.cluster.application_id}" + } + + fabric_settings { + name = "Security" + + parameters = { + "ClusterProtectionLevel" = "EncryptAndSign" + } + } + + fabric_settings { + name = "ClusterManager" + + parameters = { + EnableDefaultServicesUpgrade = "True" + } + } + + certificate { + thumbprint = "${azurerm_key_vault_certificate.cluster.thumbprint}" + thumbprint_secondary = "${azurerm_key_vault_certificate.cluster.thumbprint}" + x509_store_name = "My" + } + + client_certificate_thumbprint { + thumbprint = "${azurerm_key_vault_certificate.client.thumbprint}" + is_admin = true + } + + diagnostics_config { + storage_account_name = "${azurerm_storage_account.sf.name}" + protected_account_key_name = "StorageAccountKey1" + blob_endpoint = "${azurerm_storage_account.sf.primary_blob_endpoint}" + queue_endpoint = "${azurerm_storage_account.sf.primary_queue_endpoint}" + table_endpoint = "${azurerm_storage_account.sf.primary_table_endpoint}" + } +} diff --git a/quickstart/301-service-fabric-apim/variables.tf b/quickstart/301-service-fabric-apim/variables.tf new file mode 100644 index 00000000..67f251a0 --- /dev/null +++ b/quickstart/301-service-fabric-apim/variables.tf @@ -0,0 +1,55 @@ +# ---------------------- +# General Settings +# ---------------------- +variable "name" { + default = "demo-tfquickstart" +} + +variable "location" { + default = "West US 2" +} + +variable "dns_prefix" { + default = "tfq" +} + +variable "environment" { + default = "sandbox" +} + +variable "environment_short" { + default = "sbx" +} + +# ---------------------- +# Service Fabric Cluster Settings +# ---------------------- +variable "cluster_size" { + default = 3 +} + +variable "admin_username" { + default = "tfquickstart" +} + +variable "admin_password" { + default = "password.1!" +} + +# Your object_id in Azure Active Directory. +# Has to be manually provided when deploying with azure-cli auth. +# Used in creating KeyVault Access Policies +variable "client_object_id" { + default = "0938d8bc-3351-4bcc-ddb5-113c2218ff0d" +} + +# ---------------------- +# API Management +# ---------------------- +variable "api_publisher_name" { + default = "Terraform Quickstarts" +} + +variable "api_publisher_email" { + default = "tfquickstart@example.com" +} \ No newline at end of file diff --git a/quickstart/301-service-fabric-apim/vmss.tf b/quickstart/301-service-fabric-apim/vmss.tf new file mode 100644 index 00000000..c20134fe --- /dev/null +++ b/quickstart/301-service-fabric-apim/vmss.tf @@ -0,0 +1,111 @@ +resource "azurerm_storage_account" "vmss" { + name = "${var.dns_prefix}${substr(replace(var.name, "-", ""), 0, 12)}vmss${var.environment_short}" + resource_group_name = "${azurerm_resource_group.default.name}" + location = "${azurerm_resource_group.default.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +# Vm Scale Set +resource "azurerm_virtual_machine_scale_set" "default" { + name = "${var.name}-vmss" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + upgrade_policy_mode = "Automatic" + overprovision = false + + sku { + name = "Standard_D1_v2" + tier = "Standard" + capacity = "${var.cluster_size}" + } + + storage_profile_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2019-Datacenter-with-Containers" + version = "latest" + } + + storage_profile_os_disk { + name = "" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + storage_profile_data_disk { + lun = 0 + caching = "ReadWrite" + create_option = "Empty" + disk_size_gb = 10 + } + + os_profile { + computer_name_prefix = "sfvm" + admin_username = "${var.admin_username}" + admin_password = "${var.admin_password}" + } + + os_profile_secrets { + source_vault_id = "${azurerm_key_vault.cluster.id}" + + vault_certificates { + certificate_url = "${azurerm_key_vault.cluster.vault_uri}secrets/${azurerm_key_vault_certificate.cluster.name}/${azurerm_key_vault_certificate.cluster.version}" + certificate_store = "My" + } + } + + # These default to on if not specified, causing terraform to always want to make changes + os_profile_windows_config { + enable_automatic_upgrades = true + provision_vm_agent = true + } + + boot_diagnostics { + enabled = true + storage_uri = "${azurerm_storage_account.vmss.primary_blob_endpoint}" + } + + network_profile { + name = "NetworkProfile" + primary = true + + ip_configuration { + primary = true + name = "IPConfiguration" + subnet_id = "${azurerm_subnet.sf.id}" + load_balancer_backend_address_pool_ids = ["${azurerm_lb_backend_address_pool.sf.id}"] + load_balancer_inbound_nat_rules_ids = ["${azurerm_lb_nat_pool.sf[0].id}"] + } + } + + extension { + name = "ServiceFabricNodeVmExt_vmDefault" # This extension connects vms to the cluster. + publisher = "Microsoft.Azure.ServiceFabric" + type = "ServiceFabricNode" + type_handler_version = "1.0" + + settings = < terraform plan +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + +data.azurerm_client_config.current: Refreshing state... +data.azurerm_subscription.current: Refreshing state... + +------------------------------------------------------------------------ + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azuread_application.client will be created + + resource "azuread_application" "client" { + + application_id = (known after apply) + + homepage = (known after apply) + + id = (known after apply) + + identifier_uris = (known after apply) + + name = "demo-tfquickstart-client-sandbox" + + object_id = (known after apply) + + public_client = (known after apply) + + reply_urls = (known after apply) + + type = "webapp/api" + + + app_role { + + allowed_member_types = [ + + "User", + ] + + description = "Admins can manage roles and perform all task actions" + + display_name = "Admin" + + id = (known after apply) + + is_enabled = true + + value = "Admin" + } + + app_role { + + allowed_member_types = [ + + "User", + ] + + description = "ReadOnly roles have limited query access" + + display_name = "ReadOnly" + + id = (known after apply) + + is_enabled = true + + value = "User" + } + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + + + required_resource_access { + + resource_app_id = "00000003-0000-0000-c000-000000000000" + + + resource_access { + + id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" + + type = "Scope" + } + } + } + + # azuread_application.cluster will be created + + resource "azuread_application" "cluster" { + + application_id = (known after apply) + + homepage = (known after apply) + + id = (known after apply) + + identifier_uris = (known after apply) + + name = "demo-tfquickstart-cluster-sandbox" + + object_id = (known after apply) + + public_client = (known after apply) + + reply_urls = (known after apply) + + type = "webapp/api" + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal.client will be created + + resource "azuread_service_principal" "client" { + + application_id = (known after apply) + + display_name = (known after apply) + + id = (known after apply) + + object_id = (known after apply) + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal.cluster will be created + + resource "azuread_service_principal" "cluster" { + + application_id = (known after apply) + + display_name = (known after apply) + + id = (known after apply) + + object_id = (known after apply) + + + oauth2_permissions { + + admin_consent_description = (known after apply) + + admin_consent_display_name = (known after apply) + + id = (known after apply) + + is_enabled = (known after apply) + + type = (known after apply) + + user_consent_description = (known after apply) + + user_consent_display_name = (known after apply) + + value = (known after apply) + } + } + + # azuread_service_principal_password.client will be created + + resource "azuread_service_principal_password" "client" { + + end_date = "2099-01-01T01:00:00Z" + + id = (known after apply) + + key_id = (known after apply) + + service_principal_id = (known after apply) + + start_date = (known after apply) + + value = (sensitive value) + } + + # azuread_service_principal_password.cluster will be created + + resource "azuread_service_principal_password" "cluster" { + + end_date = "2099-01-01T01:00:00Z" + + id = (known after apply) + + key_id = (known after apply) + + service_principal_id = (known after apply) + + start_date = (known after apply) + + value = (sensitive value) + } + + # azurerm_key_vault.cluster will be created + + resource "azurerm_key_vault" "cluster" { + + access_policy = [ + + { + + application_id = null + + certificate_permissions = [ + + "create", + + "delete", + + "deleteissuers", + + "get", + + "getissuers", + + "import", + + "list", + + "listissuers", + + "managecontacts", + + "manageissuers", + + "setissuers", + + "update", + ] + + key_permissions = [ + + "backup", + + "create", + + "decrypt", + + "delete", + + "encrypt", + + "get", + + "import", + + "list", + + "purge", + + "recover", + + "restore", + + "sign", + + "unwrapKey", + + "update", + + "verify", + + "wrapKey", + ] + + object_id = "0938d8bc-3351-4bcc-ddb5-113c2218ff0d" + + secret_permissions = [ + + "backup", + + "delete", + + "get", + + "list", + + "purge", + + "recover", + + "restore", + + "set", + ] + + storage_permissions = null + + tenant_id = "72f988bf-86f1-41af-91ab-2d7cd011db47" + }, + ] + + enabled_for_deployment = true + + enabled_for_disk_encryption = true + + enabled_for_template_deployment = true + + id = (known after apply) + + location = "westus2" + + name = "tfq-demo-tfquick-sbx-kv" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + sku_name = "standard" + + tags = (known after apply) + + tenant_id = "72f988bf-86f1-41af-91ab-2d7cd011db47" + + vault_uri = (known after apply) + + + sku { + + name = (known after apply) + } + } + + # azurerm_key_vault_certificate.client will be created + + resource "azurerm_key_vault_certificate" "client" { + + certificate_data = (known after apply) + + id = (known after apply) + + key_vault_id = (known after apply) + + name = "service-fabric-client" + + secret_id = (known after apply) + + tags = (known after apply) + + thumbprint = (known after apply) + + vault_uri = (known after apply) + + version = (known after apply) + + + certificate_policy { + + issuer_parameters { + + name = "Self" + } + + + key_properties { + + exportable = true + + key_size = 2048 + + key_type = "RSA" + + reuse_key = true + } + + + lifetime_action { + + action { + + action_type = "AutoRenew" + } + + + trigger { + + days_before_expiry = 30 + } + } + + + secret_properties { + + content_type = "application/x-pkcs12" + } + + + x509_certificate_properties { + + extended_key_usage = [ + + "1.3.6.1.5.5.7.3.1", + ] + + key_usage = [ + + "cRLSign", + + "dataEncipherment", + + "digitalSignature", + + "keyAgreement", + + "keyCertSign", + + "keyEncipherment", + ] + + subject = "CN=mtcdenver" + + validity_in_months = 12 + + + subject_alternative_names { + + dns_names = [ + + "sfdemosandbox.denvermtc.net", + ] + } + } + } + } + + # azurerm_key_vault_certificate.cluster will be created + + resource "azurerm_key_vault_certificate" "cluster" { + + certificate_data = (known after apply) + + id = (known after apply) + + key_vault_id = (known after apply) + + name = "service-fabric-cluster" + + secret_id = (known after apply) + + tags = (known after apply) + + thumbprint = (known after apply) + + vault_uri = (known after apply) + + version = (known after apply) + + + certificate_policy { + + issuer_parameters { + + name = "Self" + } + + + key_properties { + + exportable = true + + key_size = 2048 + + key_type = "RSA" + + reuse_key = true + } + + + lifetime_action { + + action { + + action_type = "AutoRenew" + } + + + trigger { + + days_before_expiry = 30 + } + } + + + secret_properties { + + content_type = "application/x-pkcs12" + } + + + x509_certificate_properties { + + extended_key_usage = [ + + "1.3.6.1.5.5.7.3.1", + ] + + key_usage = [ + + "cRLSign", + + "dataEncipherment", + + "digitalSignature", + + "keyAgreement", + + "keyCertSign", + + "keyEncipherment", + ] + + subject = "CN=mtcdenver" + + validity_in_months = 12 + + + subject_alternative_names { + + dns_names = [ + + "sfdemosandbox.denvermtc.net", + ] + } + } + } + } + + # azurerm_lb.sf will be created + + resource "azurerm_lb" "sf" { + + id = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-lb" + + private_ip_address = (known after apply) + + private_ip_addresses = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + sku = "Basic" + + tags = (known after apply) + + + frontend_ip_configuration { + + inbound_nat_rules = (known after apply) + + load_balancer_rules = (known after apply) + + name = "demo-tfquickstart-lb-fe-ipconfig" + + outbound_rules = (known after apply) + + private_ip_address = (known after apply) + + private_ip_address_allocation = (known after apply) + + public_ip_address_id = (known after apply) + + public_ip_prefix_id = (known after apply) + + subnet_id = (known after apply) + } + } + + # azurerm_lb_backend_address_pool.sf will be created + + resource "azurerm_lb_backend_address_pool" "sf" { + + backend_ip_configurations = (known after apply) + + id = (known after apply) + + load_balancing_rules = (known after apply) + + loadbalancer_id = (known after apply) + + name = "ServiceFabricAddressPool" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_lb_nat_pool.sf[0] will be created + + resource "azurerm_lb_nat_pool" "sf" { + + backend_port = 3389 + + frontend_ip_configuration_id = (known after apply) + + frontend_ip_configuration_name = "demo-tfquickstart-lb-fe-ipconfig" + + frontend_port_end = 4500 + + frontend_port_start = 3389 + + id = (known after apply) + + loadbalancer_id = (known after apply) + + name = "demo-tfquickstart-nat-pool" + + protocol = "tcp" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_lb_probe.fabric_gateway will be created + + resource "azurerm_lb_probe" "fabric_gateway" { + + id = (known after apply) + + interval_in_seconds = 15 + + load_balancer_rules = (known after apply) + + loadbalancer_id = (known after apply) + + name = "demo-tfquickstart-probe-19000" + + number_of_probes = 2 + + port = 19000 + + protocol = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_lb_probe.http will be created + + resource "azurerm_lb_probe" "http" { + + id = (known after apply) + + interval_in_seconds = 15 + + load_balancer_rules = (known after apply) + + loadbalancer_id = (known after apply) + + name = "demo-tfquickstart-probe-19080" + + number_of_probes = 2 + + port = 19080 + + protocol = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_lb_rule.fabric_gateway will be created + + resource "azurerm_lb_rule" "fabric_gateway" { + + backend_address_pool_id = (known after apply) + + backend_port = 19000 + + disable_outbound_snat = false + + enable_floating_ip = false + + frontend_ip_configuration_id = (known after apply) + + frontend_ip_configuration_name = "demo-tfquickstart-lb-fe-ipconfig" + + frontend_port = 19000 + + id = (known after apply) + + idle_timeout_in_minutes = (known after apply) + + load_distribution = (known after apply) + + loadbalancer_id = (known after apply) + + name = "fabric_gateway" + + probe_id = (known after apply) + + protocol = "tcp" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_lb_rule.http will be created + + resource "azurerm_lb_rule" "http" { + + backend_address_pool_id = (known after apply) + + backend_port = 19080 + + disable_outbound_snat = false + + enable_floating_ip = false + + frontend_ip_configuration_id = (known after apply) + + frontend_ip_configuration_name = "demo-tfquickstart-lb-fe-ipconfig" + + frontend_port = 19080 + + id = (known after apply) + + idle_timeout_in_minutes = (known after apply) + + load_distribution = (known after apply) + + loadbalancer_id = (known after apply) + + name = "http" + + probe_id = (known after apply) + + protocol = "tcp" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + } + + # azurerm_public_ip.sf will be created + + resource "azurerm_public_ip" "sf" { + + allocation_method = "Dynamic" + + domain_name_label = "tfq-demo-tfquickstart-sbx-sf" + + fqdn = (known after apply) + + id = (known after apply) + + idle_timeout_in_minutes = 4 + + ip_address = (known after apply) + + ip_version = "IPv4" + + location = "westus2" + + name = "demo-tfquickstart-pip" + + public_ip_address_allocation = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + sku = "Basic" + + tags = (known after apply) + } + + # azurerm_resource_group.default will be created + + resource "azurerm_resource_group" "default" { + + id = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-sandbox-rg" + + tags = (known after apply) + } + + # azurerm_service_fabric_cluster.default will be created + + resource "azurerm_service_fabric_cluster" "default" { + + add_on_features = [ + + "DnsService", + ] + + cluster_code_version = (known after apply) + + cluster_endpoint = (known after apply) + + id = (known after apply) + + location = "westus2" + + management_endpoint = (known after apply) + + name = "demo-tfquickstart-sf" + + reliability_level = "Bronze" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + tags = (known after apply) + + upgrade_mode = "Automatic" + + vm_image = "Windows" + + + azure_active_directory { + + client_application_id = (known after apply) + + cluster_application_id = (known after apply) + + tenant_id = "72f988bf-86f1-41af-91ab-2d7cd011db47" + } + + + certificate { + + thumbprint = (known after apply) + + thumbprint_secondary = (known after apply) + + x509_store_name = "My" + } + + + client_certificate_thumbprint { + + is_admin = true + + thumbprint = (known after apply) + } + + + diagnostics_config { + + blob_endpoint = (known after apply) + + protected_account_key_name = "StorageAccountKey1" + + queue_endpoint = (known after apply) + + storage_account_name = "tfqdemotfquickstartsfsbx" + + table_endpoint = (known after apply) + } + + + fabric_settings { + + name = "Security" + + parameters = { + + "ClusterProtectionLevel" = "EncryptAndSign" + } + } + + fabric_settings { + + name = "ClusterManager" + + parameters = { + + "EnableDefaultServicesUpgrade" = "True" + } + } + + + node_type { + + client_endpoint_port = 19000 + + durability_level = "Bronze" + + http_endpoint_port = 19080 + + instance_count = 3 + + is_primary = true + + name = "default" + + + application_ports { + + end_port = 30000 + + start_port = 20000 + } + + + ephemeral_ports { + + end_port = 65534 + + start_port = 49152 + } + } + } + + # azurerm_storage_account.sf will be created + + resource "azurerm_storage_account" "sf" { + + access_tier = (known after apply) + + account_encryption_source = "Microsoft.Storage" + + account_kind = "Storage" + + account_replication_type = "LRS" + + account_tier = "Standard" + + account_type = (known after apply) + + enable_advanced_threat_protection = false + + enable_blob_encryption = true + + enable_file_encryption = true + + id = (known after apply) + + is_hns_enabled = false + + location = "westus2" + + name = "tfqdemotfquickstartsfsbx" + + primary_access_key = (sensitive value) + + primary_blob_connection_string = (sensitive value) + + primary_blob_endpoint = (known after apply) + + primary_blob_host = (known after apply) + + primary_connection_string = (sensitive value) + + primary_dfs_endpoint = (known after apply) + + primary_dfs_host = (known after apply) + + primary_file_endpoint = (known after apply) + + primary_file_host = (known after apply) + + primary_location = (known after apply) + + primary_queue_endpoint = (known after apply) + + primary_queue_host = (known after apply) + + primary_table_endpoint = (known after apply) + + primary_table_host = (known after apply) + + primary_web_endpoint = (known after apply) + + primary_web_host = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + secondary_access_key = (sensitive value) + + secondary_blob_connection_string = (sensitive value) + + secondary_blob_endpoint = (known after apply) + + secondary_blob_host = (known after apply) + + secondary_connection_string = (sensitive value) + + secondary_dfs_endpoint = (known after apply) + + secondary_dfs_host = (known after apply) + + secondary_file_endpoint = (known after apply) + + secondary_file_host = (known after apply) + + secondary_location = (known after apply) + + secondary_queue_endpoint = (known after apply) + + secondary_queue_host = (known after apply) + + secondary_table_endpoint = (known after apply) + + secondary_table_host = (known after apply) + + secondary_web_endpoint = (known after apply) + + secondary_web_host = (known after apply) + + tags = (known after apply) + + + identity { + + principal_id = (known after apply) + + tenant_id = (known after apply) + + type = (known after apply) + } + + + network_rules { + + bypass = (known after apply) + + default_action = (known after apply) + + ip_rules = (known after apply) + + virtual_network_subnet_ids = (known after apply) + } + + + queue_properties { + + cors_rule { + + allowed_headers = (known after apply) + + allowed_methods = (known after apply) + + allowed_origins = (known after apply) + + exposed_headers = (known after apply) + + max_age_in_seconds = (known after apply) + } + + + hour_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + + + logging { + + delete = (known after apply) + + read = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + + write = (known after apply) + } + + + minute_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + } + } + + # azurerm_storage_account.vmss will be created + + resource "azurerm_storage_account" "vmss" { + + access_tier = (known after apply) + + account_encryption_source = "Microsoft.Storage" + + account_kind = "Storage" + + account_replication_type = "LRS" + + account_tier = "Standard" + + account_type = (known after apply) + + enable_advanced_threat_protection = false + + enable_blob_encryption = true + + enable_file_encryption = true + + id = (known after apply) + + is_hns_enabled = false + + location = "westus2" + + name = "tfqdemotfquicksvmsssbx" + + primary_access_key = (sensitive value) + + primary_blob_connection_string = (sensitive value) + + primary_blob_endpoint = (known after apply) + + primary_blob_host = (known after apply) + + primary_connection_string = (sensitive value) + + primary_dfs_endpoint = (known after apply) + + primary_dfs_host = (known after apply) + + primary_file_endpoint = (known after apply) + + primary_file_host = (known after apply) + + primary_location = (known after apply) + + primary_queue_endpoint = (known after apply) + + primary_queue_host = (known after apply) + + primary_table_endpoint = (known after apply) + + primary_table_host = (known after apply) + + primary_web_endpoint = (known after apply) + + primary_web_host = (known after apply) + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + secondary_access_key = (sensitive value) + + secondary_blob_connection_string = (sensitive value) + + secondary_blob_endpoint = (known after apply) + + secondary_blob_host = (known after apply) + + secondary_connection_string = (sensitive value) + + secondary_dfs_endpoint = (known after apply) + + secondary_dfs_host = (known after apply) + + secondary_file_endpoint = (known after apply) + + secondary_file_host = (known after apply) + + secondary_location = (known after apply) + + secondary_queue_endpoint = (known after apply) + + secondary_queue_host = (known after apply) + + secondary_table_endpoint = (known after apply) + + secondary_table_host = (known after apply) + + secondary_web_endpoint = (known after apply) + + secondary_web_host = (known after apply) + + tags = (known after apply) + + + identity { + + principal_id = (known after apply) + + tenant_id = (known after apply) + + type = (known after apply) + } + + + network_rules { + + bypass = (known after apply) + + default_action = (known after apply) + + ip_rules = (known after apply) + + virtual_network_subnet_ids = (known after apply) + } + + + queue_properties { + + cors_rule { + + allowed_headers = (known after apply) + + allowed_methods = (known after apply) + + allowed_origins = (known after apply) + + exposed_headers = (known after apply) + + max_age_in_seconds = (known after apply) + } + + + hour_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + + + logging { + + delete = (known after apply) + + read = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + + write = (known after apply) + } + + + minute_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + } + } + + # azurerm_subnet.apim will be created + + resource "azurerm_subnet" "apim" { + + address_prefix = "10.0.2.0/24" + + id = (known after apply) + + ip_configurations = (known after apply) + + name = "demo-tfquickstart-apim-subnet" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + virtual_network_name = "demo-tfquickstart-vnet" + } + + # azurerm_subnet.default will be created + + resource "azurerm_subnet" "default" { + + address_prefix = "10.0.0.0/24" + + id = (known after apply) + + ip_configurations = (known after apply) + + name = "demo-tfquickstart-default-subnet" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + virtual_network_name = "demo-tfquickstart-vnet" + } + + # azurerm_subnet.sf will be created + + resource "azurerm_subnet" "sf" { + + address_prefix = "10.0.1.0/24" + + id = (known after apply) + + ip_configurations = (known after apply) + + name = "demo-tfquickstart-sf-subnet" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + virtual_network_name = "demo-tfquickstart-vnet" + } + + # azurerm_virtual_machine_scale_set.default will be created + + resource "azurerm_virtual_machine_scale_set" "default" { + + automatic_os_upgrade = false + + id = (known after apply) + + license_type = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-vmss" + + overprovision = false + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + single_placement_group = true + + tags = (known after apply) + + upgrade_policy_mode = "Automatic" + + + boot_diagnostics { + + enabled = true + + storage_uri = (known after apply) + } + + + extension { + + name = "ServiceFabricNodeVmExt_vmDefault" + + protected_settings = (sensitive value) + + provision_after_extensions = [] + + publisher = "Microsoft.Azure.ServiceFabric" + + settings = (known after apply) + + type = "ServiceFabricNode" + + type_handler_version = "1.0" + } + + + identity { + + identity_ids = (known after apply) + + principal_id = (known after apply) + + type = (known after apply) + } + + + network_profile { + + ip_forwarding = false + + name = "NetworkProfile" + + primary = true + + + ip_configuration { + + application_gateway_backend_address_pool_ids = [] + + application_security_group_ids = [] + + load_balancer_backend_address_pool_ids = (known after apply) + + load_balancer_inbound_nat_rules_ids = (known after apply) + + name = "IPConfiguration" + + primary = true + + subnet_id = (known after apply) + } + } + + + os_profile { + + admin_password = (sensitive value) + + admin_username = "tfquickstart" + + computer_name_prefix = "sfvm" + } + + + os_profile_linux_config { + + disable_password_authentication = (known after apply) + + + ssh_keys { + + key_data = (known after apply) + + path = (known after apply) + } + } + + + os_profile_secrets { + + source_vault_id = (known after apply) + + + vault_certificates { + + certificate_store = "My" + + certificate_url = (known after apply) + } + } + + + os_profile_windows_config { + + enable_automatic_upgrades = true + + provision_vm_agent = true + } + + + sku { + + capacity = 3 + + name = "Standard_D1_v2" + + tier = "Standard" + } + + + storage_profile_data_disk { + + caching = "ReadWrite" + + create_option = "Empty" + + disk_size_gb = 10 + + lun = 0 + + managed_disk_type = (known after apply) + } + + + storage_profile_image_reference { + + offer = "WindowsServer" + + publisher = "MicrosoftWindowsServer" + + sku = "2019-Datacenter-with-Containers" + + version = "latest" + } + + + storage_profile_os_disk { + + caching = "ReadWrite" + + create_option = "FromImage" + + managed_disk_type = "Standard_LRS" + + vhd_containers = [] + } + } + + # azurerm_virtual_network.default will be created + + resource "azurerm_virtual_network" "default" { + + address_space = [ + + "10.0.0.0/16", + ] + + id = (known after apply) + + location = "westus2" + + name = "demo-tfquickstart-vnet" + + resource_group_name = "demo-tfquickstart-sandbox-rg" + + tags = (known after apply) + + + subnet { + + address_prefix = (known after apply) + + id = (known after apply) + + name = (known after apply) + + security_group = (known after apply) + } + } + + # random_string.client_password will be created + + resource "random_string" "client_password" { + + id = (known after apply) + + length = 32 + + lower = true + + min_lower = 0 + + min_numeric = 0 + + min_special = 0 + + min_upper = 0 + + number = true + + result = (known after apply) + + special = true + + upper = true + } + + # random_string.cluster_password will be created + + resource "random_string" "cluster_password" { + + id = (known after apply) + + length = 32 + + lower = true + + min_lower = 0 + + min_numeric = 0 + + min_special = 0 + + min_upper = 0 + + number = true + + result = (known after apply) + + special = true + + upper = true + } + +Plan: 28 to add, 0 to change, 0 to destroy. + +------------------------------------------------------------------------ +``` diff --git a/quickstart/301-service-fabric/service_fabric.tf b/quickstart/301-service-fabric/service_fabric.tf new file mode 100644 index 00000000..affb76b9 --- /dev/null +++ b/quickstart/301-service-fabric/service_fabric.tf @@ -0,0 +1,78 @@ +resource "azurerm_storage_account" "sf" { + name = "${var.dns_prefix}${substr(replace(var.name, "-", ""), 0, 16)}sf${var.environment_short}" + resource_group_name = "${azurerm_resource_group.default.name}" + location = "${azurerm_resource_group.default.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_service_fabric_cluster" "default" { + name = "${var.name}-sf" + resource_group_name = "${azurerm_resource_group.default.name}" + location = "${azurerm_resource_group.default.location}" + reliability_level = "Bronze" + vm_image = "Windows" + management_endpoint = "https://${azurerm_public_ip.sf.fqdn}:19080" + upgrade_mode = "Automatic" + + add_on_features = ["DnsService"] + + node_type { + name = "default" + instance_count = 3 + is_primary = true + client_endpoint_port = 19000 + http_endpoint_port = 19080 + + application_ports { + start_port = 20000 + end_port = 30000 + } + + ephemeral_ports { + start_port = 49152 # possibly open client ports + end_port = 65534 + } + } + + azure_active_directory { + tenant_id = "${data.azurerm_subscription.current.tenant_id}" + cluster_application_id = "${azuread_application.client.application_id}" + client_application_id = "${azuread_application.cluster.application_id}" + } + + fabric_settings { + name = "Security" + + parameters = { + "ClusterProtectionLevel" = "EncryptAndSign" + } + } + + fabric_settings { + name = "ClusterManager" + + parameters = { + EnableDefaultServicesUpgrade = "True" + } + } + + certificate { + thumbprint = "${azurerm_key_vault_certificate.cluster.thumbprint}" + thumbprint_secondary = "${azurerm_key_vault_certificate.cluster.thumbprint}" + x509_store_name = "My" + } + + client_certificate_thumbprint { + thumbprint = "${azurerm_key_vault_certificate.client.thumbprint}" + is_admin = true + } + + diagnostics_config { + storage_account_name = "${azurerm_storage_account.sf.name}" + protected_account_key_name = "StorageAccountKey1" + blob_endpoint = "${azurerm_storage_account.sf.primary_blob_endpoint}" + queue_endpoint = "${azurerm_storage_account.sf.primary_queue_endpoint}" + table_endpoint = "${azurerm_storage_account.sf.primary_table_endpoint}" + } +} diff --git a/quickstart/301-service-fabric/variables.tf b/quickstart/301-service-fabric/variables.tf new file mode 100644 index 00000000..50b4504a --- /dev/null +++ b/quickstart/301-service-fabric/variables.tf @@ -0,0 +1,44 @@ +# ---------------------- +# General Settings +# ---------------------- +variable "name" { + default = "demo-tfquickstart" +} + +variable "location" { + default = "West US 2" +} + +variable "dns_prefix" { + default = "tfq" +} + +variable "environment" { + default = "sandbox" +} + +variable "environment_short" { + default = "sbx" +} + +# ---------------------- +# Service Fabric Cluster Settings +# ---------------------- +variable "cluster_size" { + default = 3 +} + +variable "admin_username" { + default = "tfquickstart" +} + +variable "admin_password" { + default = "password.1!" +} + +# Your object_id in Azure Active Directory. +# Has to be manually provided when deploying with azure-cli auth. +# Used in creating KeyVault Access Policies +variable "client_object_id" { + default = "0938d8bc-3351-4bcc-ddb5-113c2218ff0d" +} diff --git a/quickstart/301-service-fabric/vmss.tf b/quickstart/301-service-fabric/vmss.tf new file mode 100644 index 00000000..c20134fe --- /dev/null +++ b/quickstart/301-service-fabric/vmss.tf @@ -0,0 +1,111 @@ +resource "azurerm_storage_account" "vmss" { + name = "${var.dns_prefix}${substr(replace(var.name, "-", ""), 0, 12)}vmss${var.environment_short}" + resource_group_name = "${azurerm_resource_group.default.name}" + location = "${azurerm_resource_group.default.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +# Vm Scale Set +resource "azurerm_virtual_machine_scale_set" "default" { + name = "${var.name}-vmss" + location = "${azurerm_resource_group.default.location}" + resource_group_name = "${azurerm_resource_group.default.name}" + upgrade_policy_mode = "Automatic" + overprovision = false + + sku { + name = "Standard_D1_v2" + tier = "Standard" + capacity = "${var.cluster_size}" + } + + storage_profile_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2019-Datacenter-with-Containers" + version = "latest" + } + + storage_profile_os_disk { + name = "" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + storage_profile_data_disk { + lun = 0 + caching = "ReadWrite" + create_option = "Empty" + disk_size_gb = 10 + } + + os_profile { + computer_name_prefix = "sfvm" + admin_username = "${var.admin_username}" + admin_password = "${var.admin_password}" + } + + os_profile_secrets { + source_vault_id = "${azurerm_key_vault.cluster.id}" + + vault_certificates { + certificate_url = "${azurerm_key_vault.cluster.vault_uri}secrets/${azurerm_key_vault_certificate.cluster.name}/${azurerm_key_vault_certificate.cluster.version}" + certificate_store = "My" + } + } + + # These default to on if not specified, causing terraform to always want to make changes + os_profile_windows_config { + enable_automatic_upgrades = true + provision_vm_agent = true + } + + boot_diagnostics { + enabled = true + storage_uri = "${azurerm_storage_account.vmss.primary_blob_endpoint}" + } + + network_profile { + name = "NetworkProfile" + primary = true + + ip_configuration { + primary = true + name = "IPConfiguration" + subnet_id = "${azurerm_subnet.sf.id}" + load_balancer_backend_address_pool_ids = ["${azurerm_lb_backend_address_pool.sf.id}"] + load_balancer_inbound_nat_rules_ids = ["${azurerm_lb_nat_pool.sf[0].id}"] + } + } + + extension { + name = "ServiceFabricNodeVmExt_vmDefault" # This extension connects vms to the cluster. + publisher = "Microsoft.Azure.ServiceFabric" + type = "ServiceFabricNode" + type_handler_version = "1.0" + + settings = <