Giter VIP home page Giter VIP logo

cli's Introduction

terraform-compliance



terraform-compliance is a lightweight, security and compliance focused test framework against terraform to enable negative testing capability for your infrastructure-as-code.

  • compliance: Ensure the implemented code is following security standards, your own custom standards
  • behaviour driven development: We have BDD for nearly everything, why not for IaC ?
  • portable: just install it from pip or run it via docker. See Installation
  • pre-deploy: it validates your code before it is deployed
  • easy to integrate: it can run in your pipeline (or in git hooks) to ensure all deployments are validated.
  • segregation of duty: you can keep your tests in a different repository where a separate team is responsible.
  • why ?: why not ?

Performance

If terraform-compliance is not running quickly enough make sure to check the optional faster_parsing pip install flag in the Installation Guide

Idea

terraform-compliance mainly focuses on negative testing instead of having fully-fledged functional tests that are mostly used for proving a component of code is performing properly.

Fortunately, terraform is a marvellous abstraction layer for any API that creates/updates/destroys entities. terraform also provides the capability to ensure everything is up-to-date between the local configuration and the remote API(s) responses.

Given the fact, terraform is used mostly against Cloud APIs, what was missing is to ensure your code against your infrastructure must follow specific policies. Currently HashiCorp provides Sentinel for Enterprise Products. terraform-compliance is providing a similar functionality only for terraform while it is free-to-use and it is Open Source.

E.g. a sample policy could be, if you are working with AWS, you should not create an S3 bucket, without having any encryption. Of course, this is just an example which may or not be applicable for your case.

terraform-compliance provides a test framework to create these policies that will be executed against your terraform plan in a context where both developers and security teams can understand easily while reading it, by applying Behaviour Driven Development Principles.

As returning back to the example, our example defined above will be translated into a BDD Feature and Scenario, as also seen in below ;

if you are working with AWS, you should not create an S3 bucket, without having any encryption

translates into ;

Given I have AWS S3 Bucket defined
Then it must contain server_side_encryption_configuration

server_side_encryption_configuration is coming from the terraform code, as shown below ;

resource "aws_s3_bucket" "b" {
  bucket = "my-bucket"
  acl    = "private"

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        kms_master_key_id = "${aws_kms_key.mykey.arn}"
        sse_algorithm     = "aws:kms"
      }
    }
  }
}

This policy ( Scenario ) will allow all S3 buckets newly created or updated must have encryption configuration set within the code. In an ideal way, this Scenario (among with all other Scenarios) will run on a CI/CD pipeline that will ensure that nothing is deployed by violating your policies.

See Examples for more sample use cases.

Regarding the feature file format - radish is used to parse files with extension .feature - https://radish.readthedocs.io/en/stable/tutorial.html

Example Run

Sponsors

  • resmo.com: Discover unmatched insights for Cloud and SaaS assets. Use SQL to ask questions and get real-time notifications for security and compliance violations.

License

MIT

cli's People

Contributors

artran avatar burningalchemist avatar byarbrough avatar dependabot-preview[bot] avatar dependabot[bot] avatar dylanhellems avatar eerkunt avatar hjribeiro avatar horizonnet avatar huddy avatar joaoubaldo avatar jrsherry avatar kudbettin avatar martinlogan avatar mat1g3r avatar mhaley-miovision avatar misterfreeze avatar mungojam avatar n30nx avatar ptiredknees avatar samtarplee avatar shocktrooper avatar sleightsec avatar supergarotinho avatar timgates42 avatar tom-butler avatar vrbcntrl avatar whbilly avatar wp-davisona avatar yibble avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cli's Issues

Tag feature: NameError: name 'module' is not defined

Hello, I am having an issue:

Feature: Resources should be properly tagged
  In order to keep track of resource ownership
  As engineers
  We'll enforce tagging on all resources

  Scenario Outline: Name tag
    Given I have resource that supports tags defined
    Then it must contain tags
    And it must contain <tags>

  Examples:
  | tags        |
  | Name        |

result:

terraform-compliance v0.4.11 initiated
Steps    : /usr/local/lib/python2.7/site-packages/terraform_compliance/steps
Features : /Users/demianginther/git/tf-modules/compliance
TF Files : /var/folders/zf/f1h382nn35z3gd1kv92bw6r80000gn/T/tmpRbZyeD (.)
Reading terraform files.
All HCL files look good.
Running tests.
Feature: Resources should be properly tagged  # /Users/demianginther/git/tf-modules/compliance/tags.feature
    In order to keep track of resource ownership
    As engineers
    We'll enforce tagging on all resources

    Scenario Outline: Name tag
        Given I have resource that supports tags defined
        Then it must contain tags
        And it must contain <tags>

    Examples:
        | tags |
        | Name |
          NameError: name 'module' is not defined

I believe this is because I have a module which takes a 'tags' block:

module "akamai_labels" {
  source      = "git::https://github.com/cloudposse/terraform-null-label.git?ref=0.5.3"
  namespace   = "thing"
  name        = "akamai"
  environment = "${var.env}"
  delimiter   = "-"
  label_order = ["environment", "name", "attributes"]

  enabled = true

  tags = {
    "owner"       = "[email protected]"
    "expiry_date" = "n/a"
    "ManagedBy"   = "Terraform"
    "tf_module"   = "akamai/site-shield"
    "env"         = "${var.env}"
  }
}

Any ideas on a bypass?

Tagging feature doesn't recognize variables

I have a tagging variable defined, as follows:

variable "tags" {
  description = "tags to apply to all resources"
  type        = "map"
  default     = {
        "t_name" = "<value>"
        "t_owner_individual" = "<value>"
        "t_responsible_individual" = "<value>"
        "t_environment" = "<value>"
      }
}

On applicable resources, I initialize it as follows:

  tags = "${merge(var.tags, map(
    "Name", "<value>"
  ))}"

