Code Monkey home page Code Monkey logo

terraform-generator's People

Contributors

ahzhezhe avatar dependabot[bot] avatar giveadamakick avatar phjardas avatar wfuing 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

Watchers

 avatar  avatar  avatar

terraform-generator's Issues

Comments

Ability to add comments to generated code, such as "DO NOT EDIT THIS FILE IT IS GENERATED" would be very useful

Yes, we are adding comments externally through shell scripts, which is less than ideal.

Passing an object to fn generates an invalid terraform file

Describe the bug
Passing a JSON object to fn('myFunc', JsonObj) would generate an invalid JSON using v5.0.2.

To reproduce

tfg.resource('aws_iam_role', 'my_aws_iam_role', {
  assume_role_policy: fn('jsonencode', {
    Version: '2012-10-17',
    Statement: [{
      Resource: '*',
      Action: '*',
      Effect: 'Allow',
    }],
  }),
})

Expected behavior
The above produces an invalid output like:

resource "aws_iam_role" "my_aws_iam_role" {
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement {
      Resource = "*"
      Action = "*"
      Effect = "Allow"
    }
  })
}

When the expected valid output should be:

resource "aws_iam_role" "my_aws_iam_role" {
  assume_role_policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [{
      "Resource": "*",
      "Action":  "*",
      "Effect":  "Allow"
    }]
  })
}

Additional context
I think this is a critical feature if someone ought to build a .tf using a generator, but this seems to be missing from this package. A workaround right now is to provide a string e.g; MY_POLICY instead of the JSON (as an argument) to fn and then do something like tfg.generate().tf.replace('"MY_POLICY"', JSON.stringify(myPolicyJson)) to make it work. But that seems to be a headache and messes with the structure of the code.

Map values generated as blocks instead of variable assignment

Describe the bug

When adding variable values with TerraformGenerator.addVars, the generated tfvars do not format map types properly; they end up formatted as an object block instead.

To reproduce

An example in the console:

$ node
> const { TerraformGenerator } = require('terraform-generator');
> const tfg = new TerraformGenerator({ required_version: '>= 0.12' });
> tfg.addVars({ intval: 5432, strval: "whoop", listval: ["alpha", 'bravo', `charlie`], mapval: {key:"foo",key2:"bar"} });
> console.log(tfg.generate().tfvars)
intval = 5432

strval = "whoop"

listval = [
"alpha",
"bravo",
"charlie"
]

mapval {
key = "foo"
key2 = "bar"
}

Expected behavior
Would expect map values to be formatted as a map assigned to a variable name:

// this is valid for tfvars definition
mapval = {
  key = "foo"
  key2 = "bar"
}
// this evidently is not
mapval {
  key = "foo"
  key2 = "bar"
}

Additional context

Using:

  • Mac OS 10.15.7 (Darwin 19.6.0 Darwin Kernel Version 19.6.0: Tue Jun 22 19:49:55 PDT 2021; root:xnu-6153.141.35~1/RELEASE_X86_64 x86_64 i386)
  • Terraform v1.0.7
  • nvm 0.36.0
  • npm 6.14.13
  • node v14.17.0
  • terraform-generator 5.1.0

Thank you for this extremely useful npm module!

Error generating nested options when using the TerraformGenerator class

Describe the bug
When initializing the Terraform generator with const tfg = new TerraformGenerator({ }}, I tried to pass in a required_providers option for AWS which looks something like this:

const tfg = new TerraformGenerator({
 required_version: '>= 1.2.0',
 required_providers: {
  aws: {
   source: 'hashicorp/aws',
   version: "~> 4.16"
  }
 }
})

The aws option did not render well in the resulting terraform.tf file. This is what I got:

