aws_key_pair.auth: Error import KeyPair: InvalidKey.Format: Key is not in valid OpenSSH public key format - openssh

terraform to create an EC2 instance and use a public key to login to EC2 instance is not working.
aws_key_pair.auth: Error import KeyPair: InvalidKey.Format: Key is not in valid OpenSSH public key format
this is part of the main.tf to create a keypair
main.tf
resource "aws_key_pair" "auth" {
key_name = "${var.key_name}"
public_key = "${file(var.public_key_path)}"
}
declaring the variable
variable.tf
variable "public_key_path" {
description = <<DESCRIPTION
Path to the SSH public key to be used for authentication.
Ensure this keypair is added to your local SSH agent so provisioners can
connect.
Example: ~/.ssh/terraform.pub
DESCRIPTION
default = "~/.ssh/terraform.pub"
}
placeholder for the keys
~/.ssh/terraform.pub
resource "aws_key_pair" "deployer" {
key_name = "newssh"
public_key = "ssh-rsa
}

You need to add your SSH key to your ssh-agent
Ensure ssh-agent is enabled and running in the background
$ eval "$(ssh-agent -s)"
Add your SSH key to the ssh-agent. If you used an existing SSH key rather than generating a new SSH key, you’ll need to replace id_rsa in the command with the name of your existing private key file.
$ ssh-add ~/.ssh/id_rsa
so in your case
$ ssh-add ~/.ssh/terraform
Then run terraform apply

I had the same issue and I was created with unsupported encryption.
Create an RSA key. Amazon EC2 does not accept DSA keys
You can have a look at this page: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html

Related

Run Ansible playbook on OVH cloud instance with Terraform Cloud

I have a Terraform+Ansible combination that sets up an OVH cloud instance, and then runs an Ansible playbook on it using provisioners. When I run this locally, I can supply the public and private keys directly via the command line (not using file paths), and the terraform apply works perfectly.
On Terraform Cloud, I create the keys as variables. When I run the Terraform plan, the remote-exec provisioner works, and connects to the instance as it should. However, the local-exec fails with a Permission denied (publickey). What am I missing?
My provisioner blocks:
# Dummy resource to hold the provisioner that runs ansible
resource "null_resource" "run_ansible" {
provisioner "remote-exec" {
inline = ["sudo apt update", "sudo apt install python3 -y", "echo Done!"]
connection {
host = openstack_compute_instance_v2.test_instance.network[0].fixed_ip_v4
type = "ssh"
user = "ubuntu"
private_key = var.pvt_key
}
}
provisioner "local-exec" {
command = "python3 -m pip install --no-input ansible; ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u ubuntu -i '${openstack_compute_instance_v2.test_instance.network[0].fixed_ip_v4},' '--private-key=${var.pvt_key}' -e 'pub_key=${var.pub_key}' ansible/setup.yml"
}
}
Terraform cloud run error:
TASK [Gathering Facts] *********************************************************
fatal: [xx.xxx.xxx.xx]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added 'xx.xxx.xxx.xx' (ECDSA) to the list of known hosts.\r\nno such identity: /home/tfc-agent/.tfc-agent/component/terraform/runs/run-AhaANkduM9YXJVoC/config/<<EOT\n-----BEGIN OPENSSH PRIVATE KEY-----<private-key>-----END OPENSSH PRIVATE KEY-----\nEOT: No such file or directory\r\nubuntu#xx.xxx.xxx.xx: Permission denied (publickey).", "unreachable": true}
I solved the problem by creating (sensitive) key files on the Terraform Cloud host, and passing the paths to them to Ansible instead.
The variables are still supplied via TFCloud, but without the heredoc syntax.
I had to add an extra new line \n at the end of the key to get around it being stripped. See the following issue: https://github.com/ansible/awx/issues/9082.
resource "local_sensitive_file" "key_file" {
content = "${var.pvt_key}\n"
filename = "${path.root}/.ssh/key"
file_permission = "600"
directory_permission = "700"
}
resource "local_sensitive_file" "pubkey_file" {
content = "${var.pub_key}\n"
filename = "${path.root}/.ssh/key.pub"
file_permission = "644"
directory_permission = "700"
}

How to pick variables in vars.tf from BASH script

I am provisiong an EC2 instance using Terraform. It also has a startup script. I have vars.tf where I have specified all the variables in it. In my bash.sh script it should pickup one variable from vars.tf
Is it possible to refer the variable in vars.tf from bash script? Below is my use case.
bash.sh
#!/bin/bash
docker login -u username -p token docker.io
vars.tf
variable "username" {
default = "myuser"
}
variable "token" {
default = "mytoken"
}
My bash script should pick the variable from vars.tf
If this is not possible any workaround?
In order to provide Terraform variables to a script, we can use templatefile function. This function reads to content of a template file and injects Terraform variables in places marked by the templating syntax (${ ... }).
First we want to create a template file with the bash script and save it as init.tftpl:
#!/bin/bash
docker login -u ${username} -p ${token} docker.io
When creating the instance, we can use templatefile to provide the rendered script as user data:
resource "aws_instance" "web" {
ami = "ami-xxxxxxxxxxxxxxxxx"
instance_type = "t2.micro"
user_data = templatefile("init.tftpl", {
username = var.username
token = var.token
})
}

Can you not combine a variable with a string to look up another variable?