With the tagging.feature enabled, I see that it is specifically checking the text of the tag resource, rather than evaluating the variable:

   Examples:
        | tags                     |
        | Name                     |
          AssertionError: Name property in tags can not be found in es_vpc (aws_elasticsearch_domain). It is set to ${merge(var.tags, map(
    "Name", "${var.domain_name}"
  ))} instead
        | t_name                   |
          AssertionError: t_name property in tags can not be found in es_vpc (aws_elasticsearch_domain). It is set to ${merge(var.tags, map(
    "Name", "${var.domain_name}"
  ))} instead
        | t_owner_individual       |
          AssertionError: t_owner_individual property in tags can not be found in es_vpc (aws_elasticsearch_domain). It is set to ${merge(var.tags, map(
    "Name", "${var.domain_name}"
  ))} instead
        | t_responsible_individual |
          AssertionError: t_responsible_individual property in tags can not be found in es_vpc (aws_elasticsearch_domain). It is set to ${merge(var.tags, map(
    "Name", "${var.domain_name}"
  ))} instead
        | t_environment            |
          AssertionError: t_environment property in tags can not be found in es_vpc (aws_elasticsearch_domain). It is set to ${merge(var.tags, map(
    "Name", "${var.domain_name}"
  ))} instead

Tag Feature: AttributeError

receiving:

terraform-compliance v0.4.11 initiated
Steps    : /usr/local/lib/python2.7/site-packages/terraform_compliance/steps
Features : /Users/demianginther/git/tf-modules/compliance
TF Files : /var/folders/zf/f1h382nn35z3gd1kv92bw6r80000gn/T/tmpdenIxW (.)
Reading terraform files.
All HCL files look good.
Running tests.
Feature: Resources should be properly tagged  # /Users/demianginther/git/tf-modules/compliance/tags.feature
    In order to keep track of resource ownership
    As engineers
    We'll enforce tagging on all resources
