fuzzi
fuzzi

Reputation: 2277

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.

Upvotes: 5

Views: 2325

Answers (3)

Erich
Erich

Reputation: 2072

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.

Upvotes: 1

Willem van Ketwich
Willem van Ketwich

Reputation: 5994

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.

Upvotes: 4

Konstantin Suvorov
Konstantin Suvorov

Reputation: 68329

Use ec2_key module first:

- ec2_key:
    name: example2
    key_material: 'ssh-rsa AAAAxyz...== [email protected]'
    state: present

- ec2:
    key_name: example2
    instance_type: t2.micro
    image: ami-123456
    wait: yes
    group: webserver
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes

Upvotes: 0

Related Questions