by Devin Yang
(This article was automatically translated.)

Published - 1 year ago ( Updated - 1 year ago )

This article is my use of Docker on MacOS to share my experience in using Ansible.
You can adjust the Ansible environment you want according to this directory structure, or learn Ansible.

The situation is like this, I hope that in my test environment, I can see the same article as the closest to the official machine,
But I don't want to use the test machine program to directly connect to the official machine's database.
My manual method is to export the official machine db, copy it to the test machine and then import it.
Although there are not a few steps, it seems to be a bit annoying to do, and manual operation is error-prone.
This reminds me of this Ansible thing,
I've heard of it but haven't tried it, so why not give it a try. 🫢

Here I use the backup and restore instructions mentioned in my previous phpenv article,
This is a simple database backup and restore example I wrote using Laravel's console function.
The code is in Laravel's routes/console.php, the content is as follows:

 Artisan::command("db:backup", function(){
$database = env("DB_DATABASE");
$command = sprintf("mysqldump -uroot --default-character-set=utf8mb4 -h%s %s",env("DB_HOST"), env("DB_DATABASE"));
$process = new Process(explode(" ", $command));
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
$data = $process->getOutput();
Storage::disk('local')->put(sprintf("%s/%s.sql","backup",$database), $data);
$this->comment(sprintf("The backup has been completed and stored in: storage/app/backup/%s.sql",$database));
})->purpose('backup MySQL database');

Artisan::command("db:restore {auto=no}", function($auto){
if(empty($auto)||$auto=="no"){
$auto = $this->confirm('Do you want to import the backup data into the Mysql database?');
}
if ($auto=='yes') {
$database = env("DB_DATABASE");
$command = sprintf("mysql -uroot -h %s --default-character-set=utf8mb4 %s < %s/%s.sql",
env("DB_HOST"),
$database,
Storage::path("backup"),
$database);
$this->comment($command);
system($command);
}
 })->purpose('backup data restoration');

That is to say, in both the official and test environments of my Laravel, this command can be used to backup and restore data according to the DB_DATABASE defined in .env. The artisan command is as follows:
backup:

 php artisan db:backup

reduction:
(The except function of Ansible is not very useful, so directly add the yes parameter,
Help me with Ansible automation without asking about the feature of direct restore. )

 php artisan db:restore yes


For the following content, I will operate the manual process first, and the instructions at the beginning of # are my annotations:

 #連線到正式環境容器環境
ssh www
Last login: Wed Dec 14 16:22:26 2022 from 172.25.0.1
dlaravel@1030cc543f6f:~$ artisan db:backup
The backup has been completed and stored in: storage/app/backup/ccctc.sql
#I pressed ctrl+d to cut the container connection
dlaravel@1030cc543f6f:/var/www/html$ logout
Connection to 192.168.99.130 closed.
#Execute the scp command to copy the sql file backed up on www to the local directory
scp www:/home/dlaravel/html/storage/app/backup/ccctc.sql .
ccctc.sql 100% 1708KB 111.7MB/s 00:00
#Copy the sql file just copied on this machine to the test machine, and rename it to ccc_test by the way, because the DB name I use in the .env of the test machine is a
scp ccctc.sql test:/home/dlaravel/html/storage/app/backup/ccc_test.sql
ccctc.sql 100% 1708KB 114.6MB/s 00:00
#SSH connection to enter the test environment, and perform backup and restore actions
ssh test
Last login: Wed Dec 14 16:58:59 2022 from 172.20.0.1
dlaravel@7d3f3f78d2af:~$ artisan db:restore yes
mysql -uroot -h192.168.99.2 --default-character-set=utf8mb4 ccc_test < /var/www/html/storage/app/backup/ccc_test.sql
 dlaravel@7d3f3f78d2af:~$

In the manual operation process above, just copying and pasting the long folder name is troublesome to see

So, I probably googled how to play Ansible, and then opened a container to test it out.
Before starting, let's take a look at my directory structure below. Ansible.cfg can be placed in the directory because it is not used, so it is not listed.

 root@a79153aa6cae:~/workspace# tree
.
├── Dockerfile
├── inventory
├── play
├── playbook.yml
├── run.sh
└── ssh
├──config
├── id_ed25519
 └── id_ed25519.pub

File: Dockerfile

 From ubuntu:latest
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -qq \
locales ssh python3 pip tzdata vim
RUN pip install ansible
#Chinese environment
RUN echo "Asia/Taipei" > /etc/timezone && \
dpkg-reconfigure -f noninteractive tzdata && \
sed -i -e 's/# zh_TW.UTF-8 UTF-8/zh_TW.UTF-8 UTF-8/' /etc/locale.gen && \
echo 'LANG="zh_TW.UTF-8"'>/etc/default/locale && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=zh_TW.UTF-8
ENV LANG zh_TW.UTF-8
ENV LANGUAGE zh_TW.UTF-8
 ENV LC_ALL zh_TW.UTF-8

File: ssh/config
The config content in the ssh directory in the workspace, even the ssh/config for the host

 Host www
Hostname 192.168.100.1
User dlaravel
StrictHostKeyChecking no
Port 2256
Host test
Hostname 192.168.100.1
User dlaravel
StrictHostKeyChecking no
 Port 2051

File: run.sh
run.sh, here is very simple, if there are parameters, run the parameters, if not, run bash.

 #!/bin/bash