1 features (0 passed)
1 scenarios (0 passed)
3 steps (0 passed)
Run 1547252156 finished within a moment
Error: Hook 'load_terraform_data' from /usr/local/lib/python2.7/site-packages/terraform_compliance/steps/terrain.py:6 raised: 'AttributeError: 'unicode' object has no attribute 'update''

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/radish/hookregistry.py", line 121, in call
    func(model, *args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/terraform_compliance/steps/terrain.py", line 12, in load_terraform_data
    enable_resource_mounting(tf_conf.terraform_config)
  File "/usr/local/lib/python2.7/site-packages/terraform_compliance/extensions/terraform_validate.py", line 29, in enable_resource_mounting
    enable_resource_mounting(tf_conf, sub_value, sub_resource)
  File "/usr/local/lib/python2.7/site-packages/terraform_compliance/extensions/terraform_validate.py", line 29, in enable_resource_mounting
    enable_resource_mounting(tf_conf, sub_value, sub_resource)
  File "/usr/local/lib/python2.7/site-packages/terraform_compliance/extensions/terraform_validate.py", line 37, in enable_resource_mounting
    change_value_in_dict(tf_conf, target, {source: processing_resource})
  File "/usr/local/lib/python2.7/site-packages/terraform_compliance/common/helper.py", line 134, in change_value_in_dict
    target.update(value_to_change)
AttributeError: 'unicode' object has no attribute 'update'

when setting up a dynamoDB resource set.
Not sure exactly which code is tripping it up.
Any ideas?

"Must Contain Tags" Not working

I have some resources in a main.tf file which support tags, however even if tags are not supplied the following scenario still passes:

Feature: Resources should be properly tagged
  In order to keep track of resource ownership
  As engineers
  We'll enforce tagging on all resources

  Scenario: Ensure all resources have tags
    Given I have resource that supports tags defined
    Then it must contain tags

These is what's in the main.tf file:

provider "aws" {
  #   access_key = “aws_access_key_id”
  #   secret_key = “aws_secret_access_key_id”
  region = "us-east-1"
}

data "aws_availability_zones" "all" {
}

### Creating EC2 instance
resource "aws_instance" "web" {
  ami                    = var.amis[var.region]
  count                  = var.count_var
  key_name               = var.key_name
  vpc_security_group_ids = [aws_security_group.instance.id]
  source_dest_check      = false
  instance_type          = "t2.micro"
#   tags = {
#     Name = format("web-%03d", count.index + 1)
#   }
}

### Creating Security Group for EC2
resource "aws_security_group" "instance" {
  name = "terraform-example-instance"
  ingress {
    from_port   = 8080
    to_port     = 8080
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    # cidr_blocks = ["10.0.0.0/8"]
  }
}

## Creating Launch Configuration
resource "aws_launch_configuration" "example" {
  image_id        = var.amis[var.region]
  instance_type   = "t2.micro"
  security_groups = [aws_security_group.instance.id]
  key_name        = var.key_name
  user_data       = <<-EOF
              #!/bin/bash
              echo "Hello, World" > index.html
              nohup busybox httpd -f -p 8080 &
EOF


  lifecycle {
    create_before_destroy = true
  }
}

## Creating AutoScaling Group
resource "aws_autoscaling_group" "example" {
  launch_configuration = aws_launch_configuration.example.id
  availability_zones = data.aws_availability_zones.all.names
  min_size = 2
  max_size = 10
  load_balancers = [aws_elb.example.name]
  health_check_type = "ELB"
#   tag {
#     key = "Name"
#     value = "terraform-asg-example"
#     propagate_at_launch = true
#   }
}

## Security Group for ELB
resource "aws_security_group" "elb" {
  name = "terraform-example-elb"
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port = 80
    to_port = 80
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

#   tags = {
#     Name = "allow_all"
#   }
}

### Creating ELB
resource "aws_elb" "example" {
  name = "terraform-asg-example"
  security_groups = [aws_security_group.elb.id]
  availability_zones = data.aws_availability_zones.all.names
  health_check {
    healthy_threshold = 2
    unhealthy_threshold = 2
    timeout = 3
    interval = 30
    target = "HTTP:8080/"
  }
  listener {
    lb_port = 80
    lb_protocol = "http"
    instance_port = "8080"
    instance_protocol = "http"
  }
}

Here is the output from the run:

$ terraform-compliance -p /target/tc-test2/tf-template/plan.out.json -f /target/tc-test2/features
terraform-compliance v1.0.7 initiated

* Features  : /target/tc-test2/features
* Plan File : /target/tc-test2/tf-template/plan.out.json

. Running tests.
Feature: Resources should be properly tagged  # /target/tc-test2/features/tags.feature
    In order to keep track of resource ownership
    As engineers
    We'll enforce tagging on all resources

    Scenario: Ensure all resources have tags
        Given I have resource that supports tags defined
        Then it must contain tags

Am I missing anything here?

Thanks in advance.

Non-Colored output

Is it possible to get the terraform-compliance output without colors?

Getting weird characters in Jenkins console output.

image

Support for Tags with Specific Possible Values

First off, I would like to say that I am excited to see version 1.0.0 and it's support for modules and interpolation. I will be testing that out first thing tomorrow morning.

I did have a few use cases that I wanted to ask about which may or may not already be supported. These are related to Tags.

From the examples it looks like we have the ability to check if we have defined a "taggable" resource. We can also check if that resource has some specific tags assigned to it.

  • Is there a way to check if a specific tag key (e.g. department) has one of a list of possible values (e.g. IT, Marketing, HR)? Kind of like a scenario outline

  • Is there a way to enforce a regex pattern on values assigned to a tag? Name definitely come to mind here?

  • Can we check that a tag is not empty?

Any help is appreciated.

terraform-complaince 1.0.1 throws TypeError: argument of type 'NoneType' is not iterable

Hi, Thanks for the new release 1.0.1.
Today, I have started testing the new version 1.0.1 with terraform 0.12.1 plan file, however it throws me an error. please see below

`C:\Training\AWS>terraform-compliance -f C:\Training\terraform-compliance-master\example\example_01\aws -p C:\Training\AWS\cluster-of-web-servers\plans\plan_0.12.1.out
terraform-compliance v1.0.1 initiated

. Converting terraform plan file.
Traceback (most recent call last):
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\runpy.py", line 193, in _run_module_as_main
"main", mod_spec)
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\runpy.py", line 85, in run_code
exec(code, run_globals)
File "C:\Users\vrb.cntrl\AppData\Local\Programs\Python\Python37\Scripts\terraform-compliance.exe_main
.py", line 9, in
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\site-packages\terraform_compliance\main.py", line 33, in cli
_, radish_arguments = parser.parse_known_args(namespace=args)
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\argparse.py", line 1781, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\argparse.py", line 1987, in _parse_known_args
start_index = consume_optional(start_index)
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\argparse.py", line 1927, in consume_optional
take_action(action, args, option_string)
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\argparse.py", line 1855, in take_action
action(self, namespace, argument_values, option_string)
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\site-packages\terraform_compliance\common\readable_plan.py", line 35, in call
values = convert_terraform_plan_to_json(os.path.abspath(values), terraform_executable)
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\site-packages\terraform_compliance\common\terraform_files.py", line 35, in convert_terraform_plan_to_json
stderr=subprocess.PIPE)
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\subprocess.py", line 472, in run
with Popen(*popenargs, **kwargs) as process:
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\subprocess.py", line 775, in init
restore_signals, start_new_session)
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\subprocess.py", line 1119, in _execute_child
args = list2cmdline(args)
File "c:\users\vrb.cntrl\appdata\local\programs\python\python37\lib\subprocess.py", line 530, in list2cmdline
needquote = (" " in arg) or ("\t" in arg) or not arg
TypeError: argument of type 'NoneType' is not iterable`

I have Python 3.7.3
Terraform 0.12.1
Terraform-compliance 1.0.1
Please let me know if I am missing anything here...Thanks in advance!

Not able to configure two different encryption properties for a same resource in __init__.py

Hi,

Currently I am testing a use case where in I have transit_encryption_enabled and at_rest_encryption_enabled properties configured under resource aws_elasticache_replication_group. so test these 2 test cases, I have added the necessary scenarios in the encryption_at_rest and encryption_in_flight scenario files and also added the necessary configuration in the init.py file as shown below
`encryption_property = {
"aws_elasticache_replication_group": "transit_encryption_enabled",
"aws_elasticache_replication_group": "at_rest_encryption_enabled"
}

resource_name = {
"AWS Elastic Cache": "aws_elasticache_replication_group"

`
but when I run the encryption_at_rest and encryption_in_flight scenarios separately, the at_rest scenario works fine as expected and the in_flight scenario test always PASSED. so I tried to debug the steps.py and found that print statement shown below is always returning the at_rest_encryption_enabled, which is wrong
@then(u'encryption is enabled')
@then(u'encryption must be enabled')
def encryption_is_enabled(step_obj):
prop = encryption_property[step_obj.context.resource_type]
print('encryption property : '+prop)
step_obj.context.stash.property(prop).should_equal(True)

so I have commented the at_rest property as shown below and the test cases works as expected.

encryption_property = {
"aws_elasticache_replication_group": "transit_encryption_enabled"
#"aws_elasticache_replication_group": "at_rest_encryption_enabled"
}

so , this seems to be an issue ...please let me know if I am doing anything wrong here...thanks in advance!

ERROR: terraform-compliance thinks resource supports tag but doesn't.

Terraform:

resource "aws_lb_listener" "main" {
  load_balancer_arn = "${aws_lb.skeleton.arn}"
  port              = "${var.listener_port == "none" ? var.target_group_port : var.listener_port }"
  protocol          = "${var.listener_proto == "none" ? var.target_group_proto : var.listener_proto }"

  default_action {
    target_group_arn = "${aws_lb_target_group.skeleton.arn}"
    type             = "forward"
  }
}

Feature:

Feature: Resources should be properly tagged
  In order to keep track of resource ownership
  As engineers
  We'll enforce tagging on all resources

  Scenario: Ensure all resources have tags
    Given I have resource that supports tags defined
    Then it must contain tags

  Scenario Outline: Ensure that specific tags are defined
    Given I have resource that supports tags defined
    When it contains tags
    Then it must contain <tags>

Result:

    Scenario: Ensure all resources have tags
        Given I have resource that supports tags defined
        Then it must contain tags
          AssertionError: [aws_lb_listener.main] should have property: 'tags'

I think it should just skip this resource since it doesn't support tags, but terraform compliance fails the test.

Supported Python Version

Hi,

I have a question regarding which versions of Python are supported. I am new to Python so this may be a user/python issue on my side. I have Python3.7 installed. I am using Windows 10.

I installed terraform-compliance last week via pip. Install seemed to go fine yet when I tried to execute terraform-compliance -h I got the following error:

C:\Users\abc123>terraform-compliance -h
Traceback (most recent call last):
File "c:\python\python37\lib\runpy.py", line 193, in _run_module_as_main
"main", mod_spec)
File "c:\python\python37\lib\runpy.py", line 85, in run_code
exec(code, run_globals)
File "C:\Python\Python37\Scripts\terraform-compliance.exe_main
.py", line 5, in
File "c:\python\python37\lib\site-packages\terraform_compliance\main.py", line 12
print '{}ing {}..'.format(action, package)
^
SyntaxError: invalid syntax

