Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a keypair and then ssh into aws instance all via ansible to run commands on that instance

I'm creating an Ansible Playbook and I have created a new AWS EC2 instance. I am now wanting to SSH into this instance and run some commands within the shell of that instance. How would I go about doing this? Is there a way to generate a keypair via ansible, or is it best to use an existing one?

I have looked online at the online resources for Ansible ec2 - create, terminate, start or stop an instance in ec2 (http://docs.ansible.com/ansible/latest/ec2_module.html), as well as online blogs. Although, I haven't been able to figure out how to SSH into the instance, or seen an example online.

Using:

  - name: Wait for SSH to come up
      wait_for:
        host: "{{ item.public_ip }}"
        port: 22
        delay: 60
        timeout: 320
        state: started
      with_items: "{{ ec2.instances }}"

from the ansible-playbook documentation generates the following error:

"msg": "Timeout when waiting for :22"

The instance is also created without a public DNS to use to SSH into the instance via CLI.

Any help on how to ssh into the instance via ansible-playbook, or generate a public DNS name for the instance would be greatly appreciated.

like image 234
fuzzi Avatar asked Aug 17 '17 00:08

fuzzi


People also ask

How do I add a Keypair to my EC2 instance?

To add or replace a key pairConnect to your instance using your existing private key. Using a text editor of your choice, open the . ssh/authorized_keys file on the instance. Paste the public key information from your new key pair underneath the existing public key information.

How do I create an SSH connection in Ansible?

Setting up SSH keys By default, Ansible assumes you are using SSH keys to connect to remote machines. SSH keys are encouraged, but you can use password authentication if needed with the --ask-pass option. If you need to provide a password for privilege escalation (sudo, pbrun, and so on), use --ask-become-pass .

How do I create a Keypair on AWS?

To create a key pairOpen the Amazon EC2 console at https://console.aws.amazon.com/ec2/ . In the navigation pane, under Network & Security, choose Key Pairs. On the Key Pairs page, choose Create Key Pair. For Key pair name, type a name that is easy for you to remember, and then choose Create.


2 Answers

It would seem you have a fundamental misunderstanding of how AWS instances work. When an instance is created, it has a key-pair assigned to it for the default user. (eg. for an Amazon Linux instance the user will be ec2-user, ubuntu images use the ubuntu user).

This key pair can be seen in the ec2 console for the instance in it's details. All the existing key pairs can be seen under the Key Pairs section in the ec2 console.

To be able to ssh into an instance that you are starting with the key you have just created, you will need to do a few things:

  1. Generate the key pair locally (use shell: ssh-keygen ...)
  2. Create the ec2 keypair from the locally generated key pair (use ec2_key: ... )
  3. Start the instance using the named ec2 key pair (use ec2: ...)
  4. Call the instance just started in the same playbook using the key generated in step 1.

Steps 1-3 should be run as hosts: 127.0.0.1.

Step 4 will need to be done as a separate hosts: call in the same playbook and is not as easy as it seems. You will need to have some way of specifying the newly created instance in the hosts file, the Ansible group_vars path, using the add_hosts module, and/or find it's IP address somehow (possibly by using instance tags).

Once the instance is found, the Ansible private_key_file variable can then be used to specify the key in step 1 and ssh into the instance.

Not that it can't be done, but due to the difficulty and impracticality of doing this for the sake of having a new key pair each time you shell into the instance, I would advise against this unless absolutely essential. It would be better just to have proper key rotation policies in place if it is a security concern.

like image 198
Willem van Ketwich Avatar answered Oct 03 '22 22:10

Willem van Ketwich


Ansible connects to instances using SSH and then uses python on the client for most of its execution. You can bootstrap a client using the raw and shell modules to do things like install python2 and then proceed to execute using aws modules.

Something you need to understand about ansible, however, is that exists to execute upon many hosts as specified in an inventory file, not a single one. For this reason it is not possible to "ssh into an instance with ansible" as this would have no practical purpose for what ansible does. In provisioning 100s of servers the admin should not have to SSH into them, instead the process of creating an environment, maybe running containers for a service, should all be handled at a high level.

As has already been mentioned, if your intent is to create an EC2 instance using ansible that can be ssh'd into then you should use the ec2_key module and create the key BEFORE creating the instance. Then when you create the instance you will specify the SSH key through the key_name field.

Make sure that the security group you specify allows incoming connections from port 22, otherwise you will not be able to communicate with it.

If you would like ansible to automaticaly report the PublicDNS address you should look at ec2_remote_facts. This will return a JSON which can be parsed to report the public DNS.

like image 39
Erich Avatar answered Oct 03 '22 21:10

Erich