Skip to content
This repository has been archived by the owner on Jan 25, 2023. It is now read-only.

Commit

Permalink
Merge pull request #85 from MatthiasScholz/master
Browse files Browse the repository at this point in the history
Making CIDR Blocks Configurable
  • Loading branch information
brikis98 committed Feb 1, 2021
2 parents ee3eb0f + aaaf615 commit bf3ee5f
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 19 deletions.
1 change: 0 additions & 1 deletion examples/nomad-consul-separate-cluster/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -244,4 +244,3 @@ data "aws_subnet_ids" "default" {

data "aws_region" "current" {
}

1 change: 0 additions & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,3 @@ data "aws_subnet_ids" "default" {

data "aws_region" "current" {
}

4 changes: 2 additions & 2 deletions modules/nomad-cluster/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ resource "aws_security_group" "lc_security_group" {
}

resource "aws_security_group_rule" "allow_ssh_inbound" {
count = length(var.allowed_ssh_cidr_blocks) > 0 ? 1 : 0
type = "ingress"
from_port = var.ssh_port
to_port = var.ssh_port
Expand All @@ -150,7 +151,7 @@ resource "aws_security_group_rule" "allow_all_outbound" {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
cidr_blocks = var.allow_outbound_cidr_blocks

security_group_id = aws_security_group.lc_security_group.id
}
Expand Down Expand Up @@ -214,4 +215,3 @@ data "aws_iam_policy_document" "instance_role" {
}
}
}

6 changes: 6 additions & 0 deletions modules/nomad-cluster/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,12 @@ variable "protect_from_scale_in" {
default = false
}

variable "allow_outbound_cidr_blocks" {
description = "Allow outbound traffic to these CIDR blocks."
type = list(string)
default = ["0.0.0.0/0"]
}

variable "iam_permissions_boundary" {
description = "If set, restricts the created IAM role to the given permissions boundary"
type = string
Expand Down
13 changes: 1 addition & 12 deletions test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,12 @@ clean up.
### Prerequisites

- Install the latest version of [Go](https://golang.org/).
- Install [dep](https://github.com/golang/dep) for Go dependency management.
- Install [Terraform](https://www.terraform.io/downloads.html).
- Configure your AWS credentials using one of the [options supported by the AWS
SDK](http://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html). Usually, the easiest option is to
set the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables.


### One-time setup

Download Go dependencies using dep:

```
cd test
dep ensure
```


### Run all the tests

```bash
Expand All @@ -61,4 +50,4 @@ go test -v -timeout 60m -run TestFoo
```




3 changes: 2 additions & 1 deletion test/aws_helpers.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package test

import (
"github.com/gruntwork-io/terratest/modules/aws"
"testing"

"github.com/gruntwork-io/terratest/modules/aws"
)

// Get the IP address from a randomly chosen EC2 Instance in an Auto Scaling Group of the given name in the given
Expand Down
8 changes: 8 additions & 0 deletions test/nomad_cluster_ssh_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package test

import "testing"

func TestNomadClusterSSHAccess(t *testing.T) {
t.Parallel()
runNomadClusterSSHTest(t, "amazon-linux-2-ami", "ec2-user")
}
122 changes: 121 additions & 1 deletion test/nomad_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import (
"io/ioutil"
"net/http"
"path/filepath"
"strings"
"testing"
"time"

"github.com/gruntwork-io/terratest/modules/aws"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/random"
"github.com/gruntwork-io/terratest/modules/retry"
"github.com/gruntwork-io/terratest/modules/ssh"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/gruntwork-io/terratest/modules/test-structure"
)
Expand All @@ -22,6 +24,7 @@ const REPO_ROOT = "../"
const ENV_VAR_AWS_REGION = "AWS_DEFAULT_REGION"

const VAR_AMI_ID = "ami_id"
const VAR_SSH_CIDR = "allowed_ssh_cidr_blocks"

const CLUSTER_COLOCATED_EXAMPLE_PATH = "/"
const CLUSTER_COLOCATED_EXAMPLE_VAR_CLUSTER_NAME = "cluster_name"
Expand All @@ -36,6 +39,7 @@ const CLUSTER_SEPARATE_EXAMPLE_VAR_CONSUL_CLUSTER_NAME = "consul_cluster_name"
const CLUSTER_SEPARATE_EXAMPLE_VAR_NUM_NOMAD_SERVERS = "num_nomad_servers"
const CLUSTER_SEPARATE_EXAMPLE_VAR_NUM_CONSUL_SERVERS = "num_consul_servers"
const CLUSTER_SEPARATE_EXAMPLE_VAR_NUM_NOMAD_CLIENTS = "num_nomad_clients"
const CLUSTER_SEPARATE_EXAMPLE_VAR_SSH_KEY_NAME = "ssh_key_name"
const CLUSTER_SEPARATE_EXAMPLE_OUTPUT_NOMAD_SERVER_ASG_NAME = "asg_name_nomad_servers"

const DEFAULT_NUM_SERVERS = 3
Expand Down Expand Up @@ -169,11 +173,66 @@ func runNomadClusterSeparateTest(t *testing.T, packerBuildName string) {

// Check that the Nomad cluster comes up within a reasonable time period and can respond to requests
func checkNomadClusterIsWorking(t *testing.T, asgNameOutputVar string, terraformOptions *terraform.Options, awsRegion string) {
asgName := terraform.Output(t, terraformOptions, asgNameOutputVar)
asgName := rawTerraformOutput(t, terraformOptions, asgNameOutputVar)
nodeIpAddress := getIpAddressOfAsgInstance(t, asgName, awsRegion)
testNomadCluster(t, nodeIpAddress)
}

func checkNomadClusterSshAccess(t *testing.T, asgNameOutputVar string, terraformOptions *terraform.Options, awsRegion string, keyPair *ssh.KeyPair, sshUsername string) {
asgName := rawTerraformOutput(t, terraformOptions, asgNameOutputVar)
nodeIpAddress := getIpAddressOfAsgInstance(t, asgName, awsRegion)

publicHost := ssh.Host{
Hostname: nodeIpAddress,
SshKeyPair: keyPair,
SshUserName: sshUsername,
}

testSshAccess(t, publicHost, true)
}

func testSshAccess(t *testing.T, publicHost ssh.Host, ssh_access bool) {
// Check basic SSH to the instance
// SSH access might fail, if none is configured - this is expected.
response, err := retry.DoWithRetryE(t, "SSH to public host", 30, 5*time.Second, func() (string, error) {
expectedText := fmt.Sprintf("Hello, %s", publicHost.Hostname)
command := fmt.Sprintf("echo -n '%s'", expectedText)
actualText, err := ssh.CheckSshCommandE(t, publicHost, command)

if err != nil {
return "", err
}

if strings.TrimSpace(actualText) != expectedText {
return "", fmt.Errorf("Expected SSH command to return '%s' but got '%s'", expectedText, actualText)
}

return "SSH access was successful", nil
})

// No SSH access results in an error.
if err != nil && !ssh_access {
logger.Logf(t, "Nomad cluster is properly deployed without SSH access: %s", response)
return
}
if err == nil && !ssh_access {
logger.Logf(t, "Nomad cluster is NOT properly deployed without SSH access: %s", response)
t.Fatal("No SSH access configured, but nevertheless SSH access was successful.")
}

// SSH access should result in no error.
if err == nil && ssh_access {
logger.Logf(t, "Nomad cluster is properly deployed with SSH access: %s", response)
return
}
if err != nil && ssh_access {
logger.Logf(t, "Nomad cluster is NOT properly deployed with SSH access: %s", response)
t.Fatal("SSH access configured, but SSH test was unsuccessful.")
}

t.Fatal("Something went wrong. This part should never be reached.")
}

// Use a Nomad client to connect to the given node and use it to verify that:
//
// 1. The Nomad cluster has deployed
Expand Down Expand Up @@ -233,3 +292,64 @@ func callNomadApi(t *testing.T, nodeIpAddress string, path string) ([]interface{

return result, nil
}

func runNomadClusterSSHTest(t *testing.T, packerBuildName string, ssh_username string) {
examplesDir := test_structure.CopyTerraformFolderToTemp(t, REPO_ROOT, "/")

defer test_structure.RunTestStage(t, "teardown", func() {
terraformOptions := test_structure.LoadTerraformOptions(t, examplesDir)
terraform.Destroy(t, terraformOptions)

amiId := test_structure.LoadAmiId(t, examplesDir)
awsRegion := test_structure.LoadString(t, examplesDir, SAVED_AWS_REGION)
aws.DeleteAmi(t, awsRegion, amiId)
})

test_structure.RunTestStage(t, "setup_ami", func() {
awsRegion := getRandomRegion(t)
test_structure.SaveString(t, examplesDir, SAVED_AWS_REGION, awsRegion)

uniqueId := random.UniqueId()
test_structure.SaveString(t, examplesDir, SAVED_UNIQUE_ID, uniqueId)

amiId := buildAmi(t, filepath.Join(examplesDir, "examples", "nomad-consul-ami", "nomad-consul.json"), packerBuildName, awsRegion, uniqueId)
test_structure.SaveAmiId(t, examplesDir, amiId)
})

test_structure.RunTestStage(t, "deploy", func() {
amiId := test_structure.LoadAmiId(t, examplesDir)
awsRegion := test_structure.LoadString(t, examplesDir, SAVED_AWS_REGION)
uniqueId := test_structure.LoadString(t, examplesDir, SAVED_UNIQUE_ID)

terraformOptions := &terraform.Options{
TerraformDir: filepath.Join(examplesDir, "examples", "nomad-consul-separate-cluster"),
Vars: map[string]interface{}{
CLUSTER_SEPARATE_EXAMPLE_VAR_NOMAD_CLUSTER_NAME: fmt.Sprintf("test-%s", uniqueId),
CLUSTER_SEPARATE_EXAMPLE_VAR_CONSUL_CLUSTER_NAME: fmt.Sprintf("test-%s", uniqueId),
CLUSTER_SEPARATE_EXAMPLE_VAR_NUM_NOMAD_SERVERS: DEFAULT_NUM_SERVERS,
CLUSTER_SEPARATE_EXAMPLE_VAR_NUM_CONSUL_SERVERS: DEFAULT_NUM_SERVERS,
CLUSTER_SEPARATE_EXAMPLE_VAR_NUM_NOMAD_CLIENTS: DEFAULT_NUM_CLIENTS,
VAR_AMI_ID: amiId,
},
EnvVars: map[string]string{
ENV_VAR_AWS_REGION: awsRegion,
},
}

keyPairName := fmt.Sprintf("terratest-onetime-key-%s", uniqueId)
keyPair := aws.CreateAndImportEC2KeyPair(t, awsRegion, keyPairName)
terraformOptions.Vars[CLUSTER_SEPARATE_EXAMPLE_VAR_SSH_KEY_NAME] = keyPairName
test_structure.SaveEc2KeyPair(t, examplesDir, keyPair)

test_structure.SaveTerraformOptions(t, examplesDir, terraformOptions)

terraform.InitAndApply(t, terraformOptions)
})

test_structure.RunTestStage(t, "validate", func() {
terraformOptions := test_structure.LoadTerraformOptions(t, examplesDir)
awsRegion := test_structure.LoadString(t, examplesDir, SAVED_AWS_REGION)
keyPair := test_structure.LoadEc2KeyPair(t, examplesDir)
checkNomadClusterSshAccess(t, CLUSTER_SEPARATE_EXAMPLE_OUTPUT_NOMAD_SERVER_ASG_NAME, terraformOptions, awsRegion, keyPair.KeyPair, ssh_username)
})
}
12 changes: 11 additions & 1 deletion test/terratest_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package test

import (
"fmt"
"github.com/gruntwork-io/terratest/modules/packer"
"strings"
"testing"

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

const CONSUL_AMI_TEMPLATE_VAR_REGION = "aws_region"
Expand All @@ -22,3 +25,10 @@ func buildAmi(t *testing.T, packerTemplatePath string, packerBuildName string, a

return packer.BuildAmi(t, options)
}

// Recent terraform version changed the behavior on terraform output.
// Values now contain quotations marks, if terraform output is called with `-raw` option.
// - https://github.com/gruntwork-io/terratest/issues/766
func rawTerraformOutput(t *testing.T, terraformOptions *terraform.Options, outputVariableName string) string {
return strings.Trim(terraform.Output(t, terraformOptions, outputVariableName), "\"")
}

0 comments on commit bf3ee5f

Please sign in to comment.