I didn't find anything searching through the issues. It appears that this was caused by missing parentheses around the print arguments. I thought it was a bug so I added the parentheses in my local main.py file. I was able to get "terraform-compliance -h" working

I then tried to run a test and got the following error:

C:\Users\abs123>terraform-compliance -f /tmp/infrastructure-compliance/aws -t /Git-Repos/commonservices-tf
terraform-compliance v0.5.4 initiated
Steps : c:\python\python37\lib\site-packages\terraform_compliance\steps
Features : C:\tmp\infrastructure-compliance\aws
TF Files : C:\Users\abc123\AppData\Local\Temp\tmpla9jrki7 (/Git-Repos/commonservices-tf)
Reading terraform files.
All HCL files look good.
Running tests.
Error: Location 'c' to load modules does not exist

Traceback (most recent call last):
File "c:\python\python37\lib\site-packages\radish\errororacle.py", line 61, in _decorator
return func(*args, **kwargs)
File "c:\python\python37\lib\site-packages\radish\main.py", line 221, in main
return method(core)
File "c:\python\python37\lib\site-packages\radish\main.py", line 65, in run_features
load_modules(basedir)
File "c:\python\python37\lib\site-packages\radish\loader.py", line 22, in load_modules
raise OSError("Location '{0}' to load modules does not exist".format(location))
OSError: Location 'c' to load modules does not exist

I did some research and it looks like the version of radish installed was old and did not have a fix to correct a "split" issue when running on Windows. I was able to get around that installing radish-bdd from the source.

Now I try to run the test and get the following:

Error: Hook 'load_terraform_data' from c:\python\python37\lib\site-packages\terraform_compliance\steps\terrain.py:6 raised: 'NameError: name 'xrange' is not defined'

Traceback (most recent call last):
File "c:\python\python37\lib\site-packages\radish_bdd-0.11.1-py3.7.egg\radish\hookregistry.py", line 132, in call
func(model, *args, **kwargs)
File "c:\python\python37\lib\site-packages\terraform_compliance\steps\terrain.py", line 12, in load_terraform_data
enable_resource_mounting(tf_conf.terraform_config)
File "c:\python\python37\lib\site-packages\terraform_compliance\extensions\terraform_validate.py", line 29, in enable_resource_mounting
enable_resource_mounting(tf_conf, sub_value, sub_resource)
File "c:\python\python37\lib\site-packages\terraform_compliance\extensions\terraform_validate.py", line 29, in enable_resource_mounting
enable_resource_mounting(tf_conf, sub_value, sub_resource)
File "c:\python\python37\lib\site-packages\terraform_compliance\extensions\terraform_validate.py", line 37, in enable_resource_mounting
change_value_in_dict(tf_conf, target, {source: processing_resource})
File "c:\python\python37\lib\site-packages\terraform_compliance\common\helper.py", line 158, in change_value_in_dict
for x in xrange(0,len(path_to_change)):
NameError: name 'xrange' is not defined

It looks like xrange() is used in Python2 and range() is used in Python3.

So it looks to me like terraform-compliance requires Python2. Am I correct? Would installing Python 2 correct all the issues I had to work around before?

Also, if it requires Python2, are there any plans for support of Python3?

Sorry for the long question.

New step: Then it should FAIL

A new step is required to make the scenario FAIL directly unless the step is skipped already.

e.g. avoiding having any Security Groups ( just an example)

Given I have AWS Security Groups defined
Then it should fail

support resources with count parameter

For example if I had something like:

resource "aws_instance" "web" {
  instance_type = "m1.small"
  ami           = "${lookup(var.aws_amis, var.aws_region)}"

  # This will create 4 instances
  count = 4
}

terraform-compliance should be able to see or calculate the count parameter and factor that into the WHEN sum

aws_launch_configuration Resource is Marked as Supporting Tags

I have an autoscaling group with and aws_launch_configuration. When I run the test it fails stating the following:

Scenario Outline: Ensure that specific tags are defined
        Given I have resource that supports tags defined
        When it contains tags
        Then it must contain <tags>

    Examples:
        | tags |
        | Name |
          Failure: aws_launch_configuration.example (resource that supports tags) does not have Name property.

When I add tags to the aws_launch_configuration resource in terraform and try to . build the plan it gives an error:

$ terraform plan -out=plan.out

Error: Unsupported argument

  on main.tf line 50, in resource "aws_launch_configuration" "example":
  50:   tags = [

An argument named "tags" is not expected here.

It doesn't look like aws_launch_configuration resources supports tags.

security group must have rule for any port

Then it must not have <proto> protocol and port <portNumber> for 0.0.0.0/0
This will check for port with 0.0.0.0/0.
I don't want any port with public facing(0.0.0.0/0). I tried below, under the examples, but doesn't work.

| Any | tcp | 0 |

How to achieve this?

ModuleNotFoundError using Docker Image

I was trying to test out the new 1.0.0 version. I figured I would go the simple route and just use the docker image. When I run the instructions below (per the Usage instructions) I get the following.

$ function terraform-compliance { docker run --rm -v $(pwd):/target -i -t eerkunt/terraform-compliance "$@"; }
$ terraform-compliance -h
Unable to find image 'eerkunt/terraform-compliance:latest' locally
latest: Pulling from eerkunt/terraform-compliance
fc7181108d40: Pull complete
01f3b6f74410: Pull complete
d8e6069e053d: Pull complete
e6bd64ad4fe3: Pull complete
a034e22b86de: Pull complete
8731bd654de0: Pull complete
Digest: sha256:a53c917fd3c0f4ee3a7fdfe6a5a14d32410f01b99ba5a782520d17d2f9506486
Status: Downloaded newer image for eerkunt/terraform-compliance:latest
Traceback (most recent call last):
File "/usr/local/bin/terraform-compliance", line 6, in
from terraform_compliance.main import cli
File "/usr/local/lib/python3.6/site-packages/terraform_compliance/main.py", line 7, in
from terraform_compliance.common.readable_plan import ReadablePlan
File "/usr/local/lib/python3.6/site-packages/terraform_compliance/common/readable_plan.py", line 5, in
import filetype
ModuleNotFoundError: No module named 'filetype'

Is this an issue with the docker image? If not, please let me know if I may be missing anything on my MacBook.

Travis CI fails on pull requests from forks

If a user forks the repo and sends a PR from their master branch, because the branch name will seen as master in Travis, it fails on building.

It based on request type (pull_request, merge, etc) the CI process should occur.

hangs on malformed terraform code

Using terraform-compliance .48

If I have malformed terraform code for AWS (for instance, improper characters in a S3 bucket), terraform-compliance hangs indefinitely.

The code should detect the problem and give the appropriate error.

After the process has hung, the only thing I have found is to force a break. I'm not sure this will be helpful or not, but here is the trace after the break:

Executing terraform-compliance check...
c^C [ERROR]: User interrupted execution

Process WorkerProcess-8:
Traceback (most recent call last):
  File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/usr/local/Cellar/ansible/2.7.1/libexec/lib/python3.7/site-packages/ansible/executor/process/worker.py", line 118, in run
    self._final_q
  File "/usr/local/Cellar/ansible/2.7.1/libexec/lib/python3.7/site-packages/ansible/executor/task_executor.py", line 139, in run
    res = self._execute()
  File "/usr/local/Cellar/ansible/2.7.1/libexec/lib/python3.7/site-packages/ansible/executor/task_executor.py", line 603, in _execute
    result = self._handler.run(task_vars=variables)
  File "/usr/local/Cellar/ansible/2.7.1/libexec/lib/python3.7/site-packages/ansible/plugins/action/command.py", line 24, in run
    results = merge_hash(results, self._execute_module(task_vars=task_vars, wrap_async=wrap_async))
  File "/usr/local/Cellar/ansible/2.7.1/libexec/lib/python3.7/site-packages/ansible/plugins/action/__init__.py", line 839, in _execute_module
    res = self._low_level_execute_command(cmd, sudoable=sudoable, in_data=in_data)
  File "/usr/local/Cellar/ansible/2.7.1/libexec/lib/python3.7/site-packages/ansible/plugins/action/__init__.py", line 954, in _low_level_execute_command
    rc, stdout, stderr = self._connection.exec_command(cmd, in_data=in_data, sudoable=sudoable)
  File "/usr/local/Cellar/ansible/2.7.1/libexec/lib/python3.7/site-packages/ansible/plugins/connection/local.py", line 133, in exec_command
    stdout, stderr = p.communicate(in_data)
  File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 933, in communicate
    stdout, stderr = self._communicate(input, endtime, timeout)
  File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 1675, in _communicate
    ready = selector.select(timeout)
  File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/selectors.py", line 415, in select
    fd_event_list = self._selector.poll(timeout)
KeyboardInterrupt

Running terraform validate/apply on the code allows me to retrieve the problems (in this case, S3 buckets with bad characters) and fix them.

Custom Scenarion in encryption at rest feature throws AttributeError

Hi,
I wrote a custom Scenario shown below to test aws_emr_security_configuration encryption at rest
`Feature: Resources should use encryption at rest while they are created
In order to improve security
As engineers
We'll enforce encryption at rest

Scenario: AWS EMR Encryption at Rest
Given I have AWS EMR Security Configuration instance defined
When it contains configuration
Then encryption must be enabled`

main.tf
`resource "aws_emr_security_configuration" "foo" {
name = "emrsc_other"

configuration = <<EOF
{
"EncryptionConfiguration": {
"AtRestEncryptionConfiguration": {
"S3EncryptionConfiguration": {
"EncryptionMode": "SSE-S3"
},
"LocalDiskEncryptionConfiguration": {
"EncryptionKeyProviderType": "AwsKms",
"AwsKmsKey": "arn:aws:kms:us-west-2:187416307283:alias/tf_emr_test_key"
}
},
"EnableInTransitEncryption": false,
"EnableAtRestEncryption": true
}
}
EOF
}
when I run my test against the above template with my feature, I get AttributeError: 'str' object has no attribute 'keys' console outputRunning tests.
Feature: Resources should use encryption at rest while they are created # C:\Training\AWS\Cloud-CustomRules\Terraform-Compliance\rules\encryption_at_rest.feature
In order to improve security
As engineers
We'll enforce encryption at rest

Scenario: AWS EMR Encryption at Rest
    Given I have AWS EMR Security Configuration instance defined
    When it contains configuration
    Then encryption must be enabled
      AttributeError: 'str' object has no attribute 'keys'

1 features (0 passed, 1 failed)
1 scenarios (0 passed, 1 failed)
3 steps (2 passed, 1 failed)
Run 1556667708 finished within a moment
Cleaning up.`

Not sure what is wrong here, i guess may be I am not reading the EnableAtRestEncryption property correctly?

any help is appreciated. Thanks!

security group rule must take fromPort and toPort as input

Then it must not have <proto> protocol and port <portNumber> for 0.0.0.0/0 This will check for port with 0.0.0.0/0.

I don't want any port to not have 0.0.0.0/0 except some ports.

I should be able to give input as below,
| Any | tcp | 1000 | 65535 |
So that, if any port from 1000 to 65535 have access from/to 0.0.0.0/0 then terraform-compliance should identify them as issue.

Checking values within list variables

I'm having an issue at the moment where I have a module to create a resource that has a property named subnets, and expects a list. A cut-down example:

module "My-ASG" {
    subnets = ["${module.vpc.public_subnets}"]
}

I want to check that "${module.vpc.public_subnets}" is included in the list, so I have written a test like so:

Feature: Check ASG placements  
  Scenario: My-ASG Placement
    Given I have Admin-Server module configured
    When it contains subnets
    Then its value must match the "${module.vpc.public_subnets}" regex

But when I run this, I receive:

    Scenario: My-ASG Placement
      Given I have Admin-Server module configured
      When it contains subnets
      Then its value must match the "${module.vpc.public_subnets}" regex
          AttributeError: 'list' object has no attribute 'properties'

1 features (0 passed, 1 failed)
1 scenarios (0 passed, 1 failed)
3 steps (2 passed, 1 failed)

I had a quick look at the code and it looks like the @then(u'its value {condition:ANY} match the "{search_regex}" regex') step isn't designed to handle lists - however, in the feature/1.0.0 branch they look to be handled correctly.

Have I got this wrong? Is there a way to test that a list has specific values? If it doesn't currently work, is there an ETA on this feature?

Thanks!

ERROR: /hashicorp/terraform does not look like terraform

I am trying to use the 1.0.5 Docker image but I get the following error:

colon191818al:hashicorp abs123$ terraform-compliance -p /hashicorp/tc-test2/tf-template/plan.out -f /hashicorp/tc-test2/features -t /hashicorp/terraform
terraform-compliance v1.0.5 initiated

. Converting terraform plan file.
Using /hashicorp/terraform as terraform executable.
ERROR: /hashicorp/terraform does not look like terraform. Please give correct executable for "terraform".
[Errno 8] Exec format error: '/hashicorp/terraform'
colon191818al:hashicorp abs123$

I mapped the docker call to a function as follows:

colon191818al:hashicorp abs123$ function terraform-compliance { docker run -v $(pwd):/hashicorp -i -t eerkunt/terraform-compliance "$@"; }

Terraform was added to my .profile so I can execute from anywhere:

colon191818al:hashicorp abs123$ terraform -version
Terraform v0.12.2

colon191818al:hashicorp abs123$ ls -al
total 106056
drwxr-xr-x 9 abs123 COMPANY\Domain Users 288 Jun 24 17:28 .
drwxr-xr-x+ 39 abs123 COMPANY\Domain Users 1248 Jun 24 18:48 ..
drwxr-xr-x 5 abs123 COMPANY\Domain Users 160 Jun 24 17:58 tc-test2
-rwxrwxr-x@ 1 abs123 COMPANY\Domain Users 54228088 Jun 12 20:12 terraform

Is Terraform v0.12.2 supported?

Thanks in advance for your help.

more verbose error messages

when a test fails it would be useful to see for which resources the SG test fail, e.g EC2/EFS/ssh etc just like when ingress/egress is missing

Git authentication is not supported

Currently only public repositories are supported. A user/pass combination ( or an ssh-key ) combination is required to use private repos.

Of course, this means adding http(s) and ssh protocol capabilities.

No publicly open RDS Instances

New step is needed to identify there will not be any publicly open RDS instances will be created from terraform files.

New When condition: When its tags contains <key>

Example of use bellow:

  Scenario Outline: Ensure that the name tag must match project-env-app
    Given I have <resource_name> defined
    When its tags contains <name_key>
    Then its value must match the "\${var.project}-\${var.environment}-\${var.application}-.*" regex

    Examples:
    | resource_name           | name_key |
    | aws_vpc                 | Name     |
    | aws_route_table         | Name     |
    | aws_internet_gateway    | Name     |

SecurityGroup Feature:

Receiving a TypeError:

        | ProtocolName  | proto | portNumber |
        | HTTP          | tcp   | 80         |
          TypeError: string indices must be integers
        | Telnet        | tcp   | 23         |
          TypeError: string indices must be integers
        | SSH           | tcp   | 22         |
          TypeError: string indices must be integers
        | MySQL         | tcp   | 3306       |
          TypeError: string indices must be integers
        | MSSQL         | tcp   | 1443       |
          TypeError: string indices must be integers
        | NetBIOS       | tcp   | 139        |
          TypeError: string indices must be integers
        | RDP           | tcp   | 3389       |
          TypeError: string indices must be integers
        | Jenkins Slave | tcp   | 50000      |
          TypeError: string indices must be integers

when evaluating this resource:

resource "aws_security_group" "akamai-http" {
  name        = "${module.http_labels.id}"
  description = "Allow HTTP traffic inbound from Akamai"
  vpc_id      = "${data.aws_vpc.vpc.id}"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = "${concat("${var.secure_production_network}", "${var.secure_staging_network}")}"
  }

  tags = "${module.http_labels.tags}"

  lifecycle {
    ignore_changes = "description"
  }
}

