Skip to content

Commit

Permalink
AccTests with TerraTest
Browse files Browse the repository at this point in the history
  • Loading branch information
Aris van Ommeren committed May 25, 2021
1 parent 8f82413 commit cf29e48
Show file tree
Hide file tree
Showing 10 changed files with 842 additions and 124 deletions.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ go install github.com/aristosvo/aztfmove

## Authentication

Authentication is based on an default [azure-sdk-for-go](https://github.com/Azure/azure-sdk-for-go) authorizer which uses Azure CLI to obtain its credentials.
Authentication for Terraform is the same for `aztfmove` as for normal `terraform` operations. Start with `terraform init` to make sure the (remote) terraform state is available.

Authentication for the movements in Azure is based on an default [azure-sdk-for-go](https://github.com/Azure/azure-sdk-for-go) authorizer which uses Azure CLI to obtain its credentials.

To use this way of authentication, follow these steps:

Expand All @@ -63,7 +65,6 @@ To verify the current account settings, use:
az account list
```


## Examples
For examples and/or tests, see [test](https://github.com/aristosvo/aztfmove/tree/main/test) directory.

Expand Down Expand Up @@ -107,12 +108,12 @@ Congratulations! Resources are moved in Azure and corrected in Terraform.
## ToDo
- [x] Rework the code in multiple packages instead of one file
- [x] Introduce a verification step
- [x] Introduce a dry-run option
- [x] Colored output
- [x] Introduce a dry-run option, which returns the commands to execute the operations yourself
- [x] Colored output as default, `-no-color` flag is available to remove the formatting
- [x] Documentation around authentication
- [x] Support environments which require variables or variable files on import
- [x] Unit tests
- [ ] Use [terratest](https://terratest.gruntwork.io) or similar for AccTests
- [x] Use [terratest](https://terratest.gruntwork.io) for AccTests against Azure
- [ ] Multiple authentication options (ideally all options supported in the provider)
- [ ] ~~Add an `-exclude` flag (trying to mimic flags of terraform, doesn't fit in that pattern)~~

Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ require (
github.com/Azure/go-autorest/autorest/azure/auth v0.5.7
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
github.com/arschles/assert v2.0.0+incompatible
github.com/glendc/go-external-ip v0.0.0-20200601212049-c872357d968e
github.com/gruntwork-io/terratest v0.34.8
)
610 changes: 608 additions & 2 deletions go.sum

Large diffs are not rendered by default.

90 changes: 90 additions & 0 deletions test/basic-keyvault/basic_keyvault_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// +build acctest
// NOTE: We use build tags to differentiate acceptance testing

package test

import (
"fmt"
"log"
"os/exec"
"testing"

"github.com/arschles/assert"
"github.com/gruntwork-io/terratest/modules/terraform"

externalip "github.com/glendc/go-external-ip"
)

func TestAztfmoveKeyVault(t *testing.T) {
t.Parallel()

terraformOptions := &terraform.Options{
TerraformDir: "./",
Vars: map[string]interface{}{
"test": 123,
"ip": ipCIDR(),
},
VarFiles: []string{"create.tfvars"},
}
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)

// Test dry-run
cmdDryRun := exec.Command("aztfmove", "-resource-group=input-kv-rg", "-target-resource-group=output-kv-rg", "-auto-approve", "-dry-run")
outDryRun, err := cmdDryRun.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outDryRun)
}
t.Log("Dry-run succeeded")

// Test move
cmdMove := exec.Command("aztfmove", "-resource-group=input-kv-rg", "-target-resource-group=output-kv-rg", "-var-file=moved.tfvars", "-var", fmt.Sprintf("ip=%s", ipCIDR()), "-var", "test=123", "-auto-approve")
outMove, err := cmdMove.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outMove)
}
t.Log("First move succeeded")

// Validate move
terraformOptionsBack := &terraform.Options{
TerraformDir: "./",
Vars: map[string]interface{}{
"test": 123,
"ip": ipCIDR(),
},
VarFiles: []string{"moved.tfvars"},
}
exitCode := terraform.InitAndPlanWithExitCode(t, terraformOptionsBack)
assert.Equal(t, exitCode, 0, "Exitcode must be 0")
t.Log("First move validated")

// Test dry-run
cmdDryRunBack := exec.Command("aztfmove", "-resource-group=output-kv-rg", "-target-resource-group=input-kv-rg", "-auto-approve", "-dry-run")
outDryRunBack, err := cmdDryRunBack.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outDryRunBack)
}
t.Log("Dry-run 2 succeeded")

// Test move
cmdMoveBack := exec.Command("aztfmove", "-resource-group=output-kv-rg", "-target-resource-group=input-kv-rg", "-var-file=create.tfvars", "-var", fmt.Sprintf("ip=%s", ipCIDR()), "-var", "test=123", "-auto-approve")
outMoveBack, err := cmdMoveBack.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outMoveBack)
}
t.Log("Second move succeeded")

// Validate move
exitCode = terraform.InitAndPlanWithExitCode(t, terraformOptions)
assert.Equal(t, exitCode, 0, "Exitcode must be 0")
}

func ipCIDR() string {
consensus := externalip.DefaultConsensus(nil, nil)
ip, err := consensus.ExternalIP()
if err != nil {
log.Fatal(err)
}

return fmt.Sprintf("%s/32", ip.String())
}
27 changes: 19 additions & 8 deletions test/basic-keyvault/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,28 @@ resource "azurerm_key_vault" "kv_move" {
soft_delete_retention_days = 90

network_acls {
default_action = "Deny"
bypass = "None"
ip_rules = [var.ip]
default_action = "Deny"
bypass = "None"
ip_rules = [var.ip]
virtual_network_subnet_ids = []
}

tags = var.tags

lifecycle {
ignore_changes = [access_policy]
}
}

resource "azurerm_key_vault_access_policy" "move" {
key_vault_id = azurerm_key_vault.kv_move.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
secret_permissions = ["Delete", "Get", "List", "Set"]
key_vault_id = azurerm_key_vault.kv_move.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
secret_permissions = ["Delete", "Get", "List", "Set"]
certificate_permissions = []
key_permissions = []
storage_permissions = []

}

resource "azurerm_key_vault_secret" "move" {
Expand All @@ -105,6 +114,8 @@ resource "azurerm_key_vault_secret" "move" {
key_vault_id = azurerm_key_vault.kv_move.id

lifecycle {
ignore_changes = [ content_type ]
ignore_changes = [content_type]
}

tags = var.tags
}
37 changes: 0 additions & 37 deletions test/basic-keyvault/test.sh

This file was deleted.

58 changes: 58 additions & 0 deletions test/basic-storage/basic_storage_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// +build acctest
// NOTE: We use build tags to differentiate acceptance testing

package test

import (
"os/exec"
"testing"

"github.com/arschles/assert"
"github.com/gruntwork-io/terratest/modules/terraform"
)

func TestAztfmoveVNet(t *testing.T) {
t.Parallel()

terraformOptions := &terraform.Options{
TerraformDir: "./",
}
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)

// Test dry-run
cmdDryRun := exec.Command("aztfmove", "-resource-group=input-sa-rg", "-target-resource-group=output-sa-rg", "-auto-approve", "-dry-run")
outDryRun, err := cmdDryRun.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outDryRun)
}
t.Log("Dry-run succeeded")

// Test move
cmdMove := exec.Command("aztfmove", "-resource-group=input-sa-rg", "-target-resource-group=output-sa-rg", "-auto-approve")
outMove, err := cmdMove.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outMove)
}
t.Log("First move succeeded")

// Test dry-run
cmdDryRunBack := exec.Command("aztfmove", "-target-resource-group=input-sa-rg", "-auto-approve", "-dry-run")
outDryRunBack, err := cmdDryRunBack.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outDryRunBack)
}
t.Log("Dry-run 2 succeeded")

// Test move
cmdMoveBack := exec.Command("aztfmove", "-target-resource-group=input-sa-rg", "-auto-approve")
outMoveBack, err := cmdMoveBack.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outMoveBack)
}
t.Log("Second move succeeded")

// Validate move
exitCode := terraform.InitAndPlanWithExitCode(t, terraformOptions)
assert.Equal(t, exitCode, 0, "Exitcode must be 0")
}
36 changes: 0 additions & 36 deletions test/basic-storage/test.sh

This file was deleted.

58 changes: 58 additions & 0 deletions test/basic-vnet/basic_vnet_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// +build acctest
// NOTE: We use build tags to differentiate acceptance testing

package test

import (
"os/exec"
"testing"

"github.com/arschles/assert"
"github.com/gruntwork-io/terratest/modules/terraform"
)

func TestAztfmoveVNet(t *testing.T) {
t.Parallel()

terraformOptions := &terraform.Options{
TerraformDir: "./",
}
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)

// Test dry-run
cmdDryRun := exec.Command("aztfmove", "-resource=azurerm_virtual_network.vnet", "-target-resource-group=output-rg", "-auto-approve", "-dry-run")
outDryRun, err := cmdDryRun.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outDryRun)
}
t.Log("Dry-run succeeded")

// Test move
cmdMove := exec.Command("aztfmove", "-resource=azurerm_virtual_network.vnet", "-target-resource-group=output-rg", "-auto-approve")
outMove, err := cmdMove.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outMove)
}
t.Log("First move succeeded")

// Test dry-run
cmdDryRunBack := exec.Command("aztfmove", "-target-resource-group=input-rg", "-auto-approve", "-dry-run")
outDryRunBack, err := cmdDryRunBack.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outDryRunBack)
}
t.Log("Dry-run 2 succeeded")

// Test move
cmdMoveBack := exec.Command("aztfmove", "-target-resource-group=input-rg", "-auto-approve")
outMoveBack, err := cmdMoveBack.CombinedOutput()
if err != nil {
t.Errorf("aztfmove errorred out: \n\n%s", outMoveBack)
}
t.Log("Second move succeeded")

// Validate move
exitCode := terraform.InitAndPlanWithExitCode(t, terraformOptions)
assert.Equal(t, exitCode, 0, "Exitcode must be 0")
}
Loading

0 comments on commit cf29e48

Please sign in to comment.