0
votes

As part of my Jenkinsfile, i am trying to load the secret file i have on my Jenkins machine and use it as a variable to pass into my terraform script. This terraform script is ssh'ing onto my newly provisioned ansible server and generating an Ansible inventory. The problem is loading the private key file into the terraform script as a variable to create the ssh connection from my ephemeral build in Jenkins.

As you can see the load the crediential and store in a terraform var (TF_VAR_private_key) but i am then having trouble loading it into my main.tf terraform script.

Any suggestions or help much appreciated.

Jenkinsfile

stages {
    stage('Provision Infrastructure') {
        steps {
            // credentialsId loading private key and storing in var
            withCredentials([file(credentialsId: 'ec2user.pem', variable: 'TF_VAR_private_key'),
            [
                $class           : 'AmazonWebServicesCredentialsBinding',
                credentialsId    : "aws_credentials",
                accessKeyVariable: 'AWS_ACCESS_KEY_ID',
                secretKeyVariable: 'AWS_SECRET_ACCESS_KEY'
            ]])
            { sh """               
                terraform version
                cd ${TERRAFORM_DIR}
                terraform init
                terraform plan
                terraform apply -input=false -auto-approve
            """ }
        }
    }

main.tf

resource "null_resource" "inventories" {

  triggers {
    template = "${template_file.inventory.rendered}"
  }
  connection {
    type = "ssh"
    host = "${element(aws_instance.ansible.*.private_ip, 0)}"
    user = "ec2-user"
    private_key = "${file("${var.private_key}")}"
    agent = false
    timeout = "1m"
  }

  provisioner "remote-exec" {
    inline = [
      "echo '${template_file.inventory.rendered}' > /tmp/inventory"
    ]
  }
}

Error:

Can't run remote-exec as private key file not found.

1
Why not use the -var flag?Matt Schuchard
I bet it's because Jenkins isn't passing that env var to Terraform. Have you tried injecting the env var into the build step?KJH

1 Answers

1
votes

I tried a few ways, this is what works:

Jenkinsfile

withCredentials([sshUserPrivateKey(
    credentialsId: 'e4dd944e-5fef-4109-801c-b478d41af2d7',
    keyFileVariable: 'SSH_KEY')])
{
    sh 'cp "$SSH_KEY" files/jenkins-aws.pem'
    sh 'terraform plan -out tfplan'
}

You need to copy the credentials file to some place terraform can access within the workspace. Then use it normally within your terraform:

main.tf

variable "ssh_private_key_file" {
  default = "files/jenkins-aws.pem"
}

locals {
  ssh_private_key_content = file(var.ssh_private_key_file)
}