Created
December 31, 2021 07:07
-
-
Save Satak/c747932d64d21c6be0547d5b1b2ff8bf to your computer and use it in GitHub Desktop.
Terraform unit test with Pester/Powershell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
BeforeDiscovery { | |
$testCases = Get-ChildItem -Path (Join-Path $PSScriptRoot examples) -Directory | |
} | |
describe 'terraform-module-storage - <_.Name>' -ForEach $testCases { | |
BeforeAll -ErrorAction Stop { | |
$exampleName = $_ | |
Push-Location $exampleName | |
Write-Host "Test case: $($ExampleName.Name)" -Foreground Magenta | |
Write-Host 'Initializing...' | |
terraform init | |
Write-Host 'Validating...' | |
terraform validate | |
Write-Host 'Planning...' | |
(terraform plan -out terraform.plan) | Write-Host | |
# Parse plan file and pull out provided variables | |
$plan = terraform show -json terraform.plan | ConvertFrom-Json | |
$vars = $plan.variables | |
Write-Host 'Plan variables: ' | |
Write-Host ($plan.variables | ConvertTo-Json) | |
} | |
AfterAll { | |
Pop-Location | |
} | |
context 'Unit' -Tag Unit { | |
BeforeAll { | |
$stgAddress = 'module.storage.azurerm_storage_account.storage' | |
$containerAddress = 'module.storage.azurerm_storage_container.my_stuff' | |
$atpAddress = 'module.storage.azurerm_advanced_threat_protection.atp' | |
$stgAccountPlan = ($plan.resource_changes | Where-Object {$_.address -eq $stgAddress})[0] | |
$container = ($plan.resource_changes | Where-Object {$_.address -eq $containerAddress})[0] | |
$atp = ($plan.resource_changes | Where-Object {$_.address -eq $atpAddress})[0] | |
} | |
it 'Will create storage account' { | |
$stgAccountPlan.change.actions[0] | Should -Be 'create' | |
} | |
it 'Will be in correct location' { | |
$stgAccountPlan.change.after.location | Should -Be $vars.location.value | |
} | |
it 'Will have correct account_tier' { | |
$stgAccountPlan.change.after.account_tier | Should -Be $vars.account_tier.value | |
} | |
it 'Will have correct replication_type' { | |
$stgAccountPlan.change.after.account_replication_type | Should -Be $vars.replication_type.value | |
} | |
it 'Will only allow HTTPS' { | |
$stgAccountPlan.change.after.enable_https_traffic_only | Should -Be $true | |
} | |
it 'Will prevent public blob containers' { | |
$stgAccountPlan.change.after.allow_blob_public_access | Should -Be $false | |
} | |
it 'Will have correct delete_retention_days' { | |
$retentionDays = $stgAccountPlan.change.after.blob_properties.delete_retention_policy.days | |
$retentionDays | Should -Be $vars.delete_retention_days.value | |
} | |
it 'Will create private storage container' { | |
$container.change.actions[0] | Should -Be 'create' | |
} | |
it 'Will enable ATP' { | |
$atp.change.actions[0] | Should -Be 'create' | |
} | |
} | |
context 'Integration' -Tag Integration { | |
BeforeAll { | |
Write-Host 'Applying infrastructure...' | |
(terraform apply --auto-approve terraform.plan) | Write-Host | |
# Get the provisioned resources from the state file | |
$state = terraform show -json terraform.tfstate | ConvertFrom-Json | |
# The prefix was generated by the random_id resource | |
# so we need to retrieve the value for that | |
$prefix = ($state.values.root_module.resources | | |
Where-Object {$_.address -eq 'random_id.prefix'} | |
)[0].values.hex | |
# Get the storage account from state | |
$childModuleResources = $state.values.root_module.child_modules.resources | |
$stgAccountState = ($childModuleResources | | |
Where-Object {$_.address -eq 'module.storage.azurerm_storage_account.storage'})[0] | |
$stgName = $stgAccountState.values.name | |
$stgRsg = $stgAccountState.values.resource_group_name | |
# Get the provisioned storage account from Azure | |
$stgAccount = Get-AzStorageAccount -Name $stgName -ResourceGroupName $stgRsg | |
$container = Get-AzStorageContainer -Context $stgAccount.Context -Name mystuff | |
} | |
AfterAll { | |
Write-Host 'Destroying infrastructure...' | |
Write-Host (terraform destroy --auto-approve *>&1) | |
} | |
it 'Created storage account' { | |
$stgAccount.StorageAccountName | Should -Be "$($prefix)storage" | |
} | |
it 'Public blob container is disallowed' { | |
{$stgAccount | New-AzStorageContainer -Name public1 -Permission Blob -ErrorAction Stop} | Should -Throw | |
{$stgAccount | New-AzStorageContainer -Name public2 -Permission Container -ErrorAction Stop} | Should -Throw | |
} | |
it 'Created private storage container' { | |
$container | Should -Not -BeNullOrEmpty | |
} | |
it 'Can upload to private container' { | |
# Premium storage SKUs must be page blobs aligned to 512 bytes boundarys | |
$blobType = $stgAccount.Sku.Tier -eq 'Premium' ? 'Page' : 'Block' | |
$tmpName = [IO.Path]::GetRandomFileName() | |
$tmpFilePath = Join-Path $TestDrive $tmpName | |
$tmpFile = [IO.FileStream]::new($tmpFilePath, 'Create', 'ReadWrite') | |
$tmpFile.SetLength(1MB) | |
$tmpFile.Close() | |
$uploadParam = @{ | |
Container = $container.Name | |
File = $tmpFile.Name | |
Blob = $random.Name | |
Context = $stgAccount.Context | |
BlobType = $blobType | |
Force = $true | |
} | |
{Set-AzStorageBlobContent @uploadParam } | Should -Not -Throw | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment