DoTheGenes
DoTheGenes

Reputation: 197

Terraform .tfvars cast decoding error

I'm trying to set up something really simple with Terraform, but it gives me an error I haven't seen before.

When I run terraform validate -var-file=secrets.tfvars I get the following error:

Error loading files open /home/MYUSER/Documents/git/packer-with-terraform/terratest/-var-file=secrets.tfvars: no such file or directory

And when I run terraform plan -var-file=secrets.tfvars I get this:

invalid value "secrets.tfvars" for flag -var-file: Error decoding Terraform vars file: At 1:10: root.variable: unknown type for string *ast.ObjectList

I have three files within the same folder, and their content is minimal:

providers.tf

provider "aws" {
    region                      = "us-west-1"
    access_key                  = "${var.access_key}"
    secret_key                  = "${var.secret_key}"
}

main.tf

resource "aws_instance" "master_proxy" {
    ami                         = "ami-123sample"
    instance_type               = "t2.micro"
}

secrets.tfvars

variable "access_key" { default = "sampleaccesskey" }
variable "secret_key" { default = "samplesecretkey" }

If I set access_key and secret_key directly, and not via variables, then it works. A similar setup with secrets-files and whatnot works on another project of mine; I just don't understand what's wrong here.

Upvotes: 3

Views: 1765

Answers (3)

Samuel
Samuel

Reputation: 31

     # Set a Provider
    provider "aws" {
      region     = "${var.region}"
      access_key = "${var.access_key}"
      secret_key = "${var.secret_key}"
    }

    resource "aws_security_group" "test-server-sg" {
      name = "test-server-sg"

      ingress {
        from_port   = 8080
        to_port     = 8080
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      }
    }

    resource "aws_instance" "test-server" {
      ami           = "${var.ami}"
      instance_type = "${var.instance_type}"

      user_data = <<-EOF
                  #!/bin/bash
                  echo "Hello, World" > index.html
                  nohup busybox httpd -fp 8080 &
                  EOF

      tags {
        name        = "Test Web Server"
        environment = "${var.environment}"
        project     = "${var.project}"
      }
    } 


     variable "region" {
      type        = "string"
      description = "AWS region"
    }

    variable "access_key" {
      type        = "string"
      description = "AWS access key"
    }

    variable "secret_key" {
      type        = "string"
      description = "AWS secret key"
    }

    variable "ami" {
      type        = "string"
      description = "AWS image id"
    }

    variable "instance_type" {
      type        = "string"
      description = "AWS instance type"
    }

    variable "environment" {
      type        = "string"
      description = "AWS environment name"
    }

    variable "project" {
      type        = "string"
      description = "AWS project name"
    }



    output "Test Server Public DNS" {
      value = "${aws_instance.test-server.public_dns}"
    }

    output "Test Server Public IP" {
      value = "${aws_instance.test-server.public_ip}"
    }

    region = "us-east-1"
    access_key = "put your aws access key here"
    secret_key = "put your aws secret key here"
    ami = "ami-40d28157"
    instance_type = "t2.micro"
    environment = "Test"
    project = "Master Terraform"

Upvotes: 0

ydaetskcoR
ydaetskcoR

Reputation: 56987

Firstly, terraform validate validates a folder of .tf files to check that the syntax is correct. You can't pass a separate vars file to the command. In fact, terraform validate won't even check your variables are even set properly.

Secondly, your secrets.tfvars file is using the wrong syntax. Instead you want it to look more like this:

secrets.tfvars:

access_key = "sampleaccesskey"
secret_key = "samplesecretkey"

But this will error because you haven't actually defined the variables in a .tf file:

providers.tf

variable "access_key" { default = "sampleaccesskey" }
variable "secret_key" { default = "samplesecretkey" }

provider "aws" {
    region                      = "us-west-1"
    access_key                  = "${var.access_key}"
    secret_key                  = "${var.secret_key}"
}

If you don't have a sensible default for a variable (such as typically in this case) then you can remove the default argument to the variable and this will make Terraform error on the plan because a required variable is not set:

providers.tf

variable "access_key" {}
variable "secret_key" {}

provider "aws" {
    region                      = "us-west-1"
    access_key                  = "${var.access_key}"
    secret_key                  = "${var.secret_key}"
}

Upvotes: 2

DoTheGenes
DoTheGenes

Reputation: 197

Well, I messed up big time. I somehow managed to forget the supposed structure (and difference) of *.tf and *.tfvars files.

For those who might run into a similar problem later on:

  • *.tf files are for configuration and declaration, which means that any variables must be defined within a *.tf file.
  • *.tfvars files are for giving values to already defined variables. These files can be passed with the -var-file flag (which I had misused).

Upvotes: 0

Related Questions