removing the cidr_blocks declaration results in a passing test.

Python version environment?

No matter what I pass to terraform-compliance, I get the same error:

$ terraform-compliance -f terraform/tests -t terraform/es
Traceback (most recent call last):
File "/usr/local/bin/terraform-compliance", line 11, in
sys.exit(cli())
TypeError: cli() takes exactly 2 arguments (0 given)

... same with -h

Not sure if this is a python2/3 issue, or something else? I'm running on MacOSX High Sierra. I get this error from both the container and the pip installation.

Security Group feature: module with no security groups?

I have a set of resources that does not include a security group, but it seems to be triggering the example security groups feature. I end up with:

Feature: Security Groups should be used to protect services/instances  # /Users/demianginther/git/tf-modules/compliance/security_groups.feature
    In order to improve security
    As engineers
    We'll use AWS Security Groups as a Perimeter Defence

    Scenario Outline: Policy Structure
        Given I have AWS Security Group defined
        Then it must contain <policy_name>

    Examples:
        | policy_name |
        | ingress     |

    Scenario Outline: Well-known insecure protocol exposure on Public Network for ingress traffic
        Given I have AWS Security Group defined
        And it should contain ingress
        Then it must not have <proto> protocol and port <portNumber> for 0.0.0.0/0

    Examples:
        | ProtocolName  | proto | portNumber |
        | HTTP          | tcp   | 80         |
          AttributeError: TerraformResourceList instance has no attribute 'properties'
        | Telnet        | tcp   | 23         |
          AttributeError: TerraformResourceList instance has no attribute 'properties'
        | SSH           | tcp   | 22         |
          AttributeError: TerraformResourceList instance has no attribute 'properties'
        | MySQL         | tcp   | 3306       |
          AttributeError: TerraformResourceList instance has no attribute 'properties'
        | MSSQL         | tcp   | 1443       |
          AttributeError: TerraformResourceList instance has no attribute 'properties'
        | NetBIOS       | tcp   | 139        |
          AttributeError: TerraformResourceList instance has no attribute 'properties'
        | RDP           | tcp   | 3389       |
          AttributeError: TerraformResourceList instance has no attribute 'properties'
        | Jenkins Slave | tcp   | 50000      |
          AttributeError: TerraformResourceList instance has no attribute 'properties'

