Skip to content

Commit 48f178e

Browse files
feature: implement terraform (#70)
# Pull Request ## Issue N/A ## Description The PR is to add Terraform functionality to the accelerator module without making any breaking changes to Bicep. The Terraform accelerator module is being built out in a separate repository. ## License By submitting this pull request, I confirm that my contribution is made under the terms of the projects associated license. --------- Co-authored-by: Zach Trocinski <ztrocinski@outlook.com>
1 parent c30eaa0 commit 48f178e

18 files changed

Lines changed: 541 additions & 77 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ ehthumbs.db
1313
Thumbs.db
1414
src/ALZ/Assets/alz-bicep-internal/
1515
test_output/
16+
hcl2json_windows_amd64.exe

README.md

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ Update-Module -Name ALZ
4848

4949
### Quick start
5050

51-
Before you start you can utilize the functionality of the module to verify if you have all the prerequisites installed with the built in command:
51+
Before you start you can utilize the functionality of the module to verify if you have all the prerequisites installed with the built in command.
52+
53+
#### Bicep
5254

5355
```powershell
54-
Test-ALZRequirement
56+
Test-ALZRequirement -IaC "bicep"
5557
```
5658

5759
Currently this tests for:
@@ -63,26 +65,52 @@ Currently this tests for:
6365
* Bicep
6466
* Visual Studio Code
6567

66-
#### Create a new Azure Landing Zone Environment with GitHub Actions Workflows
68+
#### Terraform
6769

6870
```powershell
69-
New-ALZEnvironment -o <output_directory>
71+
Test-ALZRequirement -IaC "terraform"
7072
```
7173

72-
#### Azure Landing Zone Environment with Azure DevOps Pipelines
74+
This currently tests for:
75+
76+
* Supported minimum PowerShell version (7.1)
77+
* Git
78+
* Azure CLI
79+
* Terraform CLI
80+
81+
#### Azure Landing Zone Environment with Bicep and GitHub Actions Workflows
82+
7383
```powershell
74-
New-ALZEnvironment -o <output_directory> -cicd "azuredevops"
84+
New-ALZEnvironment -o <output_directory> -IaC "bicep" -cicd "github
7585
```
86+
87+
#### Azure Landing Zone Environment with Bicep and Azure DevOps Pipelines
88+
89+
```powershell
90+
New-ALZEnvironment -o <output_directory> -IaC "bicep" -cicd "azuredevops"
91+
```
92+
7693
> **Note**
7794
> Azure Devops Pipelines are only supported in v0.2.6 or later.
7895
79-
## Additonal Cmdlets
96+
#### Azure Landing Zone Environment with Terraform and GitHub Pipelines
97+
98+
```powershell
99+
New-ALZEnvironment -o <output_directory> -IaC "terraform" -cicd "github"
100+
```
101+
102+
#### Azure Landing Zone Environment with Terraform and Azure DevOps Pipelines
103+
104+
```powershell
105+
New-ALZEnvironment -o <output_directory> -IaC "terraform" -cicd "azuredevops"
106+
```
107+
108+
## Additional Cmdlets
80109

81110
### Update an existing Azure Landing Zone Environment
82111

83112
#### Downloads and pulls down the specified release version from the remote GitHub repository to a local directory
84113

85-
86114
```powershell
87115
Get-ALZGithubRelease -githubRepoUrl "https://github.com/Azure/ALZ-Bicep" -releases "v0.14.0" -directoryForReleases "C:\Repos\ALZ\accelerator\upstream-releases\"
88116
```
@@ -93,7 +121,24 @@ Get-ALZGithubRelease -githubRepoUrl "https://github.com/Azure/ALZ-Bicep" -releas
93121

94122
In order to develop this module you will need PowerShell 7.1 or later.
95123

96-
### Commands to install a build locally
124+
### Pre-requisites
125+
126+
```powershell
127+
# Required to run Invoke-Build
128+
Install-Module -F PSScriptAnalyzer
129+
Install-Module -F InvokeBuild
130+
Install-Module -F Pester
131+
```
132+
133+
### Commands to build locally
134+
135+
```powershell
136+
# Build and test locally
137+
Remove-Module "ALZ" -Force
138+
Invoke-Build -File .\src\ALZ.build.ps1
139+
```
140+
141+
### Commands to import a build locally
97142

98143
```powershell
99144
# Install the module locally

docs/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.2.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.2.4]
9+
10+
- Add support for Terraform
11+
812
## [0.2.3]
913

1014
- fix min prefix length from 3 to 2

src/ALZ.build.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ Add-BuildTask ImportModuleManifest {
142142
try {
143143
Import-Module $script:ModuleManifestFile -Force -PassThru -ErrorAction Stop
144144
} catch {
145-
throw 'Unable to load the project module'
145+
Write-Build Red $_
146+
throw "Unable to load the project module"
146147
}
147148
Write-Build Green " ...$script:ModuleName imported successfully"
148149
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
function Convert-HCLVariablesToUserInputConfig {
2+
[CmdletBinding(SupportsShouldProcess = $true)]
3+
param (
4+
[Parameter(Mandatory = $false)]
5+
[string] $targetVariableFile,
6+
7+
[Parameter(Mandatory = $false)]
8+
[string] $hclParserToolPath,
9+
10+
[Parameter(Mandatory = $false)]
11+
[PSCustomObject]$validators,
12+
13+
[Parameter(Mandatory = $false)]
14+
[PSCustomObject]$appendToObject = $null
15+
)
16+
17+
if ($PSCmdlet.ShouldProcess("Parse HCL Variables into Config", "modify")) {
18+
$terraformVariables = & $hclParserToolPath $targetVariableFile | ConvertFrom-Json
19+
20+
$starterModuleConfiguration = [PSCustomObject]@{}
21+
if($appendToObject -ne $null) {
22+
$starterModuleConfiguration = $appendToObject
23+
}
24+
25+
foreach($variable in $terraformVariables.variable.PSObject.Properties) {
26+
$description = $variable.Value[0].description
27+
$validationTypeSplit = $description -split "\|"
28+
29+
$hasValidation = $false
30+
$order = 0
31+
32+
if($validationTypeSplit.Length -gt 1) {
33+
$description = $validationTypeSplit[0].Trim()
34+
}
35+
36+
if($validationTypeSplit.Length -eq 2) {
37+
$splitItem = $validationTypeSplit[1].Trim()
38+
if($splitItem -match "^\d+$") {
39+
$order = [convert]::ToInt32($splitItem)
40+
} else {
41+
$validationType = $splitItem
42+
$hasValidation = $true
43+
}
44+
}
45+
46+
if($validationTypeSplit.Length -eq 3) {
47+
$order = [convert]::ToInt32($validationTypeSplit[1].Trim())
48+
$validationType = $validationTypeSplit[2].Trim()
49+
$hasValidation = $true
50+
}
51+
52+
if($hasValidation -and $validationType -eq "hidden") {
53+
continue
54+
}
55+
56+
$inputType = "UserInput"
57+
if($hasValidation -and $validationType -eq "hidden_azure_subscription_ids") {
58+
$inputType = "AzureSubscriptionIds"
59+
}
60+
61+
$dataType = $variable.Value[0].type
62+
$dataType = $dataType.Replace("`${", "").Replace("}", "")
63+
64+
$starterModuleConfigurationInstance = [PSCustomObject]@{}
65+
$starterModuleConfigurationInstance | Add-Member -NotePropertyName "Order" -NotePropertyValue $order
66+
$starterModuleConfigurationInstance | Add-Member -NotePropertyName "Type" -NotePropertyValue $inputType
67+
$starterModuleConfigurationInstance | Add-Member -NotePropertyName "Value" -NotePropertyValue ""
68+
$starterModuleConfigurationInstance | Add-Member -NotePropertyName "DataType" -NotePropertyValue $dataType
69+
70+
if($variable.Value[0].PSObject.Properties.Name -contains "default") {
71+
$defaultValue = $variable.Value[0].default
72+
73+
if($variable.Value[0].default.GetType().Name -eq "Boolean") {
74+
$defaultValue = $variable.Value[0].default.ToString().ToLower()
75+
}
76+
if($dataType -eq "list(string)") {
77+
$defaultValueRaw = $variable.Value[0].default
78+
$defaultValue = ""
79+
if($defaultValue.Length -gt 0) {
80+
$join = $defaultValueRaw -join "`",`""
81+
$defaultValue = "`"$join`""
82+
}
83+
}
84+
$starterModuleConfigurationInstance | Add-Member -NotePropertyName "DefaultValue" -NotePropertyValue $defaultValue
85+
}
86+
87+
if($hasValidation) {
88+
$validator = $validators.PSObject.Properties[$validationType].Value
89+
$description = "$description ($($validator.Description))"
90+
if($validator.Type -eq "AllowedValues"){
91+
$starterModuleConfigurationInstance | Add-Member -NotePropertyName "AllowedValues" -NotePropertyValue $validator.AllowedValues
92+
}
93+
if($validator.Type -eq "Valid"){
94+
$starterModuleConfigurationInstance | Add-Member -NotePropertyName "Valid" -NotePropertyValue $validator.Valid
95+
}
96+
$starterModuleConfigurationInstance | Add-Member -NotePropertyName "Validator" -NotePropertyValue $validationType
97+
}
98+
99+
$starterModuleConfigurationInstance | Add-Member -NotePropertyName "Description" -NotePropertyValue $description
100+
101+
$starterModuleConfiguration | Add-Member -NotePropertyName $variable.Name -NotePropertyValue $starterModuleConfigurationInstance
102+
}
103+
}
104+
105+
return $starterModuleConfiguration
106+
}

