{"id":4510,"date":"2025-05-11T14:32:51","date_gmt":"2025-05-11T14:32:51","guid":{"rendered":"https:\/\/geekmungus.co.uk\/?p=4510"},"modified":"2025-05-11T14:32:52","modified_gmt":"2025-05-11T14:32:52","slug":"ansible-workstation-setup-and-example","status":"publish","type":"post","link":"https:\/\/geekmungus.co.uk\/?p=4510","title":{"rendered":"Ansible Workstation Setup and Example"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">I\u2019m trying a simple example Ansible configuration, I have three Raspberry Pi, each with Ubuntu Linux 22.04.4 LTS installed, one I&#8217;m going to use as the Ansible Workstation, then use it to configure the other two servers for different use cases. Its a simple setup, but helps build understanding.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">My Ansible workstation is called dev1 on IP: 192.168.1.4, I then have two other servers called dev2 and dev3, which are on IP addresses: 192.168.1.7 and 192.168.1.6 respectively.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Configure Git Repository<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Its advised to setup a git repository, in my case I created on and cloned it down to the workstation machine. I\u2019m using a Personal Access Token, so enter your Github Username and PAT when prompted.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone https:\/\/github.com\/tristanhself\/ansible.git<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Setup Workstation (Install Python, Python Virtual Environment and Ansible)<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">To set things up, we now need to install Python.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update\nsudo apt install python3 python3-pip\nsudo apt install sshpass\npip3 install virtualenv<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I have a git repository cloned which has created the \u201cansible\u201d directory to hold all the Ansible configuration, but we also need a directory to hold the Python Virtual environment we\u2019re going to use with our Ansible Configuration. So we setup a virtual environment called \u201cansible-env\u201d, then source it, then install ansible inside the virtual environment and we are then ready to rhumble!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\nvirtualenv ansible-env\n\nsource ansible-env\/bin\/activate\n\npip install ansible\n\nansible --version<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s the first part done, we have Ansible installed and ready to start managing our two other servers, but to do that we need to create our Ansible configuration.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Quick Test 1 (Password Authentication)<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ll now perform a quick test to see what happens:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ansible -i ansble_inventory all -m ping -u ubuntu --ask-pass<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That appears to be fine, so we&#8217;ll now create a two files on called ansible_inventory and one called main.yml with the contents as follows:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ansible_inventory<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;servers]\ndev2 ansible_host=192.168.1.7\ndev3 ansible_host=192.168.1.6<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>main.yml<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\n- name: Set up a server\n  hosts: all\n  become: yes\n  tasks:\n    - name: Install Apache\n      apt:\n        name: apache2\n        state: present<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">then run with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ansible-playbook -i ansible_inventory main.yml -u ubuntu --ask-pass --ask-become-pass<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That should complete and install Apache to the two managed servers.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Setup of SSH Keys for use with Ansible<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ideally we don&#8217;t want to have to enter our user&#8217;s password and the sudo password each time we run the Ansible playbook, especially if we&#8217;re looking to have this automated, so what what can we use? Well, we have SSH Key-Based Authentication as an option, so let&#8217;s try that!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1 &#8211; Generate SSH Key Pair on your Local Machine<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We first create n SSH key pair on your local machine, we&#8217;ll go with the defaults and the default storage location, and we won&#8217;t specify a passphrase, but in production you will want to set a passphrase because if someone has your Private Key they have your access, at least a passphrase an help mitigate this somewhat!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh-keygen -t rsa -b 4096 -C \"yourname@domain.com\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once completed, you&#8217;ll have two files within your <strong>~\/.ssh\/<\/strong> directory: <strong>id_rsa <\/strong>(Private Key) and <strong>id_rsa.pub<\/strong> (Public Key). You must never share or expose your Private Key.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2 &#8211; Copy SSH Public Key to Remote Machine(s)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ok, so now we copy the key to the remote machines, in this example we&#8217;ll copy the Public Key to dev2 and dev3, so we can log on to these without needing to enter a password. In my case my user account is called &#8220;ubuntu&#8221; both on my Ansible Workstation, but also on the two remote servers (dev2 and dev3). Of course if you had your own user account you&#8217;d use that instead.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh-copy-id -i ~\/.ssh\/id_rsa.pub ubuntu@192.168.1.7\nssh-copy-id -i ~\/.ssh\/id_rsa.pub ubuntu@192.168.1.6<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Of course, this time you are connecting you will be prompted for a password when you&#8217;re logging on, and that is so it can copy the SSH Public Key to the server.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ubuntu@dev1:~\/.ssh$ ssh-copy-id -i ~\/.ssh\/id_rsa.pub ubuntu@192.168.1.6\n\/usr\/bin\/ssh-copy-id: INFO: Source of key(s) to be installed: \"\/home\/ubuntu\/.ssh\/id_rsa.pub\"\n\/usr\/bin\/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n\/usr\/bin\/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys\nubuntu@192.168.1.6's password:\n\nNumber of key(s) added: 1\n\nNow try logging into the machine, with:   \"ssh 'ubuntu@192.168.1.6'\"\nand check to make sure that only the key(s) you wanted were added.<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3 &#8211; Verify SSH Key-Based Authentication<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We have our user account&#8217;s Public Key now stored on both the dev2 and dev3 remote servers, so we can try to connect to them in turn with the below commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh ubuntu@192.168.1.7\nssh ubuntu@192.168.1.6<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If all has worked well, you&#8217;ll log into the server via SSH, but not be prompted for a password! And now we are ready to use this with Ansible, so we can run our Ansible against our two servers, without having to enter a password.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Quick Test 2 (Key-Based Authentication)<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">We can now perform a test with Ansible using Key-Based Authentication (i.e. password-less), this will be as simple as running:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ansible-playbook -i ansible_inventory main.yml -u ubuntu<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">However, what you&#8217;ll notice is an error &#8220;Missing Sudo Password&#8221;, we have this issue because our play includes &#8220;become: yes&#8221;, which means the &#8220;ubuntu&#8221; user we are using is attempting to become &#8220;root&#8221; and we haven&#8217;t specified the sudo password, there are a few ways to resolve this, one is to just add <em>&#8220;&#8211;ask-become-pass&#8221;<\/em> to the end of the command, that&#8217;s fine but it slightly defeats the point of a password-less Ansible playbook run.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ansible-playbook -i ansible_inventory main.yml -u ubuntu --ask-become-pass<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Instead, for our example we&#8217;ll use one of the other options, which is to ensure the &#8220;ubuntu&#8221; user on the remote host has password-less sudo, now in a real world environment you can do this as a method, but what you need to ensure is that the user account you use is never used for anything else but running Ansible, you may also want to set a very long password and\/or disable password authentication for that account altogether, i.e. means that only Key-Based Authentication can be used. Anyway let&#8217;s resolve this problem.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Firstly SSH to each of our servers dev2 and dev3 in this example and edit the sudoers file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo visudo<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then add this line to the file above the &#8220;includedir&#8221; statement the following, in our case we using the &#8220;ubuntu&#8221; username.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ubuntu ALL=(ALL) NOPASSWD:ALL<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should now be able to sudo from this user account without needing to enter a password, give it a quick try with &#8220;sudo -s&#8221;, if you&#8217;re not prompted for a password, we&#8217;re all set.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s try running our Ansible again from the Ansible workstation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ansible-playbook -i ansible_inventory main.yml -u ubuntu<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That looks like a success to me!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"195\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/05\/image-1-1024x195.png\" alt=\"\" class=\"wp-image-4517\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/05\/image-1-1024x195.png 1024w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/05\/image-1-300x57.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/05\/image-1-768x146.png 768w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/05\/image-1-1536x292.png 1536w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2025\/05\/image-1.png 1893w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">Conclusion<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ve performed the installation of Ansible on our workstation, we&#8217;ve then configured an SSH key pair for our Ansible Workstation user, deployed the public key to our two managed servers (dev2 and dev3), configured password-less sudo, and finally used this to run our Ansible Playbook which installed Apache onto our two managed servers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I\u2019m trying a simple example Ansible configuration, I have three Raspberry Pi, each with Ubuntu Linux 22.04.4 LTS installed, one I&#8217;m going to use as the Ansible Workstation, then use it to configure the other two servers for different use cases. Its a simple setup, but helps build understanding. My Ansible workstation is called dev1 &#8230; <a title=\"Ansible Workstation Setup and Example\" class=\"read-more\" href=\"https:\/\/geekmungus.co.uk\/?p=4510\" aria-label=\"Read more about Ansible Workstation Setup and Example\">Read more<\/a><\/p>\n","protected":false},"author":4,"featured_media":4522,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49],"tags":[],"class_list":["post-4510","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ansible"],"_links":{"self":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/4510","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4510"}],"version-history":[{"count":9,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/4510\/revisions"}],"predecessor-version":[{"id":4521,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/4510\/revisions\/4521"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/media\/4522"}],"wp:attachment":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4510"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4510"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4510"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}