I get a pass on the 'ingress' check, meaning it's finding something it thinks is a security group. I assume I'm getting a missing attribute because there's not actually any properties in the instance of TerraformResourceList, because there weren't any properties to load the list with.

Tag Feature: Difficulty with a count variable

Having an issue here:

Feature: Resources should be properly tagged
  In order to keep track of resource ownership
  As engineers
  We'll enforce tagging on all resources

  Scenario Outline: Name tag
    Given I have resource that supports tags defined
    Then it must contain tags
    And it must contain <tags>

  Examples:
  | tags        |
  | Name        |

result:

terraform-compliance v0.4.11 initiated
Steps    : /usr/local/lib/python2.7/site-packages/terraform_compliance/steps
Features : /Users/demianginther/git/tf-modules/compliance
TF Files : /var/folders/zf/f1h382nn35z3gd1kv92bw6r80000gn/T/tmpxTN1V9 (.)
Reading terraform files.
All HCL files look good.
Running tests.
Feature: Resources should be properly tagged  # /Users/demianginther/git/tf-modules/compliance/tags.feature
    In order to keep track of resource ownership
    As engineers
    We'll enforce tagging on all resources
1 features (0 passed)
1 scenarios (0 passed)
3 steps (0 passed)
Run 1547251063 finished within a moment
Error: Hook 'load_terraform_data' from /usr/local/lib/python2.7/site-packages/terraform_compliance/steps/terrain.py:6 raised: 'SyntaxError: invalid syntax (<string>, line 1)'

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/radish/hookregistry.py", line 121, in call
    func(model, *args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/terraform_compliance/steps/terrain.py", line 12, in load_terraform_data
    enable_resource_mounting(tf_conf.terraform_config)
  File "/usr/local/lib/python2.7/site-packages/terraform_compliance/extensions/terraform_validate.py", line 29, in enable_resource_mounting
    enable_resource_mounting(tf_conf, sub_value, sub_resource)
  File "/usr/local/lib/python2.7/site-packages/terraform_compliance/extensions/terraform_validate.py", line 29, in enable_resource_mounting
    enable_resource_mounting(tf_conf, sub_value, sub_resource)
  File "/usr/local/lib/python2.7/site-packages/terraform_compliance/extensions/terraform_validate.py", line 37, in enable_resource_mounting
    change_value_in_dict(tf_conf, target, {source: processing_resource})
  File "/usr/local/lib/python2.7/site-packages/terraform_compliance/common/helper.py", line 119, in change_value_in_dict
    target = eval('target_dictionary{}'.format(path_to_adjust))
  File "<string>", line 1
    target_dictionary["resource"]["!var"]["alb_enabled && !var"]["double_elb_listener_enabled && var"]["env == "prod" ? 1 : 0"]
                                                                                                                   ^
SyntaxError: invalid syntax

Relevant Terraform code:

resource "aws_cloudwatch_metric_alarm" "elb_single_listener_unhealthy_host_count" {
  alarm_name          = "${var.app_group}-${var.app}-${var.env}-unhealthy-host-count"
  count               = "${!var.alb_enabled && !var.double_elb_listener_enabled && var.env != "prod" ? 1 : 0}"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "UnHealthyHostCount"
  namespace           = "AWS/ELB"
  period              = "60"
  statistic           = "Maximum"
  threshold           = "${var.unhealthy_host_count_threshold}"

  dimensions {
    LoadBalancerName = "${aws_elb.app_elb_single_listener.name}"
  }

  alarm_description = "${aws_elb.app_elb_single_listener.name} - unhealthy host alarm triggered"

  alarm_actions = ["${var.slack_sns_topic}"]
}

Any ideas?

1.0.4 version is not able to identify the encryption properties

Hi @eerkunt,

I was testing the encryption_at_rest.feature with AWS RDS Instance and found that the rule is able to read the aws_db_instance resource however its not able to read the storage_encrypted=false property. it says : Failure: Resource aws_db_instance.default does not have encryption enabled (storage_encrypted). even though I have that property configured in my out file.

`. Running tests.
Feature: Resources should use encryption at rest while they are created # C:\Training\cloud\terraform-compliance\1.0.4\terraform-compliance-master\example\example_01\aws\testing-inprogress\encryption_at_rest.feature
In order to improve security
As engineers
We'll enforce encryption at rest

Scenario: RDS instances
    Given I have AWS RDS instance defined
    Then encryption must be enabled
      Failure: Resource aws_db_instance.default does not have encryption enabled (storage_encrypted).`

I have attached the .tf , .out, and .out.json files for yur reference

aws_db_instance_encryption.zip

Cannot check tags

Hi,

Thanks for this usefull tool.
I tried to check the tags exist on resource but i got an error :

Feature: Resources should be properly tagged  # features/tags.feature
    In order to keep track of resource ownership
    As engineers
    We'll enforce tagging on all resources

    Scenario Outline: Name tag
        Given I have resource that supports tags defined
        Then it must contain tags
        And it must contain <tags>

    Examples:
        | tags        |
        | Name        |
          AssertionError: Name property in tags can not be found in sg-inf-vpc (aws_security_group). It is set to {u'Environment': u'${var.environment}', u'Name': u'inf-vpc-${var.environment}', u'level': u'VPC'} instead
        | Environment |
          AssertionError: Environment property in tags can not be found in sg-inf-vpc (aws_security_group). It is set to {u'Environment': u'${var.environment}', u'Name': u'inf-vpc-${var.environment}', u'level': u'VPC'} instead
        | level       |
          AssertionError: level property in tags can not be found in sg-inf-vpc (aws_security_group). It is set to {u'Environment': u'${var.environment}', u'Name': u'inf-vpc-${var.environment}', u'level': u'VPC'} instead

i cannot understand the error becose the tag are present.

Thanks for your assist.

Julien

Integration/E2E tests are required

Implement tests where will have multiple scenarios and tf files that will run on CI for every PR (or push).

This might require using tox.

Looks like we sometimes miss some cases after development

Implement terraform interpolations

Currently, some of the values cannot be parsed because there are some terraform interpolations there. In some cases, it might be impossible to retrieve the data ( e.g. using remote module outputs ).

At least there must be a method for general use for terraform interpolations. Then we can just iterate and add more support on iterations throughout the terraform lifecycle.

Terraform-compliance is not able to readd the variable values from vars.tf

Hi, I am new to Terraform and Terraform-compliance.
I have downloaded a sample Terraform template from Github and tried to run terraform-compliance test on it
here is my TF Template:

main.tf

resource "aws_security_group" "instance" {
  name = "terraform-example-instance"

  # Inbound HTTP from anywhere
  ingress {
    from_port = "${var.server_port}"
    to_port = "${var.server_port}"
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

vars.tf

variable "server_port" {
  description = "The port the server will use for HTTP requests"
  default = 8080
}

when I run terraform-compliance test, it throws me below error:

 Scenario Outline: Well-known insecure protocol exposure on Public Network for ingress traffic
        Given I have AWS Security Group defined
        When it contains ingress
        Then it must not have <proto> protocol and port <portNumber> for 0.0.0.0/0

    Examples:
        | ProtocolName  | proto | portNumber |
        | HTTP          | tcp   | 443        |
          ValueError: invalid literal for int() with base 10: '${var.server_port}'
        | Telnet        | tcp   | 23         |
          ValueError: invalid literal for int() with base 10: '${var.server_port}'
        | SSH           | tcp   | 22         |
          ValueError: invalid literal for int() with base 10: '${var.server_port}'
        | MySQL         | tcp   | 3306       |
          ValueError: invalid literal for int() with base 10: '${var.server_port}'
        | MSSQL         | tcp   | 1443       |
          ValueError: invalid literal for int() with base 10: '${var.server_port}'
        | NetBIOS       | tcp   | 139        |
          ValueError: invalid literal for int() with base 10: '${var.server_port}'
        | RDP           | tcp   | 3389       |
          ValueError: invalid literal for int() with base 10: '${var.server_port}'
        | Jenkins Slave | tcp   | 50000      |
          ValueError: invalid literal for int() with base 10: '${var.server_port}'

    Scenario: No publicly open ports
        Given I have AWS Security Group defined
        When it contains ingress
        Then it must not have tcp protocol and port 1024-65535 for 0.0.0.0/0
          ValueError: invalid literal for int() with base 10: '${var.server_port}'

does this error means that terrafform-compliance is not able to read the variable values from the vars.tf?

can anybody help me resolve this issue please?

Thanks!

Support for Standalone aws_security_group_rule Resource

Hi,

I see that the code was recently updated to handle a security group rule defined within a an aws_security_group resource.

Is there any way to handle a standalone aws_security_group_rule, which effectively has the same keys as the nested security group rule within an aws_security_group resource.?

ERROR: terraform-compliance -h

Traceback (most recent call last):
File "/usr/local/bin/terraform-compliance", line 7, in
from terraform_compliance.main import cli
File "/usr/local/lib/python2.7/dist-packages/terraform_compliance/main.py", line 3, in
from radish.main import main as call_radish
File "/usr/local/lib/python2.7/dist-packages/radish/main.py", line 12, in
from . import VERSION
ImportError: cannot import name VERSION

State/Variable/Value Storing among Scenarios/Tests

Store it like

    Given I have AWS ELB resource defined
    When it contains internal
    Then store this resource as aws_public_elb

Then retrieve it like ;

     Given I have aws_public_elb stored
     When it contains ....
     Then ....

Examples might differ.

  • Storage must be based on Feature, so multiple Scenarios can use each other.
  • Maybe radish-bdd already has this kind of a feature ?
  • Storage must be extendable - based on some overwrite flags maybe ? - where same variable might be used several times to create a list.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.