Home > Back-end >  How to pass variable from jenkins to terraform
How to pass variable from jenkins to terraform

Time:06-19

I created a small project on GitHub with which I create an ec2 with tomcat on aws and assign it the policies relating to port 8080. Now I would like to take a small step forward and

  1. wait for the server to be active to be able to copy files
  2. copy some sample files (such as index.html a jpg) in the Tomcat ROOT folder.

The problem is that I can't pass the PEM file to the terraform part of the code. I saw some examples that put the PEM file on the git repository but I don't want to do this and I uploaded the PEM file in the Jenkis credentials. What is the correct way to "wait" for the server to be ready and then copy the files?

Jenkins:

environment {

    AWS_ACCESS_KEY_ID     = credentials('AWS_ACCESS_KEY_ID')
    AWS_SECRET_ACCESS_KEY = credentials('AWS_SECRET_ACCESS_KEY')
    USER_KEYPEM      = credentials("AWS_USER_KEY_PEM")
}

terraform side

resource "aws_instance" "web1" {
   ami           = "${lookup(var.ami_id, var.region)}"
   instance_type = "t2.micro"
   vpc_security_group_ids = ["sg-XXXXXXXXX"]

    tags = {
    Name = "myFirstWebServer"
  }

    provisioner "remote-exec" {
    inline = [
      "cloud-init status --wait"
    ]
  }
    provisioner "file" {
    source      = "web/index.html"
    destination = "/path_to_tomcat_root/index.html"
  }
    provisioner "file" {
    source      = "web/img.jpg"
    destination = "/path_to_tomcat_root/img.jpg"
  }

    connection {
    user        = "ec2-user"
    private_key = "?????????"    <-----how to pass pem file from Jenkins credentials?
    host = "${aws_instance.web1.public_ip}"
  }

CodePudding user response:

I would try using the built-in mechanism for assigning values to variables using environment variables which have to start with TF_VAR_ [1]. So, in your case, I would first define a variable in the Terraform code:

variable "private_key" {
  type = string
  description = "SSH private key for accessing the EC2 instance."
}

In the EC2 instance resource, the change you would have to make is only in the connection block:

resource "aws_instance" "web1" {
.
.
.
    connection {
    user        = "ec2-user"
    private_key = var.private_key # this is where you have to make the change
    host = "${aws_instance.web1.public_ip}"
  }
}

Then, in Jenkins, I would rename the variable USER_KEYPEM to TF_VAR_private_key. Note that you should export the value of the variable TF_VAR_private_key so it is picked up by Terraform [2]. Finally, run plan and apply steps without the need to specify any values on the CLI:

sh "pwd; cd terraform/myfolder; export TF_VAR_private_key; terraform plan -input=false -out tfplan"

[1] https://www.terraform.io/cli/config/environment-variables#tf_var_name

[2] https://www.terraform.io/language/values/variables#environment-variables

CodePudding user response:

tnx for your support Marko. I did what you suggest but i still receive this error

aws_instance.web1: Creating...[0m[0m
aws_instance.web1: Still creating... [10s elapsed][0m[0m
aws_instance.web1: Still creating... [20s elapsed][0m[0m
aws_instance.web1: Still creating... [30s elapsed][0m[0m
aws_instance.web1: Still creating... [40s elapsed][0m[0m
aws_instance.web1: Provisioning with 'remote-exec'...[0m[0m
remote-exec provisioner error with aws_instance.web1,
  on aws-instance-example.tf line 10, in resource "aws_instance" "web1":
  provisioner "remote-exec" Failed to read ssh private key: no key found

Maybe the problem is in the method, the original one is

 connection {
    user        = "ec2-user"
    private_key = "${file("${var.private_key_path}")}"
      host = "${aws_instance.web-server.public_ip}"
  }

so the variable was the path to the PEM file , and private _key receive ${file(path)}. I added the file PEM in jenkins, maybe I must use a different way? or I can put in jenkins pem file as string?

  • Related