Anu
Anu

Reputation: 151

terraform v0.12.21 throws "Failed to read ssh private key: no key found"

Not able to connect to ec2 instance from terraform. The same key pair works if I create the ec2 instance manually (not via terraform). That confirms my key-pair is correct. Here is the code that I'm trying to do. The error I get: `aws_instance.ec2_test_instance: Provisioning with 'remote-exec'...

Error: Failed to read ssh private key: no key found

Error: Error import KeyPair: MissingParameter: The request must contain the parameter PublicKeyMaterial status code: 400, request id: `

resource "aws_instance" "ec2_test_instance" {
  ami           = var.instance_test_ami
  instance_type = var.instance_type
  subnet_id     = var.aws_subnet_id
  key_name      = aws_key_pair.deployer.key_name

  tags = {
    Name = var.environment_tag
    }
  connection {
    type    = "ssh"
    host    = self.public_ip
    user    = "centos"
    private_key   = "file(path.root/my-key)"
    }
   provisioner "remote-exec" {
    inline = [
        "sudo yum -y install wget, unzip",
        "sudo yum -y install java-1.8.0-openjdk",
        ]
    }

Upvotes: 1

Views: 4416

Answers (2)

pr0b3r7
pr0b3r7

Reputation: 11

Documentation for terraform file function helped and this answer from this same thread helped me.

In my case I was receiving the same error when setting the connection block for a remote-exec and file function that copied a script and ran it after provisioning an AWS instance. Here's an example snippet of the resource block:


    resource "local_file" "my_script" {
      content  = <<-EOT
    #!/bin/bash
    
    echo "Hello World"
    
    EOT
      filename = "${path.root}/my_script.sh"
    }
    
    
    resource "aws_instance" "aws_instance_name" {
      ami                         = var.aws_instance_AMI
      instance_type               = var.aws_instance_type
      key_name                    = var.aws_key_variable_name
      vpc_security_group_ids      = [aws_security_group.aws_instance_sg.id]
      count                       = 3
      subnet_id                   = var.subnet_variable                            
      private_ip                  = var.list_private_ips_aws_instance[count.index]
      associate_public_ip_address = true
    
    
    provisioner "file" {
        source      = local_file.my_script.filename
        destination = "/tmp/my_script.sh" # Destination path on the instance
        connection {
          host        = self.public_ip # Use the public IP address of the instance
          type        = "ssh"
          user        = var.ansible_become_user
          private_key = file("${var.aws_key_variable_name}.pem")
        }
      }
    
      # Use the remote-exec provisioner to run the script
      provisioner "remote-exec" {
        inline = [
          "chmod +x /tmp/my_script.sh",
          "sudo /tmp/my_script.sh arg_1 arg_2"
        ]
        connection {
          host        = self.public_ip # Use the public IP address of the instance
          type        = "ssh"
          user        = var.ansible_become_user
          private_key = file("${var.aws_key_variable_name}.pem")
      }
    }

Upvotes: 1

Peter Kay
Peter Kay

Reputation: 996

You will need to use ${} for the interpolation syntax in your path:

private_key = file("${path.module}/my-key")

In the documentation, the example shows ${} around the actual file path within the argument field: https://www.terraform.io/docs/configuration/functions/file.html

Upvotes: 1

Related Questions