if [ $1 ]; then
docker run --rm -v $(pwd)/ssh:/root/.ssh -v $(pwd):/root/workspace -w /root/workspace -ti ansible ./$1
else
docker run --rm -v $(pwd)/ssh:/root/.ssh -v $(pwd):/root/workspace -w /root/workspace -ti ansible bash
 the fi

$(pwd) means mount the directory on the current host to the container, if you don’t know pwd very well
You can type pwd on the command line to see.

 /Users/devin/workspace

So when the container is executed, I will mount the /Users/devin/workspace/ssh directory to the /root/.ssh directory of the container.
In this way, after entering the container, you can use the ssh command to connect to the remote host. Of course, the premise is that you need to add the ssh public key to the remote host.
In this article, I assume that you already know how to create an openssh key pair, and set up connection OpenSSH public key authentication. I won’t discuss it here. Please Google to learn the knowledge points you need.

Archives: inventory
Inventory defines the host to be used by my ansible. The test and www host names here are the host names in the shh config above.

 [my_servers]
test
www
 localhost ansible_connection=local

File: playbook.yml
The main event is playbook.yml (compared with it, it is not difficult to find that it is the manual operation steps above)
Looking at the Yaml file should be quite intuitive, so I won’t explain too much, and I should understand it. I also read other people’s examples and adjusted it to my own.
chdir is to cut the directory, shell is to execute the command of the shell, hosts is to connect to the host, and tasksk is to set the action to be executed.

 - hosts: www
tasks:
- name: make website database backup
shell:
"php artisan db:backup"
args:
chdir: "html"
- hosts: localhost
tasks:
- name: Copy the official machine data to this machine
shell:
"scp www:/home/dlaravel/html/storage/app/backup/ccctc.sql /root/workspace/ccc.sql"
- name: copy the file to the test machine
shell:
"scp /root/workspace/ccc.sql test:/home/dlaravel/html/storage/app/backup/ccc_test.sql"
- hosts: test
tasks:
- name: Import backup data to test machine
shell:
"php artisan db:restore yes"
args:
 chdir: "html"


Build and execute:
1. First, use docker build to build an ansible image in the workspace directory.
If you are a beginner of Docker, you are reminded that this will overwrite the original image on your system, please confirm that you know what this is doing before proceeding.

 $docker build -t ansible .
[+] Building 0.1s (8/8) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:latest 0.0s
=> [1/4] FROM docker.io/library/ubuntu:latest 0.0s
=> CACHED [2/4] RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -qq locales ssh python3 pip tzdata vi 0.0s
=> CACHED [3/4] RUN pip install ansible 0.0s
=> CACHED [4/4] RUN echo "Asia/Taipei" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata && sed -i -e ' 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:65590a0a9c31de5f611b85b9d5fd14be5a1615aa13746ebfa440bcbe5d8a70c2 0.0s
 => => naming to docker.io/library/ansible

2. Execute ./run.sh play and run, done, OK 1,2,3

 ./run.sh play
PLAY [www] ************************************************* ***************************************************** ***********************
TASK [Gathering Facts] ************************************************* ***************************************************** *************
ok: [www]
TASK [Backup website database] ********************************************* ***************************************************** *************
changed: [www]
PLAY [localhost] ************************************************* ***************************************************** *******************
TASK [Gathering Facts] ************************************************* ***************************************************** *************
ok: [localhost]
TASK [Copy official machine data to this machine] ******************************************* ***************************************************** *************
changed: [localhost]
TASK [copy file to test machine] ********************************************* ***************************************************** ***************
changed: [localhost]
PLAY [test] ************************************************* ***************************************************** ***********************
TASK [Gathering Facts] ************************************************* ***************************************************** *************
ok: [test]
TASK [Import backup data to test machine] ******************************************* ***************************************************** *************
changed: [test]
PLAY RECAP *************************************************** ***************************************************** *********************
localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
www : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0


If you want to verify whether the environment is normal, you can also use the same bash to enter the container to see if you can connect to the host normally. In the operation below, I am on the MacOS system and enter through ./run.sh Inside the container, and execute the ssh command to test the connection of the remote host.

 devin@m1Max > ~/workspace > ./run.sh
root@1e2c1ff05843:~/workspace# ssh www
Last login: Wed Dec 14 17:45:04 2022 from 172.25.0.1
dlaravel@1030cc543f6f:~$ logout
Connection to 192.168.100.1 closed.
root@1e2c1ff05843:~/workspace# ssh test
Last login: Wed Dec 14 17:45:08 2022 from 172.20.0.1
 dlaravel@7d3f3f78d2af:~$


Ansible still has a lot of setting methods and functions, which are waiting for you to discover by yourself. This is not the end but the beginning, Fighting. (I might watch too many Korean dramas)

Tags: ansible bash

Devin Yang

Feel free to ask me, if you don't get it.:)

No Comment

Post your comment

Login is required to leave comments

Similar Stories


bash,cli

some commands to check cpu, ram and disk info in linux

Introduce those commands that can be used to check hardware information on the Linux host

cwebp,bash

How do I use bash to optimize website image files and transfer images through cwebp

There are a lot of background images on the same page in my website, the download is too big, and I need to slim down. This cwebp tool is good. In the ubunut environment, apt install webp can be installed.

terminal,shortcuts,bash

Terminal Hotkey Raiders

This article introduces and sorts out some hotkeys of the terminal, let’s see what you don’t know? Come and try.