Deploying DotNetCore on Ubuntu using Ansible
Tags: ansible, dotnetcore, ubuntu
Published: 2020-02-14 01:32:03

## Ansible
[Ansible](https://docs.ansible.com/ansible/latest/index.html) is an IT automation tool but I am going to use it here as a deployment tools. Ansible manages machines in an agent-less manner, so I only need to install it on my managing machine.

## Provisioning 2 VMs
I have provisioned 2 Ubuntu VMs on Azure. The managing VM is called *AnsibleLocal* and the other one is called *node01*.

## Installing Ansible on the AnsibleLocal machine
From Azure cloud shell *ssh* to the local machine and then run following commands:
```bash
$ sudo apt update
$ sudo apt install software-properties-common
$ sudo apt-add-repository --yes --update ppa:ansible/ansible
$ sudo apt install ansible
```
If you have different OS find the installation instruction from [here](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)

Per [Microsoft recommendation](https://github.com/dotnet/core/blob/master/release-notes/3.1/preview/3.1.0-preview2-install-instructions.md#install-using-snap) we are going to use *snap* module. Then ensure the version of *ansible* is greater than 2.8.
```bash
ansible-playbook --version
```
again to see the details of this module you can try:
```bash
ansible-doc -t module snap
```

## Adding the *node01* machine
We need to tell ansible the machine(s) which are going to be managed. Edit the ansible hosts file.
```bash
nano  /etc/ansible/hosts
```
Create a group and add the IP and ssh login details of the node machine(s)
```inf
[MyGroupA]
10.0.0.5 ansible_ssh_pass={a password} ansible_ssh_user={a user}
```

## Creating the playbook
Create a yaml file 
```bash
nano myplaybook.yaml
```
and put the following content:
```yaml
- name: my sample playbook
  hosts: [MyGroupA]
  remote_user: mohsen
  become: true

  tasks:
  - name: Install DotNetCore
    snap:
      name: dotnet-sdk 
      channel: 3.1
      classic: yes
      state: present
```
Note: the hosts group name (MyGroupA) and the remote_user is what we have defined in */etc/ansible/hosts* file.

Note: The *snap* module parameters used here are coming from Microsoft instruction:
sudo snap install dotnet-sdk --channel=3.1/beta --classic

In this example we are installing the dotnetsdk but in real cases we might only need *dotnet runtime* so the snap properties would be like:
```yaml
  - name: Install DotNetCore
    snap:
      name: dotnet-runtime-31
      state: present
```

In the most of ansible modules the property *state* accept following choices:
- present: it would install
- absent: it would uninstall

Before running the playbook you can do a syntax check on it:
```bash
ansible-playbook myplaybook.yaml --syntax-check
```

## Running
Finally, you can run our playbook:
```bash
ansible-playbook myplaybook.yaml 
```
The output would be like
![report](https://github.com/mkokabi/images/blob/master/Ansible/report-firsttime.png?raw=yes)
If we run the playbook again, it would detect the DotNetCore is already installed so the *changed* would be 0 but the *ok* would be still 2.
The output this time would be like
![report](https://github.com/mkokabi/images/blob/master/Ansible/report-nochange.png?raw=yes)

Now, we are going to *ssh* to the node01 VM and do a test. Again, as explained by Microsoft:
> When .NET Core is installed using the Snap package, the default .NET Core command is dotnet-sdk.dotnet, as opposed to just dotnet

Thus we would test as:
```bash
dotnet-sdk.dotnet --version
```
![report](https://github.com/mkokabi/images/blob/master/Ansible/FinalTest.png?raw=yes)