I have a script that I'm creating to create new users and add publickeys when I boot up a new node. However I'm running into issues when trying to pull from (user)_PUBLIC_KEYS array.
#!/bin/sh
USERS=(
User1
User2
)
User1_PUBLIC_KEYS=(
"ssh-rsa ..."
"ssh-rsa ..."
)
User2_PUBLIC_KEYS=(
"ssh-rsa ..."
)
for user in "${USERS}"; do
USERNAME="${user}"
...
# Add provided public keys
for key in "${USER}_PUBLIC_KEYS[#]"; do
echo "${key}" >> "${home_directory}/.ssh/authorized_keys"
done
...
done
I've even tried testing
user+="_PUBLIC_KEYS[#]"
# Add provided public keys
for key in "${user}"; do
echo "${key}"
done
This results in
User1
User1_PUBLIC_KEYS[#]
User2
User2_PUBLIC_KEYS[#]

How to call a variable of string with spaces in a terraform provisioner?

I am trying to run terraform provisioner which is calling my ansible playbook , now I am passing public key as a variable from user . When passing public key it doesnt take the entire key and just ssh-rsa , but not a complete string.
I want to pass the complete string as "ssh-rsa Aghdgdhfghjfdh"
The provisioner in terraform which I am running is :
resource "null_resource" "bastion_user_provisioner" {
provisioner "local-exec" {
command = "sleep 30 && ansible-playbook ../../../../ansible/create-user.yml --private-key ${path.module}/${var.project_name}.pem -vvv -u ubuntu -e 'username=${var.username}' -e 'user_key=${var.user_key}' -i ${var.bastion_public_ip}, -e 'root_shell=/bin/rbash' -e 'raw_password=${random_string.bastion_password.result}'"
}
}
If i run playbook alone as:
ansible-playbook -i localhost create-user.yml --user=ubuntu --private-key=kkk000.pem -e "username=kkkkk" -e 'user_key='ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+GWlljlLzW6DOEo"' -e root_shell="/bin/bash"
it works,
But I want the string to be in a terraform variable which is passed in provisioner.
I want to have key copied to a file as
ssh-rsa AWRDkj;jfdljdfldkf'sd.......
and not just
ssh-rsa
You are getting bitten by the -e key=value splitting that goes on with the command-line --extra-args interpretation [citation]. What you really want is to feed -e some JSON text, to stop it from trying to split on whitespace. That will also come in handy for sufficiently complicated random string passwords, which would otherwise produce a very bad outcome when trying to pass them on the command-line.
Thankfully, there is a jsonencode() function that will help you with that problem:
resource "null_resource" "bastion_user_provisioner" {
provisioner "local-exec" {
command = <<SH
set -e
sleep 30
ansible -vvv -i localhost, -c local -e '${jsonencode({
"username"="${var.username}",
"user_key"="${var.user_key}",
"raw_password"="${random_string.bastion_password.result}",
})}' -m debug -a var=vars all
SH
}
}

How to run ansible from linux to deploy on windows machines

Here is what I have after setting kerberos according to ansible:
http://docs.ansible.com/ansible/intro_windows.html
[libdefaults]
default_realm = MY.DOMAIN.COM
…
[realms]
MY.DOMAIN.COM = {
default_domain = my.domain.com
kdc = <domain-controller-server>.my.domain.com
kpasswd_server = <domain-controller-server>.my.domain.com
}
…
[domain_realm]
.my.domain.com = MY.DOMAIN.COM
…
I was able to create a kerberos ticket, here is my output:
root#alex-VirtualBox:/etc/ansible# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: <user_name>#MY.DOMAIN.COM
Valid starting Expires Service principal
04/07/2016 13:58:52 04/07/2016 23:58:52 krbtgt/MY.DOMAIN.COM#MY.DOMAIN.COM
renew until 04/08/2016 13:58:48
04/07/2016 14:02:20 04/07/2016 23:58:52 HTTP/<windows-target-server>.my.domain.com#MY.DOMAIN.COM
renew until 04/08/2016 13:58:48
So what I am trying to do is run ansible playbook or even a simple command on . But I am getting this error which I am pretty sure have nothing to do with ansible:
root#alex-VirtualBox:/etc/ansible# ansible windows -m win_ping --ask-vault-pass
Vault password:
<windows-target-server>.my.domain.com | FAILED! => {
"failed": true,
"msg": "kerberos: (('Unspecified GSS failure. Minor code may provide more information', 851968), ('Server not found in Kerberos database', -1765328377)), plaintext: 401 Unauthorized."
}
I even went ahead and created the keytab file:
> ktutil
ktutil: addent -password -p <user_name>#MY.DOMAIN.COM -k 1 -e rc4-hmac
provide password
ktutil: wkt <user_name>.keytab
ktutil: quit
But then I get different error:
root#alex-VirtualBox:/etc/ansible# ansible windows -m win_ping --ask-vault-pass
n2-2wbp-wbsvr01.na.msds.rhi.com | FAILED! => {
"failed": true,
"msg": "kerberos: (('An invalid name was supplied', 131072), ('Success', 100001)), plaintext: 401 Unauthorized."
}
Try to put the IP and Hostname of your Windows Host entry in /etc/hosts file and then try: https://github.com/diyan/pywinrm/issues/21#issuecomment-58958732 , https://github.com/diyan/pywinrm/issues/21#issuecomment-59084178
PS:
'Server not found in Kerberos database' - That usually means that the Linux host where you're running kinit is not joined to the domain (ie, it doesn't have a properly configured computer account in the domain). The existing docs unhelpfully omit that requirement...

Resources