Samples: end-to-end testing (#47)
Add a new sample for end-to-end testing in Terraform projects.
This commit is contained in:
140
samples/end-to-end-testing/src/main.tf
Normal file
140
samples/end-to-end-testing/src/main.tf
Normal file
@ -0,0 +1,140 @@
|
||||
resource "random_integer" "rand" {
|
||||
min = 1000
|
||||
max = 9999
|
||||
}
|
||||
|
||||
resource "azurerm_resource_group" "rg" {
|
||||
name = "rg-terratest-sample-${random_integer.rand.result}"
|
||||
location = var.location
|
||||
}
|
||||
|
||||
resource "azurerm_virtual_network" "vnet" {
|
||||
name = "vnet-terratest-sample"
|
||||
address_space = ["10.0.0.0/16"]
|
||||
location = azurerm_resource_group.rg.location
|
||||
resource_group_name = azurerm_resource_group.rg.name
|
||||
}
|
||||
|
||||
resource "azurerm_subnet" "subnet" {
|
||||
name = "default"
|
||||
resource_group_name = azurerm_resource_group.rg.name
|
||||
virtual_network_name = azurerm_virtual_network.vnet.name
|
||||
address_prefixes = ["10.0.2.0/24"]
|
||||
}
|
||||
|
||||
## Linux VM 1
|
||||
|
||||
resource "azurerm_public_ip" "pip" {
|
||||
name = "pip-vm-linux-1"
|
||||
location = azurerm_resource_group.rg.location
|
||||
resource_group_name = azurerm_resource_group.rg.name
|
||||
allocation_method = "Dynamic"
|
||||
idle_timeout_in_minutes = 30
|
||||
}
|
||||
|
||||
resource "azurerm_network_interface" "nic1" {
|
||||
name = "nic-vm-linux-1"
|
||||
location = azurerm_resource_group.rg.location
|
||||
resource_group_name = azurerm_resource_group.rg.name
|
||||
|
||||
ip_configuration {
|
||||
name = "internal"
|
||||
subnet_id = azurerm_subnet.subnet.id
|
||||
private_ip_address_allocation = "Dynamic"
|
||||
public_ip_address_id = azurerm_public_ip.pip.id
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_group" "nsg" {
|
||||
name = "nsg-terraform-sample"
|
||||
location = var.location
|
||||
resource_group_name = azurerm_resource_group.rg.name
|
||||
|
||||
security_rule {
|
||||
name = "SSH"
|
||||
priority = 1001
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "Tcp"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "22"
|
||||
source_address_prefix = "*"
|
||||
destination_address_prefix = "*"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_network_interface_security_group_association" "nic1-nsg" {
|
||||
network_interface_id = azurerm_network_interface.nic1.id
|
||||
network_security_group_id = azurerm_network_security_group.nsg.id
|
||||
}
|
||||
|
||||
resource "azurerm_linux_virtual_machine" "vm1" {
|
||||
name = "vm-linux-1"
|
||||
resource_group_name = azurerm_resource_group.rg.name
|
||||
location = azurerm_resource_group.rg.location
|
||||
size = "Standard_B2s"
|
||||
admin_username = "azureuser"
|
||||
network_interface_ids = [
|
||||
azurerm_network_interface.nic1.id,
|
||||
]
|
||||
|
||||
admin_ssh_key {
|
||||
username = "azureuser"
|
||||
public_key = file("~/.ssh/id_rsa.pub")
|
||||
}
|
||||
|
||||
os_disk {
|
||||
caching = "ReadWrite"
|
||||
storage_account_type = "Standard_LRS"
|
||||
}
|
||||
|
||||
source_image_reference {
|
||||
publisher = "Canonical"
|
||||
offer = "UbuntuServer"
|
||||
sku = "18.04-LTS"
|
||||
version = "latest"
|
||||
}
|
||||
}
|
||||
|
||||
## Linux VM 2
|
||||
|
||||
resource "azurerm_network_interface" "nic2" {
|
||||
name = "nic-vm-linux-2"
|
||||
location = azurerm_resource_group.rg.location
|
||||
resource_group_name = azurerm_resource_group.rg.name
|
||||
|
||||
ip_configuration {
|
||||
name = "internal"
|
||||
subnet_id = azurerm_subnet.subnet.id
|
||||
private_ip_address_allocation = "Dynamic"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_linux_virtual_machine" "vm2" {
|
||||
name = "vm-linux-2"
|
||||
resource_group_name = azurerm_resource_group.rg.name
|
||||
location = azurerm_resource_group.rg.location
|
||||
size = "Standard_B2s"
|
||||
admin_username = "azureuser"
|
||||
|
||||
network_interface_ids = [
|
||||
azurerm_network_interface.nic2.id,
|
||||
]
|
||||
|
||||
admin_ssh_key {
|
||||
username = "azureuser"
|
||||
public_key = file(var.ssh_public_key_file)
|
||||
}
|
||||
|
||||
os_disk {
|
||||
caching = "ReadWrite"
|
||||
storage_account_type = "Standard_LRS"
|
||||
}
|
||||
|
||||
source_image_reference {
|
||||
publisher = "Canonical"
|
||||
offer = "UbuntuServer"
|
||||
sku = "18.04-LTS"
|
||||
version = "latest"
|
||||
}
|
||||
}
|
11
samples/end-to-end-testing/src/output.tf
Normal file
11
samples/end-to-end-testing/src/output.tf
Normal file
@ -0,0 +1,11 @@
|
||||
output "resource_group_name" {
|
||||
value = azurerm_resource_group.rg.name
|
||||
}
|
||||
|
||||
output "vm_linux_1_public_ip_address" {
|
||||
value = azurerm_public_ip.pip.ip_address
|
||||
}
|
||||
|
||||
output "vm_linux_2_private_ip_address" {
|
||||
value = azurerm_network_interface.nic2.ip_configuration[0].private_ip_address
|
||||
}
|
3
samples/end-to-end-testing/src/provider.tf
Normal file
3
samples/end-to-end-testing/src/provider.tf
Normal file
@ -0,0 +1,3 @@
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
}
|
101
samples/end-to-end-testing/src/test/end2end_test.go
Normal file
101
samples/end-to-end-testing/src/test/end2end_test.go
Normal file
@ -0,0 +1,101 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gruntwork-io/terratest/modules/terraform"
|
||||
test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
func TestEndToEndDeploymentScenario(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fixtureFolder := "../"
|
||||
sshKeyPath := os.Getenv("TEST_SSH_KEY_PATH")
|
||||
|
||||
if sshKeyPath == "" {
|
||||
t.Fatalf("TEST_SSH_KEY_PATH environment variable cannot be empty.")
|
||||
}
|
||||
|
||||
// User Terratest to deploy the infrastructure
|
||||
test_structure.RunTestStage(t, "setup", func() {
|
||||
terraformOptions := &terraform.Options{
|
||||
// Indicate the directory that contains the Terraform configuration to deploy
|
||||
TerraformDir: fixtureFolder,
|
||||
}
|
||||
|
||||
// Save options for later test stages
|
||||
test_structure.SaveTerraformOptions(t, fixtureFolder, terraformOptions)
|
||||
|
||||
// Triggers the terraform init and terraform apply command
|
||||
terraform.InitAndApply(t, terraformOptions)
|
||||
})
|
||||
|
||||
test_structure.RunTestStage(t, "validate", func() {
|
||||
// run validation checks here
|
||||
terraformOptions := test_structure.LoadTerraformOptions(t, fixtureFolder)
|
||||
|
||||
vmLinux1PublicIPAddress := terraform.Output(t, terraformOptions, "vm_linux_1_public_ip_address")
|
||||
vmLinux2PrivateIPAddress := terraform.Output(t, terraformOptions, "vm_linux_2_private_ip_address")
|
||||
|
||||
// it takes some time for Azure to assign the public IP address so it's not available in Terraform output after the first apply
|
||||
attemptsCount := 0
|
||||
for vmLinux1PublicIPAddress == "" && attemptsCount < 5 {
|
||||
// add wait time to let Azure assign the public IP address and apply the configuration again, to refresh state.
|
||||
time.Sleep(30 * time.Second)
|
||||
terraform.Apply(t, terraformOptions)
|
||||
vmLinux1PublicIPAddress = terraform.Output(t, terraformOptions, "vm_linux_1_public_ip_address")
|
||||
attemptsCount++
|
||||
}
|
||||
|
||||
if vmLinux1PublicIPAddress == "" {
|
||||
t.Fatal("Cannot retrieve the public IP address value for the linux vm 1.")
|
||||
}
|
||||
|
||||
key, err := ioutil.ReadFile(sshKeyPath)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read private key: %v", err)
|
||||
}
|
||||
|
||||
signer, err := ssh.ParsePrivateKey(key)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to parse private key: %v", err)
|
||||
}
|
||||
|
||||
sshConfig := &ssh.ClientConfig{
|
||||
User: "azureuser",
|
||||
Auth: []ssh.AuthMethod{
|
||||
ssh.PublicKeys(signer),
|
||||
},
|
||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
||||
}
|
||||
|
||||
sshConnection, err := ssh.Dial("tcp", fmt.Sprintf("%s:22", vmLinux1PublicIPAddress), sshConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot establish SSH connection to vm-linux-1 public IP address: %v", err)
|
||||
}
|
||||
|
||||
defer sshConnection.Close()
|
||||
sshSession, err := sshConnection.NewSession()
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot create SSH session to vm-linux-1 public IP address: %v", err)
|
||||
}
|
||||
|
||||
defer sshSession.Close()
|
||||
err = sshSession.Run(fmt.Sprintf("ping -c 1 %s", vmLinux2PrivateIPAddress))
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot ping vm-linux-2 from vm-linux-2: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
// When the test is completed, teardown the infrastructure by calling terraform destroy
|
||||
test_structure.RunTestStage(t, "teardown", func() {
|
||||
terraformOptions := test_structure.LoadTerraformOptions(t, fixtureFolder)
|
||||
terraform.Destroy(t, terraformOptions)
|
||||
})
|
||||
}
|
8
samples/end-to-end-testing/src/test/go.mod
Normal file
8
samples/end-to-end-testing/src/test/go.mod
Normal file
@ -0,0 +1,8 @@
|
||||
module test
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/gruntwork-io/terratest v0.28.5
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975
|
||||
)
|
11
samples/end-to-end-testing/src/variables.tf
Normal file
11
samples/end-to-end-testing/src/variables.tf
Normal file
@ -0,0 +1,11 @@
|
||||
variable location {
|
||||
type = string
|
||||
description = "The Azure location where the resources will be created."
|
||||
default = "westeurope"
|
||||
}
|
||||
|
||||
variable ssh_public_key_file {
|
||||
type = string
|
||||
description = "The file path of the public SSH key to use for the virtual machine."
|
||||
default = "~/.ssh/id_rsa.pub"
|
||||
}
|
Reference in New Issue
Block a user