src/ALZ/Private/Get-ALZBicepConfig.ps1

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/ALZ/Private/Get-ALZConfig.ps1

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
function Get-ALZConfig {
2+
<#
3+
4+
#>
5+
param(
6+
[Parameter(Mandatory = $false)]
7+
[string] $alzVersion = "v0.16.3",
8+
[Parameter(Mandatory = $false)]
9+
[ValidateSet("bicep", "terraform")]
10+
[Alias("Iac")]
11+
[string] $alzIacProvider = "bicep",
12+
[Parameter(Mandatory = $false)]
13+
[string] $configFilePath = ""
14+
)
15+
16+
# Import the config from the json file inside assets and transform it to a PowerShell object
17+
if ($configFilePath -ne "") {
18+
$config = Get-Content -Path $configFilePath | ConvertFrom-Json
19+
return $config
20+
}
21+
22+
else {
23+
$config = Get-Content -Path (Join-Path $(Get-ScriptRoot) "../Assets/alz-$alzIacProvider-config" "$alzVersion.config.json" ) | ConvertFrom-Json
24+
return $config
25+
}
26+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
function Get-HCLParserTool {
2+
[CmdletBinding(SupportsShouldProcess = $true)]
3+
param (
4+
[Parameter(Mandatory = $false)]
5+
[string] $alzEnvironmentDestination,
6+
7+
[Parameter(Mandatory = $false)]
8+
[string] $toolVersion
9+
)
10+
11+
if ($PSCmdlet.ShouldProcess("Download Terraform Tools", "modify")) {
12+
$os = ""
13+
if ($IsWindows) {
14+
$os = "windows"
15+
}
16+
if($IsLinux) {
17+
$os = "linux"
18+
}
19+
if($IsMacOS) {
20+
$os = "darwin"
21+
}
22+
23+
$architecture = $($env:PROCESSOR_ARCHITECTURE).ToLower()
24+
$toolFileName = "hcl2json_$($os)_$($architecture)"
25+
26+
if($os -eq "windows") {
27+
$toolFileName = "$($toolFileName).exe"
28+
}
29+
30+
$toolFilePath = Join-Path -Path $alzEnvironmentDestination -ChildPath $toolFileName
31+
32+
if(!(Test-Path $toolFilePath)) {
33+
Invoke-WebRequest -Uri "https://github.com/tmccombs/hcl2json/releases/download/$($toolVersion)/$($toolFileName)" -OutFile "$toolFilePath" | Out-String | Write-Verbose
34+
}
35+
}
36+
37+
return $toolFilePath
38+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
function Import-SubscriptionData {
2+
<#
3+
4+
#>
5+
param(
6+
[Parameter(Mandatory = $false)]
7+
[PSCustomObject] $starterModuleConfiguration,
8+
[Parameter(Mandatory = $false)]
9+
[PSCustomObject] $bootstrapConfiguration
10+
)
11+
12+
$subscriptions = $starterModuleConfiguration.PsObject.Properties | Where-Object { $_.Value.Validator -eq "azure_subscription_id" }
13+
$subscriptionIds = @()
14+
foreach($subscription in $subscriptions) {
15+
$subscriptionIds += $subscription.Value.Value
16+
}
17+
18+
$subscriptionIdsJoined = $subscriptionIds -join ","
19+
$subscriptionsObject = $bootstrapConfiguration.PsObject.Properties | Where-Object { $_.Value.Validator -eq "hidden_azure_subscription_ids" }
20+
$subscriptionsObject.Value.Value = $subscriptionIdsJoined
21+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function Invoke-Terraform {
2+
[CmdletBinding(SupportsShouldProcess = $true)]
3+
param (
4+
[Parameter(Mandatory = $false)]
5+
[string] $moduleFolderPath,
6+
7+
[Parameter(Mandatory = $false)]
8+
[string] $tfvarsFileName
9+
)
10+
11+
if ($PSCmdlet.ShouldProcess("Apply Terraform", "modify")) {
12+
terraform -chdir="$moduleFolderPath" init
13+
terraform -chdir="$moduleFolderPath" apply -var-file="$tfvarsFileName"
14+
}
15+
}

0 commit comments

Comments
 (0)