github.com/darmach/terratest@v0.34.8-0.20210517103231-80931f95e3ff/test/terraform_remote_exec_example_test.go (about) 1 package test 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "strings" 9 "testing" 10 11 "github.com/gruntwork-io/terratest/modules/aws" 12 "github.com/gruntwork-io/terratest/modules/random" 13 "github.com/gruntwork-io/terratest/modules/ssh" 14 "github.com/gruntwork-io/terratest/modules/terraform" 15 test_structure "github.com/gruntwork-io/terratest/modules/test-structure" 16 "github.com/stretchr/testify/assert" 17 ) 18 19 // This test shows how to override the systems local SSH Agent, with an in-process SSH agent, whose keys can be managed 20 // from within your tests. This allows you to test Terraform modules which make SSH connections to the created 21 // instances, useful for tasks such as provisioning. 22 func TestTerraformRemoteExecExample(t *testing.T) { 23 t.Parallel() 24 25 terraformDirectory := "../examples/terraform-remote-exec-example" 26 27 // At the end of the test, run `terraform destroy` to clean up any resources that were created 28 defer test_structure.RunTestStage(t, "teardown", func() { 29 terraformOptions := test_structure.LoadTerraformOptions(t, terraformDirectory) 30 keyPair := test_structure.LoadEc2KeyPair(t, terraformDirectory) 31 32 // destroy terraform resources and delete ec2 key pair 33 terraform.Destroy(t, terraformOptions) 34 aws.DeleteEC2KeyPair(t, keyPair) 35 36 // remove testFile, if it exists 37 testFile := filepath.Join(terraformDirectory, "public-ip") 38 if _, err := os.Stat(testFile); err == nil { 39 os.Remove(testFile) 40 } 41 }) 42 43 // Deploy the example 44 test_structure.RunTestStage(t, "setup", func() { 45 46 // A unique ID we can use to namespace resources so we don't clash with anything already in the AWS account or 47 // tests running in parallel 48 uniqueID := random.UniqueId() 49 50 // Give this EC2 Instance and other resources in the Terraform code a name with a unique ID so it doesn't clash 51 // with anything else in the AWS account. 52 instanceName := fmt.Sprintf("terratest-remote-exec-example-%s", uniqueID) 53 54 // Pick a random AWS region to test in. This helps ensure your code works in all regions. 55 awsRegion := aws.GetRandomStableRegion(t, nil, nil) 56 57 // Some AWS regions are missing certain instance types, so pick an available type based on the region we picked 58 instanceType := aws.GetRecommendedInstanceType(t, awsRegion, []string{"t2.micro", "t3.micro"}) 59 60 // Create an EC2 KeyPair that we can use for SSH access 61 keyPairName := fmt.Sprintf("terratest-remote-exec-example-%s", uniqueID) 62 keyPair := aws.CreateAndImportEC2KeyPair(t, awsRegion, keyPairName) 63 64 // start an SSH agent, with our key pair added 65 sshAgent := ssh.SshAgentWithKeyPair(t, keyPair.KeyPair) 66 defer sshAgent.Stop() 67 68 // Construct the terraform options with default retryable errors to handle the most common retryable errors in 69 // terraform testing. 70 terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ 71 // The path to where our Terraform code is located 72 TerraformDir: terraformDirectory, 73 74 // Variables to pass to our Terraform code using -var options 75 Vars: map[string]interface{}{ 76 "aws_region": awsRegion, 77 "instance_name": instanceName, 78 "instance_type": instanceType, 79 "key_pair_name": keyPairName, 80 }, 81 82 SshAgent: sshAgent, // Overrides local SSH agent with our new agent 83 }) 84 85 // Save the options and key pair so later test stages can use them 86 test_structure.SaveTerraformOptions(t, terraformDirectory, terraformOptions) 87 test_structure.SaveEc2KeyPair(t, terraformDirectory, keyPair) 88 89 // Because of the SshAgent option above, the terraform process will be provided an `SSH_AUTH_SOCK` environment 90 // variable, which will point to the socket file of our in-process `sshAgent` instance: 91 terraform.InitAndApply(t, terraformOptions) 92 93 // save the `public_instance_ip` output variable for later steps 94 publicIP := terraform.Output(t, terraformOptions, "public_instance_ip") 95 test_structure.SaveString(t, terraformDirectory, "publicIP", publicIP) 96 }) 97 98 // Make sure we can SSH to the public Instance directly from the public Internet and the private Instance by using 99 // the public Instance as a jump host 100 test_structure.RunTestStage(t, "validate", func() { 101 publicIP := test_structure.LoadString(t, terraformDirectory, "publicIP") 102 103 // Confirm that the public-ip file that was generated by the provisioner was copied back from the server using 104 // the `scp` command 105 testFile := filepath.Join(terraformDirectory, "public-ip") 106 assert.FileExists(t, testFile) 107 108 // Check that public IP from output matches public IP generated by script on the server 109 b, err := ioutil.ReadFile(testFile) 110 if err != nil { 111 fmt.Print(err) 112 } 113 assert.Equal(t, strings.TrimSpace(publicIP), strings.TrimSpace(string(b))) 114 }) 115 116 }