terraform {
  required_version = ">= 1.2.0"
  required_providers {
    aws {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }
}

To reproduce

  1. Scaffold a mordern Sails.js application with npx create-sails <project-name> and complete the prompts to choose which frontend to build your app with(Vue in my case).
  2. cd into the new directory and run npm i.
  3. Run npm i terraform-generator to install the package.
  4. Run the helper generator with sails generate helper <helper-name> to generate a test helper to run the Terraform generator.
  5. Replace the contents of the file with the following code snippet.
const { TerraformGenerator } = require('terraform-generator')
const path = require('path')

module.exports = {


  friendlyName: 'Generate terraform config',


  description: 'Generate vendor-specific terraform configurations',


  inputs: {

  },


  exits: {

    success: {
      description: 'All done.',
    },

  },


  fn: async function (inputs, exits) {
    try {
      const tfg = new TerraformGenerator({
        required_version: '>= 1.2.0',
        required_providers: {
          aws: {
            source: 'hashicorp/aws',
            version: "~> 4.16"
          }
        }
      })
  
      tfg.provider('aws', {
        region: 'us-west-2'
      })
  
      tfg.resource('aws_instance', 'app_server', {
        ami: 'ami-08d70e59c07c61a3a',
        instance_type: 't2.micro'
      })
  
      // Write the configuration into a terraform.tf file
      const outputDir = path.join('terraform', 'configs');
      tfg.write({ dir: outputDir, format: true });
      return exits.success('Configuration generated successfully...')

    } catch (error) {
      console.log(error)
    }
  }

};
  1. Open the directory from the terminal and enter into console mode with the sails console command.
  2. Run the await sails.helpers.<name-of-helper-in-camelcase>. So if the helper filename is generate-terraform-config.js, you'd have your command as await sails.helpers.generateTerraformConfig().
  3. The generated file should contain the supposed bug.

This issue may not be platform specific but the summary of the complaint is that nested options in the TerraformGenerator class do not render properly.

Expected behavior
According to the Terraform docs, the aws option is supposed to render with a = as such:

terraform {
  required_version = ">= 1.2.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }
}

Additional context
Add any other context about the problem here.

Import is not working by Readme manual

Describe the bug
import TerraformGenerator, { Resource, map, fn } from 'terraform-generator';
^^^^^^

SyntaxError: Cannot use import statement outside a module
To reproduce
Follow Readme instructions
Expected behavior
Import completes successfully

Additional context
Tried to rename the file from .js to .mjs
Tried to add "type": "module" to package.json
Tried to add parameter --experimental-modules from cli
Node v12.14.1

Tag blocks are malformed

generated tag objects are formatted as

tags {
    foo = "bar"
} 

instead of
tags = {
foo = "bar"
}

This throws an error since Terraform v1

I wouldn't be surprised if other other objects are also malformed ( eg dynamic blocks, null resources etc )

in-built Terraform file function isn't recognized

Describe the bug
The in-built Terraform file function isn't recognized. When it is used in a resource like shown below, a reference error is thrown.

To reproduce

tfg.resource('spinnaker_pipeline', 'deploypipeline', {
    application: `spinnaker_appication.myservice.application`,
    name: 'deploy',
    pipeline: file('resources/rollback.json')
  });

Throws this error:

pipeline: file('resources/rollback.json')
              ^
ReferenceError: file is not defined

Expected behavior
I would have expected the file function to be recognized.

Additional context
Add any other context about the problem here.

Terraform Configuration is failing when provisioner added to resource

Describe the bug
Terraform Configuration is failing when provisioner added to resource

To reproduce
1.Add provisioner to resource based on terraform doc
2.try to create terraform config

My code:

tfg.resource("aws_instance","example",{
  ami:"ami-042b34111b1289ccd",
  instance_type:"t2.micro"
},tfg.provisioner("local-exec",{
    command:"echo The server's IP address is self.private_ip"
  })
);

Error response:


node_modules/terraform-generator/dist/blocks/Block.js:90
this.innerBlocks.forEach(block => {
^

TypeError: this.innerBlocks.forEach is not a function


Expected behavior
Terraform configuration should create without any issues

Additional context

"lcoals" should be "locals"

The code:

  tfg.locals({
    foo: 'bar',
  });

produces:

lcoals {
  foo = "bar"
}

Expected behavior

locals {
  foo = "bar"
}

Using tags inside resources not output correctly, missing "=" operator

Describe the bug
I notice when I use tags inside the resources and then generate the Terraform template using the .write , the tags will become tags {} and I believe it should be tags = {}

Here the full example:

import { TerraformGenerator} from 'terraform-generator';
const generator = new TerraformGenerator();

generator.resource('aws_instance', 'example_instance', {
    ami: 'ami-example', 
    instance_type: 't2.micro',
    key_name: 'example_key', 
    tags: {
        Environment: 'Production',
        Application: 'TestingApps',
    },
    iam_instance_profile: 'example_instance_profile', // replace with the name of your IAM instance profile
});

generator.write({
    dir: '.',
    format: true
})

And here is the output:

resource "aws_instance" "example_instance" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  key_name      = "example_key"
  tags {
    Environment = "Production"
    Application = "TestingApps"
  }
  iam_instance_profile = "example_instance_profile"
}

Expected behavior
And I believe the output should be something like:

resource "aws_instance" "example_instance" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  key_name      = "example_key"
  tags          = {
    Environment = "Production"
    Application = "TestingApps"
  }
  iam_instance_profile = "example_instance_profile"
}


Additional context
Then I also try to output it and print on my terminal using console.log i notice that the = is also misising. Here example of code i used;

//assume continue the above code. 
let result = generator.generate()
console.log(result.tf);

and here the output:

resource "aws_instance" "example_instance"{
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
key_name = "example_key"
tags {
Environment = "Production"
Application = "TestingApps"
}
iam_instance_profile = "example_instance_profile"
}

Variables with type constraints generate a warning with terraform cli 1.5.7

import {TerraformGenerator, map} from 'terraform-generator'

const tf = new TerraformGenerator()
tf.provider(
  'example'
, {
    key: tf.variable('var1', {type: 'string'}, 'KEY')
  }
)
tf.write({dir: '/tmp/repro/', pretty: false})
> cd /tmp/repro
➜  repro  
> terraform validate
╷
│ Error: Invalid quoted type constraints
│
│   on terraform.tf line 2, in variable "var1":
│    2: type = "string"
│
│ Terraform 0.11 and earlier required type constraints to be given in quotes, but
│ that form is now deprecated and will be removed in a future version of Terraform.
│ Remove the quotes around "string".
╵
> cat terraform.tf
variable "var1"{
type = "string"
}

provider "example"{
key = var.var1
}

If you use pretty output, it gets reformatted in a way that removes the message.

> terraform fmt
terraform.tf
> cat terraform.tf
variable "var1" {
  type = string
}

provider "example" {
  key = var.var1
}

Interpolation-only expressions being deprecated

Describe the bug
Perhaps I am missing something but no matter what I try, I cannot get terraform generator to generate Arrays without double quotes for Interpolation-only expressions being deprecated. The terraform-generator module seems to indicate support for current version of terraform. Is this supported?

To reproduce

const gobject = new String(`okta_group.group_${objName}.id`)
groupArray.push(`${gobject}`)

tfg.resource('okta_group_rule', `rule_${objName}`, {
  name: `${record.name}`,
  status: "ACTIVE",
  group_assignments: groupArray,
  expression_type: record.conditions.expression.type,
  expression_value: record.conditions.expression.value
});

groupArray will appear as

resource "okta_group_rule" "rule_deptSecurity" {
  name   = "dept: Security"
  status = "ACTIVE"
  group_assignments = [
    "okta_group.group_Security.id"
  ]
  expression_type  = "urn:okta:expression:1.0"
  expression_value = "user.department==\"Security\""
}

Logging to console shows no quotes but soon as generate resource using terraform-generator, quotes are added back.

Expected behavior
for newer versions of terraform, generate TF without the double quotes.

resource "okta_group_rule" "rule_deptSecurity" {
  name   = "dept: Security"
  status = "ACTIVE"
  group_assignments = [
    okta_group.group_Security.id
  ]
  expression_type  = "urn:okta:expression:1.0"
  expression_value = "user.department==\"Security\""
}

Additional context

Terraform 0.11 and earlier required all non-constant expressions to be
provided via interpolation syntax, but this pattern is now deprecated. To
silence this warning, remove the "${ sequence from the start and the }"
sequence from the end of this expression, leaving just the inner expression.

Template interpolation syntax is still used to construct strings from
expressions when the template includes multiple interpolation sequences or a
mixture of literal strings and interpolations. This deprecation applies only
to templates that consist entirely of a single interpolation sequence.

terraform value from tfg.generate().tf is not pretty

Describe the bug
Terraform value from tfg.generate().tf is not pretty

To reproduce

const tfg = new TerraformGenerator();
tfg.provider('aws', {
  region: 'ap-southeast-1'
});

tfg.generate().tf return bellow

terraform {
required_providers {
aws = "3.3.0"
}
}

provider "aws" {
region = "ap-southeast-1"
}

Expected behavior

terraform {
  required_providers {
    aws = "3.3.0"
  }
}

provider "aws" {
  region = "ap-southeast-1"
}

Question: How does one use a keyword when adding a variable?

I have some variable I want to generate, defined like so:

variable "my_var" {
  type        = string
  description = "This is my variable."
}

How do I set the type = string in terraform-generator?

I don't see a way to do so; I only see ways to pass in arguments as js types (i.e. a string, number, etc) and not a keyword.

what I am looking for is something like the following:

const myTerraformGenerator = new TerraformGenerator();
myTerraformGenerator.variable('my_var', {
  type: escapeToKeyword('string'),
  description: 'This is my variable'
})

Repeated blocks

Describe the bug
I would like to create an s3 bucket with multiple cors blocks

resource "aws_s3_bucket" "my-bucket" {
  bucket = "my-bucket"
  cors_rule {
    allowed_headers = [
      "Authorization",
    ]
    allowed_methods = [
      "GET",
    ]
    allowed_origins = [
      "*",
    ]
    expose_headers  = []
    max_age_seconds = 3000
  }
  cors_rule {
    allowed_headers = [
      "*",
    ]
    allowed_methods = [
      "PUT",
    ]
    allowed_origins = [
      "*",
    ]
    expose_headers  = []
    max_age_seconds = 0
  }

To reproduce

tfg.resource("aws_s3_bucket", "my-bucket", {
    bucket: "my-bucket",
    
    cors_rule: {
        allowed_headers: ["*"],
        allowed_methods: ["PUT"],
        allowed_origins: ["*"],
        expose_headers: [],
        max_age_seconds: 0,
    },
    cors_rule: {
        allowed_headers: ["Authorization"],
        allowed_methods: ["GET"],
        allowed_origins: ["*"],
        expose_headers: [],
        max_age_seconds: 3000,
    }
})

Expected behavior
This only creates 1 block

Additional context

write issue on environment variables

When trying to add environment details for a function, the terraform file that is being generated it doesnt add the = sign.
ex:

 tfg.resource('aws_lambda_function', lambdaName, {
...
environment: { 
                                variables: { 
                                    environment: "${var.environment}"
                                }
                            }
}

Results to:

resource "aws_lambda_function" "someName" {
...
environment {
variables {
environment = var.environment
}
}
}

As you can see above.. variables should be followed by an = sign

bad variable type translation

Describe the bug

  const pass = tf.variable('config', {
    type: [new Map({key:'string', val: 'string'})], default: [{key:'some',val:'default'}]
  }, [{key:'ex', val:'pass'}))

translates to:

variable "config" {
  type = [
    {
      key = "string"
      val = "string"
    }
  ]
  default {
    key = "some"
    val = "default"
  }
}

I tried to put it within quotes, but then terraform failed with:

19, in variable "config":
  19:   type = "list(object({ key  = string val = string }))"

The legacy variable type hint form, using a quoted string, allows only the
values "string", "list", and "map". To provide a full type expression, remove
the surrounding quotes and give the type expression directly.

which seems to point to a possible bug with type "number" ...
To reproduce

  const pass = tf.variable('config', {
    type: [new Map({key:'string', val: 'string'})], default: [{key:'some',val:'default'}]
  }, [{key:'ex', val:'pass'}))
console.log(tf.generate().tf)

Expected behavior
should print:

variable "config" {
  type = list(object({key = string val = string }))
  default = [{key:'some',val:'default'}]
}

Convert input file resource to data source

hey i'm trying to import an existing terraform file so I can do some manipulation on it dynamically using your library.

I'm trying to understand this import:
import { vpc as vpcDS } from 'other-terraform-project';

can you be more specific with how the 'other-terraform-project' is supposed to work?

Currently, I used your cidr example to generate a output/dev/subnets/terraform.tf file and I have another ts that is trying to import that generated file

fs.readFile(path.join('input', configs.env, 'subnets', "terraform.tf"), (err, data) => {
  if (err) throw err;
  console.log(data.toString());
  tfg.dataFromResource(data.toString(), null, ['cidr_block', ['tags', 'tag']]);
})

It is failing the first argument in the function dataFromResource which is type resource. I'm using a string. So it makes sense to me that it is failing.

Is this possible?

variable types are no longer supported with double quotes from terraform.

When defining a variable like the below:
tfg.variable("region", { type: 'string' });

The output in the file generated is:
variable "region" { type = "string" }

The problem here is that with the latest terraform update it is expecting the type value to be without the double quotes (ex. instead of type="string" => type=string) hence when executing terraform, it failing.

Similar issue (not blocking from terraform yet but with warnings) is happening also to the resources. For example when you define ${data.api_gatewayv2_api.myresource.id} as a value for a field, the output will create the file with quotes again field = "data.api_gatewayv2_api.myresource.id" and terraform is complaining again about the quotes.

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.