---
title: Lab Exam Ansible
tags: I5, ESIEE
---
# Examen Ansible TP
Groupe :
- Maxence Bertrand
- Rémi Maubanc
Nous travaillons dans une VM de Debian 11.
## LAB 1 : Installation Ansible
Installation de python pip
```shell=
$ sudo apt install python3-pip
```
Installation de Ansible
```shell=
$ python3 -m pip install --user ansible
```
Mise à jour de la variable d'environnement
```shell=
$ export PATH=$PATH:/home/hyperion/.local/bin
```
Test de la version d'Ansible
```shell=
$ ansible --version
ansible [core 2.14.0]
config file = None
configured module search path = ['/home/hyperion/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/hyperion/.local/lib/python3.9/site-packages/ansible
ansible collection location = /home/hyperion/.ansible/collections:/usr/share/ansible/collections
executable location = /home/hyperion/.local/bin/ansible
python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110] (/usr/bin/python3)
jinja version = 3.1.2
libyaml = True
```
## LAB 2 : Installation de Terraform & Docker
### Installation de Terraform
Installation des requirements
```shell=
$ sudo apt install wget curl unzip software-properties-common gnupg2 -y
```
Ajout de la clé GPG de Hashicorp dans le serveur de clé d'APT
```shell=
$ curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
```
Ajout du dépot APT contenant Terraform
```shell=
$ sudo apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
```
Mise à jour des dépots et installation de Terraform
```shell=
$ sudo apt update
$ sudo apt install terraform -y
```
Vérification de la version de terraform
```shell=
$ terraform -v
Terraform v1.3.5
on linux_amd64
```
### Installation de Docker
Installation des dépendances
```shell=
$ sudo apt install ca-certificates curl gnupg lsb-release
```
Ajout de la clé GPG
```shell=
$ sudo mkdir -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
```
Ajout du dépot contenant Docker
```shell=
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
Mise à jour et installation de Docker
```shell=
$ sudo apt update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
```
Ajout du compte utilisateur dans le groupe docker
```shell=
$ sudo groupadd docker
$ sudo usermod -aG docker $USER
# Restart session
$ newgrp docker
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:faa03e786c97f07ef34423fccceeec2398ec8a5759259f94d99078f264e9d7af
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
```
## LAB 3 : Utilisation de Terraform et SSH
Fichier de configuration de Terraform
```yaml=
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "2.23.1"
}
}
}
provider "docker" {
host = "unix:///var/run/docker.sock"
}
# Pulls the image
resource "docker_image" "ubuntu-sshd" {
name = "takeyamajp/ubuntu-sshd"
}
resource "docker_network" "private_network" {
name = "unilasalle"
}
# Create a container
resource "docker_container" "database" {
image = docker_image.ubuntu-sshd.image_id
name = "database"
ports {
internal = "22"
external = "2200"
}
networks_advanced {
name = docker_network.private_network.name
}
}
resource "docker_container" "webserver" {
image = docker_image.ubuntu-sshd.image_id
name = "webserver"
ports {
internal = "22"
external = "2201"
}
networks_advanced {
name = docker_network.private_network.name
}
}
```
Initialisation de l'environnement
```shell=
$ terraform init
```
Application du plan de construction
```shell=
$ terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# docker_container.database will be created
+ resource "docker_container" "database" {
+ attach = false
+ bridge = (known after apply)
+ command = (known after apply)
+ container_logs = (known after apply)
+ container_read_refresh_timeout_milliseconds = 15000
+ entrypoint = (known after apply)
+ env = (known after apply)
+ exit_code = (known after apply)
+ gateway = (known after apply)
+ hostname = (known after apply)
+ id = (known after apply)
+ image = (known after apply)
+ init = (known after apply)
+ ip_address = (known after apply)
+ ip_prefix_length = (known after apply)
+ ipc_mode = (known after apply)
+ log_driver = (known after apply)
+ logs = false
+ must_run = true
+ name = "database"
+ network_data = (known after apply)
+ read_only = false
+ remove_volumes = true
+ restart = "no"
+ rm = false
+ runtime = (known after apply)
+ security_opts = (known after apply)
+ shm_size = (known after apply)
+ start = true
+ stdin_open = false
+ stop_signal = (known after apply)
+ stop_timeout = (known after apply)
+ tty = false
+ wait = false
+ wait_timeout = 60
+ healthcheck {
+ interval = (known after apply)
+ retries = (known after apply)
+ start_period = (known after apply)
+ test = (known after apply)
+ timeout = (known after apply)
}
+ labels {
+ label = (known after apply)
+ value = (known after apply)
}
+ networks_advanced {
+ aliases = []
+ name = "unilasalle"
}
+ ports {
+ external = 2200
+ internal = 22
+ ip = "0.0.0.0"
+ protocol = "tcp"
}
}
# docker_container.webserver will be created
+ resource "docker_container" "webserver" {
+ attach = false
+ bridge = (known after apply)
+ command = (known after apply)
+ container_logs = (known after apply)
+ container_read_refresh_timeout_milliseconds = 15000
+ entrypoint = (known after apply)
+ env = (known after apply)
+ exit_code = (known after apply)
+ gateway = (known after apply)
+ hostname = (known after apply)
+ id = (known after apply)
+ image = (known after apply)
+ init = (known after apply)
+ ip_address = (known after apply)
+ ip_prefix_length = (known after apply)
+ ipc_mode = (known after apply)
+ log_driver = (known after apply)
+ logs = false
+ must_run = true
+ name = "webserver"
+ network_data = (known after apply)
+ read_only = false
+ remove_volumes = true
+ restart = "no"
+ rm = false
+ runtime = (known after apply)
+ security_opts = (known after apply)
+ shm_size = (known after apply)
+ start = true
+ stdin_open = false
+ stop_signal = (known after apply)
+ stop_timeout = (known after apply)
+ tty = false
+ wait = false
+ wait_timeout = 60
+ healthcheck {
+ interval = (known after apply)
+ retries = (known after apply)
+ start_period = (known after apply)
+ test = (known after apply)
+ timeout = (known after apply)
}
+ labels {
+ label = (known after apply)
+ value = (known after apply)
}
+ networks_advanced {
+ aliases = []
+ name = "unilasalle"
}
+ ports {
+ external = 2201
+ internal = 22
+ ip = "0.0.0.0"
+ protocol = "tcp"
}
}
# docker_image.ubuntu-sshd will be created
+ resource "docker_image" "ubuntu-sshd" {
+ id = (known after apply)
+ image_id = (known after apply)
+ latest = (known after apply)
+ name = "ubuntu-sshd:ubuntu22.04"
+ output = (known after apply)
+ repo_digest = (known after apply)
}
# docker_network.private_network will be created
+ resource "docker_network" "private_network" {
+ driver = (known after apply)
+ id = (known after apply)
+ internal = (known after apply)
+ ipam_driver = "default"
+ name = "unilsalle"
+ options = (known after apply)
+ scope = (known after apply)
+ ipam_config {
+ aux_address = (known after apply)
+ gateway = (known after apply)
+ ip_range = (known after apply)
+ subnet = (known after apply)
}
}
Plan: 4 to add, 0 to change, 0 to destroy.
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
```
Test de connexion sur le conteneur
```shell=
$ ssh -p 2200 10.0.3.30
$ ssh -p 2201 10.0.3.30
```
## LAB 4 : Création de l'inventaire Ansible
Fichier de l'inventaire Ansible
```yaml=
db:
hosts:
database:
ansible_port: 2200
ansible_host: 10.0.3.30
ansible_user: root
web:
hosts:
webserver:
ansible_port: 2201
ansible_host: 10.0.3.30
ansible_user: root
```
Ajout des `/etc/hosts`
```
172.19.0.2 webserver
172.19.0.3 database
```
Ajout des clés SSH
```shell=
$ ssh-copy-id root@webserver
$ ssh-copy-id root@database
```
Test Ansible
```shell=
$ ansible all -i inventory.yml -m ping
webserver | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
database | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
```
## LAB 5 : Livraison d'une bannière SSH
Script Ansible pour l'ajout d'une banière
```yaml=
---
- name: Install Banner
hosts: all
vars:
ansible_python_interpreter: "/usr/bin/python3"
tasks:
- name: Copy Banner to server
ansible.builtin.lineinfile:
path: /etc/banner
create: true
regexp: "Authorized access only, server belongs to Unilasalle$"
line: "Authorized access only, server belongs to Unilasalle 2"
- name: Add banner in SSH Settings
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#Banner none'
line: 'Banner /etc/banner'
owner: root
group: root
mode: 0644
notify:
- Stop container
- Start container
handlers:
- name: Stop container
community.docker.docker_container:
name: "{{ inventory_hostname }}"
state: stopped
delegate_to: 127.0.0.1
- name: Start container
community.docker.docker_container:
name: "{{ inventory_hostname }}"
state: started
delegate_to: 127.0.0.1
```
Pour la partie de redémarrage des conteneurs, on a eu
besoin d'installer une dépendence Ansible Galaxy
```shell=
$ ansible-galaxy collection install community.docker
```
On délègue à `127.0.0.1` sinon la commande est exécutée sur la machine remote et non sur le serveur local.
## LAB 6 : Création d'une bannière SSH dynamique
Fichier Ansible
```yaml=
---
- name: Install Dynamic Banner
hosts: all
vars:
ansible_python_interpreter: "/usr/bin/python3"
tasks:
- name: Copy Banner template to server
template:
src: template/banner
dest: /etc/banner
mode: 0755
- name: Add banner in SSH Settings
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#Banner none'
line: 'Banner /etc/banner'
owner: root
group: root
mode: 0644
notify:
- Stop container
- Start container
handlers:
- name: Stop container
community.docker.docker_container:
name: "{{ inventory_hostname }}"
state: stopped
delegate_to: 127.0.0.1
- name: Start container
community.docker.docker_container:
name: "{{ inventory_hostname }}"
state: started
delegate_to: 127.0.0.1
```
Fichier Template
```
Hostname : {{ ansible_host }}
Groups : {{ group_names|join(', ') }}
```
## LAB 7 : Création des utilisateurs et des groupes
Fichier Ansible
```yaml=
---
- name: Add group and users
hosts: all
tasks:
- name: Add group to server
ansible.builtin.group:
name: "{{ item }}"
state: present
loop:
- "supervision"
- "applicative"
- name: Add user to server and group
ansible.builtin.user:
name: "{{ item }}"
group: "{{ item }}"
loop:
- "supervision"
- "applicative"
- name: Add web user
hosts: web
tasks:
- name: Add web user
ansible.builtin.user:
name: web
group: applicative
- name: Add db user
hosts: db
tasks:
- name: Add dbadmin user
ansible.builtin.user:
name: dbadmin
group: applicative
```
## LAB 8 : Installation du serveur web
Fichier Ansible
```yaml=
---
- name: Install apache2
hosts: web
become: true
tasks:
- name: Update APT
ansible.builtin.apt:
update_cache: yes
- name: Install Apache2
ansible.builtin.apt:
name: apache2
state: present
- name: Check if apache is started
ansible.builtin.service:
state: started
name: apache2
- name: Enabled apache service
ansible.builtin.service:
enabled: yes
name: apache2
- name: Install PHP with PSQL
hosts: web
tasks:
- name: Update APT
ansible.builtin.apt:
update_cache: yes
- name: Install PHP
ansible.builtin.apt:
name: php
state: present
- name: Install PGSQL module for PHP
ansible.builtin.apt:
name: php-pgsql
state: present
```
## LAB 9 : Installation de PostgreSQL
Fichier Ansible
```yaml=
---
- name: Install DB
hosts: db
become: true
tasks:
- name: Update APT
ansible.builtin.apt:
update_cache: yes
- name: Install Postgres
ansible.builtin.apt:
name: "{{ item }}"
state: present
loop:
- "postgresql"
- name: Change port PSQL
ansible.builtin.lineinfile:
path: "/etc/postgresql/14/main/postgresql.conf"
regexp: '^port = [0-9]+.*'
line: 'port = 5431'
notify:
- Restart psql
handlers:
- name: Restart psql
ansible.builtin.service:
name: postgresql
state: restarted
```
## Conclusion
- Tous les labs de 1 à 8 fonctionnent et ont été testés.
- Le bonus du Lab 5 fonctionne