2

I'm trying to setup an automated script in Ansible to set a new server, and i'm using ssh-copy-id to add the Ansible master server to the new server's authorized ssh keys.

I created a script which uses ssh-copy-id, but that command is asking for the new server's password.

Is it possible to give it that password in the same line of calling it so i can automate it in a script?

3 Answers 3

1

Yes, you can do it with a loop using expect.

3

Here's a method I use to provision new Debian hosts without known ssh keys. Host needs to have python and python-apt packages installed for this playbook to work out of the box. If you want to test it on a VM, you can run Debian installer with boot parameter url=drybjed.github.io - installer will download a preseed file with python and python-apt packages selected (among others). After installation, default password for root account will be debian and you will be forced to change it upon first login.

After installation and first login:

  1. Make sure that you can ssh into the root@host using password (accept host fingerprint, etc.).
  2. Create init.yml:

    hosts: all
      user: root
      sudo: no
      tags: init
      vars:
      - ssh_user: $ENV(USER)
    
      tasks:
      - name: INIT | Create admin system group
        group: name=admins system=yes state=present
        tags: init
    
      - name: INIT | Create admin account from current user
        user: name=$ssh_user state=present shell=/bin/bash groups=admins
        tags: init
    
      - name: INIT | Make sure essential software is installed
        apt: pkg=$item state=latest install_recommends=no
        with_items:
        - python
        - python-apt
        - sudo
        tags: init
    
      - name: INIT | Install ssh public key from current account
        authorized_key: user=$ssh_user key="$FILE(~/.ssh/id_rsa.pub)"
        tags: init
    
      - name: INIT | Install sudoers file for admin accounts
        lineinfile: "dest=/etc/sudoers.d/admins state=present create=yes regexp='^%admins' line='%admins ALL=(ALL:ALL) NOPASSWD: SETENV: ALL' owner=root group=root mode=0440"
        tags: init
    
  3. Run Ansible with: ansible-playbook -k -l host init.yml. Ansible will ask for root password, create a system admins group with access to sudo, create an user account based on your current user, copy your ~/.ssh/id_rsa.pub to your new account, and add it to the admins group.

From now you can use Ansible through your user account using sudo.

1
  • Almost worked for me. Had to do this for the ssh key: authorized_key: user={{ ansible_user_id }} key="{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
    – metakermit
    May 7, 2015 at 16:12
0

You could try a dirty hack with expect, but that's all it is: a dirty hack.

The correct way of having a public key in a just provisioned host is to add that step to the provision itself, i.e., include it it your pressed, kickstart or custom method you use to provision you hosts.

2
  • Can you give me an example of using "expect" with "ssh-copy-id"?
    – shaharmor
    Aug 21, 2013 at 7:04
  • Check the links in @Petter H's answer
    – dawud
    Aug 21, 2013 at 8:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.