ubuntu@server:~/my-ansible$ mkdir ~/my-ansible/chapter_09.1
cd ~/my-ansible/chapter_09.1
ubuntu@server:~/my-ansible/chapter_09.1$ cat <<EOT > ansible.cfg
[defaults]= ./inventory
inventory = ./inventory
remote_user = ubuntu
ask_pass = false
[privilege_escalation]
[privilege_escalation]
become = true = sudo
become_method = sudo
become_user = rootfalse
become_ask_pass = false
EOT
cat <<EOT> inventory
tnode1
tnode2
tnode3
EOT
# 패스워드 지정
ubuntu@server:~/my-ansible/chapter_09.1$ ansible-vault create vars/secret.yml
New Vault password:
Confirm New Vault password:
# 입력후 wq 저장
----
user_info:
- userid: "ansible"
userpw: "ansiblePw1"
- userid: "stack"
userpw: "stackPw1"
----
[WARNING]: vars does not exist, creating...
ubuntu@server:~/my-ansible/chapter_09.1$ ls -l vars/secret.yml
-rw------- 1 ubuntu ubuntu 743 Feb 1 20:26 vars/secret.yml
ubuntu@server:~/my-ansible/chapter_09.1$ cat vars/secret.yml
$ANSIBLE_VAULT;1.1;AES256
35623435363363613734316432653637343138633333363833646261386438343739376362366636
6165663331303134336630333166626363346335623732360a343034663834373264616533623963
36396664376137643964386136616432383031393037656633323366623031333338303762376536
3135626538663462360a333638303734316631343866643238343661373166633832346134643965
38653736623634393130396365346366616431383162646464616563633030363862333739346665
31313739393264613232363339343231633632393431303362366133623435633439356234643163
66343834363663326533306238633866616166623435363031306435383666653563623639616531
35613234633762393539303065303037656134616230623063666632343131393162383464633538
33323865393539626230303731666630336538616236316137663836353761636265
# create_user.yml
---
- hosts: all
# vault로 사용자 계정 관련 변수가 정의된 파일을 임포트하여 사용
vars_files:
- vars/secret.yml
tasks:
# loop 문을 사용하여 user_info의 userid와 userpw 사용
- name: Create user
ansible.builtin.user:
name: "{{ item.userid }}"
password: "{{ item.userpw | password_hash('sha512', 'mysecret') }}"
state: present
shell: /bin/bash
loop: "{{ user_info }}
ubuntu@server:~/my-ansible/chapter_09.1$ ansible-playbook --ask-vault-pass create_user.yml
Vault password:
PLAY [all] ********************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [tnode3]
ok: [tnode1]
ok: [tnode2]
TASK [Create user] ************************************************************************************************************************************************************************************************************
[DEPRECATION WARNING]: Encryption using the Python crypt module is deprecated. The Python crypt module is deprecated and will be removed from Python 3.13. Install the passlib library for continued encryption functionality.
This feature will be removed in version 2.17. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Encryption using the Python crypt module is deprecated. The Python crypt module is deprecated and will be removed from Python 3.13. Install the passlib library for continued encryption functionality.
This feature will be removed in version 2.17. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Encryption using the Python crypt module is deprecated. The Python crypt module is deprecated and will be removed from Python 3.13. Install the passlib library for continued encryption functionality.
This feature will be removed in version 2.17. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [tnode3] => (item={'userid': 'ansible', 'userpw': 'ansiblePw1'})
changed: [tnode2] => (item={'userid': 'ansible', 'userpw': 'ansiblePw1'})
changed: [tnode1] => (item={'userid': 'ansible', 'userpw': 'ansiblePw1'})
changed: [tnode2] => (item={'userid': 'stack', 'userpw': 'stackPw1'})
changed: [tnode3] => (item={'userid': 'stack', 'userpw': 'stackPw1'})
changed: [tnode1] => (item={'userid': 'stack', 'userpw': 'stackPw1'})
PLAY RECAP ********************************************************************************************************************************************************************************************************************
tnode1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible -m shell -a "tail -n 3 /etc/passwd" all
tnode3 | CHANGED | rc=0 >>
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
ansible:x:1001:1001::/home/ansible:/bin/bash
stack:x:1002:1002::/home/stack:/bin/bash
tnode1 | CHANGED | rc=0 >>
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
ansible:x:1001:1001::/home/ansible:/bin/bash
stack:x:1002:1002::/home/stack:/bin/bash
tnode2 | CHANGED | rc=0 >>
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
ansible:x:1001:1001::/home/ansible:/bin/bash
stack:x:1002:1002::/home/stack:/bin/bash
사용자 아이디는 외부 변수로 받습니다.
ansible-server에서 ansible 계정을 만들고 SSH 키를 생성합니다.
ansible-server에 생성된 SSH 공개 키를 각 tnode에 복사합니다.
계정을 생성할 때는 ansible.builtin.user 모듈을, SSH 공개 키를 복사할 때는 ansible.posix.authorized_key 모듈을 이용할 수 있습니다.
해당 플레이북명은 create_sshkey.yml 로 설정하고, ‘Create ssh key’ 태스크와 ‘Copy SSH Pub Key’ 라는 2개의 태스크를 갖습니다.
‘Create ssh key’ 태스크는 localhost(현재 ansble 서버)에서 실행하고, ‘Copy SSH Pub Key’ 태스크는 tnode에서 실행합니다.
인벤토리에는 다음과 같이 tnode라는 그룹을 만든 다음 모든 관리 노드를 tnode 그룹으로 정의합니다.
ansible.posix.authorized_key
모듈 https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html
Lookups
플러그인 https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_lookups.html
ubuntu@server:~/my-ansible/chapter_09.1$ mkdir ~/my-ansible/chapter_09.2
cd ~/my-ansible/chapter_09.2
ubuntu@server:~/my-ansible/chapter_09.2$ cp ~/my-ansible/ansible.cfg ./
ubuntu@server:~/my-ansible/chapter_09.2$ cat <<EOT> inventory
[tnode]
tnode1
tnode2
tnode3
EOT
### lookup 플러그인
ubuntu@server:~/my-ansible/chapter_09.2$ ansible-doc -l -t lookup
[WARNING]: While constructing a mapping from /usr/lib/python3/dist-packages/ansible_collections/wti/remote/plugins/lookup/cpm_snmp_config.py, line 58, column 9, found a duplicate dict key (type). Using last defined value
only.
amazon.aws.aws_account_attribute Look up AWS account attributes
amazon.aws.aws_collection_constants expose various collection related constants
amazon.aws.aws_service_ip_ranges Look up the IP ranges for services provided in AWS such as EC2 and S3
amazon.aws.secretsmanager_secret Look up secrets stored in AWS Secrets Manager
amazon.aws.ssm_parameter gets the value for a SSM parameter or all parameters under a path
ansible.builtin.config Lookup current Ansible configuration values
ansible.builtin.csvfile read data from a TSV or CSV file
ansible.builtin.dict returns key/value pair items from dictionaries
ansible.builtin.env Read the value of environment variables
ansible.builtin.file read file contents
ansible.builtin.fileglob list files matching a pattern
ansible.builtin.first_found return first file found from list
ansible.builtin.indexed_items rewrites lists to return 'indexed items'
ansible.builtin.ini read data from an ini file
ansible.builtin.inventory_hostnames list of inventory hosts matching a host pattern
ansible.builtin.items list of items
SSH 키 생성하고 복사하는 플레이북을 작성 : 여기서는 태스크가 실행될 호스트별로 태스크 작성
localhost인 ansible-server에서 생성된 SSH 공개 키는 ansible.posix.authorized_key 모듈을 이용하여 인벤토리의 tnode 호스트 그룹의 각 서버로 복사됩니다.
이때 키를 등록하기 위해 lookup 함수가 사용 : 외부 소스(파일, DB, key/value stores, APIs 등)ㅌ으로 부터 데이터를 검색 합니다.
### create_sshkey.yml
---
- hosts: localhost
tasks:
- name : Create ssh key
ansible.builtin.user:
name: "{{ userid }}"
generate_ssh_key: true
ssh_key_bits: 2048
ssh_key_file: /home/{{ userid }}/.ssh/id_rsa
shell: /bin/bash
- hosts: tnode
tasks:
- name: Copy SSH Pub key
ansible.posix.authorized_key:
user: "{{ userid }}"
state: present
key: "{{ lookup('file', '/home/{{ userid }}/.ssh/id_rsa.pub') }}"
## ansible.cfg 파일 수정
[defaults]
inventory = ./inventory
remote_user = root
inject_facts_as_vars = false
---
ubuntu@server:~/my-ansible/chapter_09.2$ sudo ansible-playbook -e userid=ansible create_sshkey.yml --ask-pass
SSH password:
PLAY [localhost] **************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [localhost]
TASK [Create ssh key] *********************************************************************************************************************************************************************************************************
ok: [localhost]
PLAY [tnode] ******************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [tnode2]
ok: [tnode3]
ok: [tnode1]
TASK [Copy SSH Pub key] *******************************************************************************************************************************************************************************************************
changed: [tnode3]
changed: [tnode1]
changed: [tnode2]
PLAY RECAP ********************************************************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# ansible 계정 전환
ubuntu@server:~/my-ansible/chapter_09.2$ sudo su - ansible
ansible@server:~$ echo $SHELL
/bin/bash
ansible@server:~$ whoami
ansible
ansible@server:~$ ls -al
total 24
drwxr-x--- 3 ansible ansible 4096 Feb 1 20:50 .
drwxr-xr-x 4 root root 4096 Feb 1 20:50 ..
-rw-r--r-- 1 ansible ansible 220 Jan 7 2022 .bash_logout
-rw-r--r-- 1 ansible ansible 3771 Jan 7 2022 .bashrc
-rw-r--r-- 1 ansible ansible 807 Jan 7 2022 .profile
drwx------ 2 ansible ansible 4096 Feb 1 20:50 .ssh
ansible@server:~$ ls -l .ssh/
total 8
-rw------- 1 ansible ansible 1831 Feb 1 20:50 id_rsa
-rw-r--r-- 1 ansible ansible 409 Feb 1 20:50 id_rsa.pub
## tnode ssh 접속 테스트
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i hostname; echo; done
## # 대상 노드에 정보 확인
ansible@server:~$ for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i tree /home/ansible/.ssh; echo; done
>> tnode1 <<
/home/ansible/.ssh
└── authorized_keys
0 directories, 1 file
>> tnode2 <<
/home/ansible/.ssh
└── authorized_keys
0 directories, 1 file
>> tnode3 <<
/home/ansible/.ssh
└── authorized_keys
0 directories, 1 file
ansible@server:~$ for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i cat /home/ansible/.ssh/authorized_keys; echo; done
>> tnode1 <<
ssh-rsa ... ansible-generated on server
>> tnode2 <<
ssh-rsa ... ansible-generated on server
>> tnode3 <<
ssh-rsa ... ansible-generated on server
## ubuntu 유저로 복귀
exit
## sudo-ansible.yml
---
- hosts: all
tasks:
- name: Create file
ansible.builtin.file:
path: /etc/sudoers.d/ansible
mode: '0600'
state: touch
- name: Edit file
ansible.builtin.lineinfile:
path: /etc/sudoers.d/ansible
line: ansible ALL=(root) NOPASSWD:ALL
ubuntu@server:~/my-ansible/chapter_09.2$ sudo ansible-playbook sudo-ansible.yml --ask-pass
SSH password:
PLAY [all] ********************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [tnode2]
ok: [tnode3]
ok: [tnode1]
TASK [Create file] ************************************************************************************************************************************************************************************************************
changed: [tnode2]
changed: [tnode1]
changed: [tnode3]
TASK [Edit file] **************************************************************************************************************************************************************************************************************
changed: [tnode2]
changed: [tnode3]
changed: [tnode1]
PLAY RECAP ********************************************************************************************************************************************************************************************************************
tnode1 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode2 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode3 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ubuntu@server:~/my-ansible/chapter_09.2$ sudo su - ansible
ansible@server:~$ ssh tnode1
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 6.2.0-1018-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Thu Feb 1 21:08:05 KST 2024
System load: 0.0205078125 Processes: 104
Usage of /: 6.1% of 28.89GB Users logged in: 0
Memory usage: 6% IPv4 address for ens5: 10.10.1.11
Swap usage: 0%
Expanded Security Maintenance for Applications is not enabled.
2 updates can be applied immediately.
2 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
ansible@tnode1:~$ whoami
ansible
ansible@tnode1:~$ sudo cat /etc/sudoers.d/ansible
ansible ALL=(root) NOPASSWD:ALL
NTP 서버 주소는 메인 플레이북에서 정의합니다.
운영체제가 Ubuntu면 apt 모듈을 사용하여 chrony를 설치합니다.
운영체제가 CentOS/레드햇이면 dnf 모듈을 사용하여 chrony를 설치합니다.
Jinja2 템플릿 방식의 chrony.conf 파일을 대상 호스트로 복사합니다.
설정 파일이 복사되면 chrony 서비스를 재시작합니다.
다음에도 사용할 수 있도록 롤을 이용하여 설계하고 작성해보겠습니다.
또한, 원활한 실습 진행을 위해 root 계정으로 실습을 진행하도록 하겠습니다.
## ansible 계정의 실습 디렉토리 생성
root@server:~# su - ansible -c 'mkdir -p ~/ansible-project/chapter_09.3'
root@server:~# ls -l /home/ansible/
total 4
drwxrwxr-x 3 ansible ansible 4096 Feb 1 21:23 ansible-project
root@server:~# ls -l /home/ansible/
total 4
drwxrwxr-x 3 ansible ansible 4096 Feb 1 21:23 ansible-project
root@server:/home/ansible/ansible-project# su - ansible
ansible@server:~$ whoami
ansible
ansible@server:~$ pwd
/home/ansible
ansible@server:~$ cd ~/ansible-project/chapter_09.3/
ansible@server:~/ansible-project/chapter_09.3$ cat <<EOT > ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ansible
ask_pass = false
roles_path = ./roles
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
EOT
ansible@server:~/ansible-project/chapter_09.3$ cat <<EOT > inventory
[tnode]
tnode1
tnode2
tnode3
EOT
ansible@server:~/ansible-project/chapter_09.3$ ll
total 16
drwxrwxr-x 2 ansible ansible 4096 Feb 1 21:26 ./
drwxrwxr-x 3 ansible ansible 4096 Feb 1 21:23 ../
-rw-rw-r-- 1 ansible ansible 197 Feb 1 21:26 ansible.cfg
-rw-rw-r-- 1 ansible ansible 29 Feb 1 21:26 inventory
ansible@server:~/ansible-project/chapter_09.3$ ansible-galaxy role init --init-path ./roles myrole.chrony
- Role myrole.chrony was created successfully
ansible@server:~/ansible-project/chapter_09.3$ tree roles
roles
└── myrole.chrony
├── README.md
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
9 directories, 8 files
---
# vars file for myrole.chrony
package_name : chrony
service_name : chronyd
fedora_os:
- RedHat
- CentOS
pool {{ ntp_server }}
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
allow 10.10.0.0/16
local stratum 10
keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony
--------
ansible@server:~/ansible-project/chapter_09.3/roles/myrole.chrony/vars$ cat ~/ansible-project/chapter_09.3/roles/myrole.chrony/templates/chrony.conf.j2
pool {{ ntp_server }}
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
allow 10.10.0.0/16
local stratum 10
keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony
---
# handlers file for myrole.chrony
- name: Restart chrony
ansible.builtin.service:
name: "{{ service_name }}"
state: restarted
------
ansible@server:~/ansible-project/chapter_09.3/roles/myrole.chrony/handlers$ cat main.yml
---
# handlers file for myrole.chrony
- name: Restart chrony
ansible.builtin.service:
name: "{{ service_name }}"
state: restarted---
# handlers file for myrole.chrony
---
# tasks file for myrole.chrony
- name: Import playbook
ansible.builtin.include_tasks:
file: "{{ ansible_facts.distribution }}.yml"
- name: Copy chrony config file when Ubuntu
ansible.builtin.template:
src: chrony.conf.j2
dest: /etc/chrony/chrony.conf
notify: "Restart chrony"
when: ansible_facts.distribution == "Ubuntu"
- name: Copy chrony config file when Other OS
ansible.builtin.template:
src: chrony.conf.j2
dest: /etc/chrony.conf
notify: "Restart chrony"
when: ansible_facts.distribution in fedora_os
------------
ansible@server:~/ansible-project/chapter_09.3/roles/myrole.chrony/tasks$ cat main.yml
---
# tasks file for myrole.chrony
- name: Import playbook
ansible.builtin.include_tasks:
file: "{{ ansible_facts.distribution }}.yml"
- name: Copy chrony config file when Ubuntu
ansible.builtin.template:
src: chrony.conf.j2
dest: /etc/chrony/chrony.conf
notify: "Restart chrony"
when: ansible_facts.distribution == "Ubuntu"
- name: Copy chrony config file when Other OS
ansible.builtin.template:
src: chrony.conf.j2
dest: /etc/chrony.conf
notify: "Restart chrony"
when: ansible_facts.distribution in fedora_os
touch ~/ansible-project/chapter_09.3/roles/myrole.chrony/tasks/RedHat.yml
---
---
- name: Install chrony using dnf
ansible.builtin.dnf:
name: "{{ package_name }}"
state: latest
---
touch ~/ansible-project/chapter_09.3/roles/myrole.chrony/tasks/CentOS.yml
---
---
- name: Install chrony using dnf
ansible.builtin.dnf:
name: "{{ package_name }}"
state: latest
---
touch ~/ansible-project/chapter_09.3/roles/myrole.chrony/tasks/Ubuntu.yml
---
---
- name: Install chrony using apt
ansible.builtin.apt:
name: "{{ package_name }}"
state: latest
---
touch ~/ansible-project/chapter_09.3/install_ntp.yml
---
ansible@server:~/ansible-project/chapter_09.3$ cat install_ntp.yml
---
- hosts: tnode
roles:
- role: myrole.chrony
ntp_server: 0.kr.pool.ntp.org
ansible@server:~/ansible-project/chapter_09.3$ ansible-playbook --syntax-check install_ntp.yml
playbook: install_ntp.yml
ansible@server:~/ansible-project/chapter_09.3$ ansible-playbook install_ntp.yml
PLAY [tnode] *************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [tnode3]
ok: [tnode1]
ok: [tnode2]
TASK [myrole.chrony : Import playbook] ***********************************************************************
included: /home/ansible/ansible-project/chapter_09.3/roles/myrole.chrony/tasks/Ubuntu.yml for tnode1, tnode2, tnode3
TASK [myrole.chrony : Install chrony using apt] **************************************************************
ok: [tnode3]
ok: [tnode1]
ok: [tnode2]
TASK [myrole.chrony : Copy chrony config file when Ubuntu] ***************************************************
changed: [tnode2]
changed: [tnode3]
changed: [tnode1]
TASK [myrole.chrony : Copy chrony config file when Other OS] *************************************************
skipping: [tnode1]
skipping: [tnode2]
skipping: [tnode3]
RUNNING HANDLER [myrole.chrony : Restart chrony] *************************************************************
changed: [tnode2]
changed: [tnode1]
changed: [tnode3]
PLAY RECAP ***************************************************************************************************
tnode1 : ok=5 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
tnode2 : ok=5 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
tnode3 : ok=5 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
ansible@server:~/ansible-project/chapter_09.3$ ansible -m shell -a "cat /etc/chrony/chrony.conf" tnode1
tnode1 | CHANGED | rc=0 >>
pool 0.kr.pool.ntp.org
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
allow 10.10.0.0/16
local stratum 10
keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony
ansible@server:~/ansible-project/chapter_09.3$ ansible -m shell -a "systemctl status chrony" tnode1
tnode1 | CHANGED | rc=0 >>
● chrony.service - chrony, an NTP client/server
Loaded: loaded (/lib/systemd/system/chrony.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2024-02-01 21:42:30 KST; 2min 25s ago
Docs: man:chronyd(8)
man:chronyc(1)
man:chrony.conf(5)
Process: 3554 ExecStart=/usr/lib/systemd/scripts/chronyd-starter.sh $DAEMON_OPTS (code=exited, status=0/SUCCESS)
Main PID: 3565 (chronyd)
Tasks: 2 (limit: 4598)
Memory: 1.2M
CPU: 50ms
CGroup: /system.slice/chrony.service
├─3565 /usr/sbin/chronyd -F 1
└─3566 /usr/sbin/chronyd -F 1
Feb 01 21:42:30 tnode1 systemd[1]: Starting chrony, an NTP client/server...
Feb 01 21:42:30 tnode1 chronyd[3565]: chronyd version 4.2 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +NTS +SECHASH +IPV6 -DEBUG)
Feb 01 21:42:30 tnode1 chronyd[3565]: Could not open keyfile /etc/chrony.keys
Feb 01 21:42:30 tnode1 chronyd[3565]: Initial frequency -6.115 ppm
Feb 01 21:42:30 tnode1 chronyd[3565]: Using right/UTC timezone to obtain leap second data
Feb 01 21:42:30 tnode1 chronyd[3565]: Loaded seccomp filter (level 1)
Feb 01 21:42:30 tnode1 systemd[1]: Started chrony, an NTP client/server.
Feb 01 21:44:40 tnode1 chronyd[3565]: Selected source 121.162.54.1 (0.kr.pool.ntp.org)
Feb 01 21:44:40 tnode1 chronyd[3565]: System clock TAI offset set to 37 seconds
community.general.nmcli
모듈 https://docs.ansible.com/ansible/latest/collections/community/general/nmcli_module.htmlnic2를 추가하기 번거로워서 동작 적용은 하지 않았습니다.
프로젝트 디렉터리 생성 및 ansible.cfg, inventory 파일 작성
ansible@server:~/ansible-project/chapter_09.3$ mkdir ~/ansible-project/chapter_10.1
cd ~/ansible-project/chapter_10.1
ansible@server:~/ansible-project/chapter_10.1$ cat <<EOT> ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ansible
ask_pass = false
inject_facts_as_vars = false
roles_path = ./roles
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
EOT
ansible@server:~/ansible-project/chapter_10.1$ cat <<EOT> inventory
[tnode]
tnode1
tnode2
tnode3
EOT
ansible@server:~/ansible-project/chapter_10.1$ ansible-galaxy role init --init-path ./roles myrole.nmcli
- Role myrole.nmcli was created successfully
ansible@server:~/ansible-project/chapter_10.1$ ansible-galaxy role init --init-path ./roles myrole.netplan
- Role myrole.netplan was created successfully
ansible@server:~/ansible-project/chapter_10.1$ ansible-galaxy role list
# /home/ansible/ansible-project/chapter_10.1/roles
- myrole.nmcli, (unknown version)
- myrole.netplan, (unknown version)
ansible@server:~/ansible-project/chapter_10.1/roles/myrole.nmcli/tasks$ cat main.yml
---
# tasks file for myrole.nmcli
- name: Setup nic ip
community.general.nmcli:
type: ethernet
conn_name: "{{ item.con_name }}"
ip4: "{{ item.ip_addr }}"
gw4: "{{ item.ip_gw }}"
dns4: "{{ item.ip_dns }}"
state: present
loop: "{{ net_info }}"
when: net_info[0].con_name in ansible_facts.interfaces
ansible@server:~/ansible-project/chapter_10.1/roles/myrole.nmcli/tasks$ cat ~/ansible-project/chapter_10.1/rol
es/myrole.netplan/templates/01-netplan-ansible.yaml.j2
# This is the network config written by 'ansible'
network:
version: 2
ethernets:
{% for item in net_info %}
{{ item.con_name }}:
dhcp4: no
dhcp6: no
addresses: [{{ item.ip_addr }}]
gateway4: {{ item.ip_gw }}
nameservers:
addresses: [{{ item.ip_dns }}]
{% endfor %}
Jinja2 템플릿을 이용하여 외부로부터 받은 배열형 변수를 for 문으로 하나씩 꺼내 사용할 수 있습니다.
Jinja2 템플릿에서 제어문이나 반복문을 사용할 때는 다음과 같이 {% ~ %}를 이용합니다.
앤서블에서 변수 확장에는 파이썬으로 작성된 Jinja2 템플릿 엔진을 사용.
원래 플라스크 Flask라는 파이썬의 웹 애플리케이션 프로임워크로 HTML에 동적인 값을 설정할 때 사용되는 템플릿 엔진.
진자의 ‘템플릿의 변수 정보를 확장하고 출력한다’ 일반적인 동작을 앤서블에서는 템플릿 모듈을 사용해 파일을 확장하는 것은 물론이고,
플레이북에 있는 변수 정보를 확장할 때도 진자2를 사용합니다.
ansible@server:~/ansible-project/chapter_10.1/roles/myrole.netplan/tasks$ cat main.yml
---
# tasks file for myrole.netplan
- name: Copy netplan file
ansible.builtin.template:
src: 01-netplan-ansible.yaml.j2
dest: /etc/netplan/01-netplan-ansible.yaml
when: net_info[0].con_name in ansible_facts.interfaces
notify: Netplan apply
emplate 모듈을 이용하여 앞에서 생성한 템플릿 파일을 대상 호스트에 복사합니다.
이때 when 구문을 이용하여 외부로부터 받은 인터페이스가 앤서블 팩트에 존재하는지 확인합니다.
템플릿 복사가 잘 되면 notify 키워드를 사용하여 핸들러를 호출합니다.
ansible@server:~/ansible-project/chapter_10.1/roles/myrole.netplan/handlers$ cat main.yml
---
# handlers file for myrole.netplan
- name: Netplan apply
ansible.builtin.command: netplan apply
마지막으로 롤을 호출할 메인 플레이북을 작성
메인 플레이북에는 롤에 전달할 변수들을 vars 섹션에 선언하고 tasks 섹센에 롤을 추가합니다.
이때 ansible.builtin.include_role 모듈을 이용하여 롤을 호출하면 when 구문을 함께 사용할 수 있습니다.
이렇게 앤서블 팩트에서 수집한 OS 버전에 따라 해당 롤을 호출할 수 있습니다.
ansible@server:~/ansible-project/chapter_10.1/roles/myrole.netplan/handlers$ cd ~/ansible-project/chapter_10.1
touch set_ip.yml
ansible@server:~/ansible-project/chapter_10.1$ vi set_ip.yml
ansible@server:~/ansible-project/chapter_10.1$ cat set_ip.yml
---
- hosts: tnode1
vars:
fedora_os:
- CentOS
- RedHat
net_info:
- con_name: ens5
ip_addr: 10.10.1.11/24
ip_gw: 10.10.1.1
ip_dns: 127.0.0.53
tasks:
- name: Include role in CentOS and RedHat
ansible.builtin.include_role:
name: myrole.nmcli
when: ansible_facts.distribution in fedora_os
- name: Include role in Ubuntu
ansible.builtin.include_role:
name: myrole.netplan
when: ansible_facts.distribution == "Ubuntu"
- hosts: tnode2
vars:
fedora_os:
- CentOS
- RedHat
net_info:
- con_name: ens7
ip_addr: 10.10.1.12/24
ip_gw: 10.10.1.1
ip_dns: 127.0.0.53
tasks:
- name: Include role in CentOS and RedHat
ansible.builtin.include_role:
name: myrole.nmcli
when: ansible_facts.distribution in fedora_os
- name: Include role in Ubuntu
ansible.builtin.include_role:
name: myrole.netplan
when: ansible_facts.distribution == "Ubuntu"
ansible@server:~/ansible-project/chapter_10.1$ ssh tnode1 ls /etc/netplan
50-cloud-init.yaml
ansible@server:~/ansible-project/chapter_10.1$ ssh tnode1 cat /etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by the datasource. Changes
# to it will not persist across an instance reboot. To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
ethernets:
ens5:
dhcp4: true
dhcp6: false
match:
macaddress: 02:dd:05:9b:2c:26
set-name: ens5
version: 2
ansible@server:~/ansible-project/chapter_10.1$ ssh tnode1 ip -br -c addr
lo UNKNOWN 127.0.0.1/8 ::1/128
ens5 UP 10.10.1.11/24 metric 100 fe80::dd:5ff:fe9b:2c26/64
ansible@server:~/ansible-project/chapter_10.1$ ssh tnode1 ip -c route
default via 10.10.1.1 dev ens5 proto dhcp src 10.10.1.11 metric 100
10.10.0.2 via 10.10.1.1 dev ens5 proto dhcp src 10.10.1.11 metric 100
10.10.1.0/24 dev ens5 proto kernel scope link src 10.10.1.11 metric 100
10.10.1.1 dev ens5 proto dhcp scope link src 10.10.1.11 metric 100
ansible@server:~/ansible-project/chapter_10.1$ ssh tnode1 nslookup blog.cloudneta.net
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: blog.cloudneta.net
Address: 52.219.60.116
Name: blog.cloudneta.net
Address: 52.219.60.129
Name: blog.cloudneta.net
Address: 52.219.206.40
Name: blog.cloudneta.net
Address: 52.219.60.92
Name: blog.cloudneta.net
Address: 52.219.60.21
Name: blog.cloudneta.net
Address: 52.219.206.64
Name: blog.cloudneta.net
Address: 52.219.56.9
Name: blog.cloudneta.net
Address: 52.219.146.13
ansible@server:~/ansible-project/chapter_10.1$ ansible -m shell -a "cat /var/log/syslog | grep -i dhcp" tnode1
tnode1 | CHANGED | rc=0 >>
Feb 1 11:00:16 ip-10-10-1-11 dhclient[295]: Internet Systems Consortium DHCP Client 4.4.1
Feb 1 11:00:16 ip-10-10-1-11 dhclient[295]: For info, please visit https://www.isc.org/software/dhcp/
Feb 1 11:00:16 ip-10-10-1-11 dhclient[295]: DHCPDISCOVER on ens5 to 255.255.255.255 port 67 interval 3 (xid=0xbf46a67d)
Feb 1 11:00:16 ip-10-10-1-11 dhclient[295]: DHCPOFFER of 10.10.1.11 from 10.10.1.1
Feb 1 11:00:16 ip-10-10-1-11 dhclient[295]: DHCPREQUEST for 10.10.1.11 on ens5 to 255.255.255.255 port 67 (xid=0x7da646bf)
Feb 1 11:00:16 ip-10-10-1-11 dhclient[295]: DHCPACK of 10.10.1.11 from 10.10.1.1 (xid=0xbf46a67d)
Feb 1 11:00:16 ip-10-10-1-11 systemd-networkd[332]: ens5: DHCPv4 address 10.10.1.11/24 via 10.10.1.1
Feb 1 11:00:16 ip-10-10-1-11 kernel: [ 6.076597] audit: type=1400 audit(1706785209.340:8): apparmor="STATUS" operation="profile_load" profile="unconfined" name="/usr/lib/NetworkManager/nm-dhcp-client.action" pid=257 comm="apparmor_parser"
Feb 1 11:00:16 ip-10-10-1-11 kernel: [ 6.078154] audit: type=1400 audit(1706785209.344:9): apparmor="STATUS" operation="profile_load" profile="unconfined" name="/usr/lib/NetworkManager/nm-dhcp-helper" pid=257 comm="apparmor_parser"
Feb 1 13:13:38 ip-10-10-1-11 python3[4012]: ansible-ansible.legacy.command Invoked with _raw_params=cat /var/log/syslog | grep -i dhcp _uses_shell=True stdin_add_newline=True strip_empty_ends=True argv=None chdir=None executable=None creates=None removes=None stdin=None
ansible@server:~/ansible-project/chapter_10.1$ ssh tnode1 sudo dhclient -v ens5
Internet Systems Consortium DHCP Client 4.4.1
Copyright 2004-2018 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Listening on LPF/ens5/02:dd:05:9b:2c:26
Sending on LPF/ens5/02:dd:05:9b:2c:26
Sending on Socket/fallback
DHCPDISCOVER on ens5 to 255.255.255.255 port 67 interval 3 (xid=0x1dcce82b)
DHCPDISCOVER on ens5 to 255.255.255.255 port 67 interval 5 (xid=0x1dcce82b)
DHCPOFFER of 10.10.1.11 from 10.10.1.1
DHCPREQUEST for 10.10.1.11 on ens5 to 255.255.255.255 port 67 (xid=0x2be8cc1d)
DHCPACK of 10.10.1.11 from 10.10.1.1 (xid=0x1dcce82b)
RTNETLINK answers: File exists
bound to 10.10.1.11 -- renewal in 1565 seconds.
ansible@server:~/ansible-project/chapter_10.1$ ansible-playbook --syntax-check set_ip.yml
playbook: set_ip.yml
ansible@server:~/ansible-project/chapter_10.1$ ansible-playbook set_ip.yml
PLAY [tnode1] *****************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [tnode1]
TASK [Include role in CentOS and RedHat] **************************************************************************************************************************************************************************************
skipping: [tnode1]
TASK [Include role in Ubuntu] *************************************************************************************************************************************************************************************************
TASK [myrole.netplan : Copy netplan file] *************************************************************************************************************************************************************************************
changed: [tnode1]
RUNNING HANDLER [myrole.netplan : Netplan apply] ******************************************************************************************************************************************************************************
changed: [tnode1]
PLAY [tnode2] *****************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [tnode2]
TASK [Include role in CentOS and RedHat] **************************************************************************************************************************************************************************************
skipping: [tnode2]
TASK [Include role in Ubuntu] *************************************************************************************************************************************************************************************************
TASK [myrole.netplan : Copy netplan file] *************************************************************************************************************************************************************************************
skipping: [tnode2]
PLAY RECAP ********************************************************************************************************************************************************************************************************************
tnode1 : ok=3 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
tnode2 : ok=1 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
ansible@server:~/ansible-project/chapter_10.1$ ssh tnode1 ls /etc/netplan
01-netplan-ansible.yaml
50-cloud-init.yaml
ansible@server:~/ansible-project/chapter_10.1$ ssh tnode1 cat /etc/netplan/01-netplan-ansible.yaml
# This is the network config written by 'ansible'
network:
version: 2
ethernets:
ens5:
dhcp4: no
dhcp6: no
addresses: [10.10.1.11/24]
gateway4: 10.10.1.1
nameservers:
addresses: [127.0.0.53]
ansible@server:~/ansible-project/chapter_10.1$ ssh tnode1 ip -br -c addr
lo UNKNOWN 127.0.0.1/8 ::1/128
ens5 UP 10.10.1.11/24 fe80::dd:5ff:fe9b:2c26/64
ansible@server:~/ansible-project/chapter_10.1$ ssh tnode1 ip -c route
default via 10.10.1.1 dev ens5 proto static
default via 10.10.1.1 dev ens5 proto dhcp src 10.10.1.11 metric 100
10.10.0.2 via 10.10.1.1 dev ens5 proto dhcp src 10.10.1.11 metric 100
10.10.1.0/24 dev ens5 proto kernel scope link src 10.10.1.11
10.10.1.1 dev ens5 proto dhcp scope link src 10.10.1.11 metric 100
ansible@server:~/ansible-project/chapter_10.1$ ssh tnode1 nslookup blog.cloudneta.net
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: blog.cloudneta.net
Address: 52.219.146.68
Name: blog.cloudneta.net
Address: 52.219.60.72
Name: blog.cloudneta.net
Address: 52.219.146.25
Name: blog.cloudneta.net
Address: 52.219.202.24
Name: blog.cloudneta.net
Address: 52.219.146.60
Name: blog.cloudneta.net
Address: 52.219.146.13
Name: blog.cloudneta.net
Address: 52.219.204.60
Name: blog.cloudneta.net
Address: 52.219.58.153
ansible.builtin.hostname
모듈을 사용한다.ansible.builtin.lineinfile
모듈을 사용한다.ansible.builtin.hostname
모듈 https://docs.ansible.com/ansible/latest/collections/ansible/builtin/hostname_module.html
ansible.builtin.lineinfile
모듈 https://docs.ansible.com/ansible/latest/collections/ansible/builtin/lineinfile_module.html
ansible@server:~/ansible-project/chapter_10.1$ mkdir ~/ansible-project/chapter_10.2
cd ~/ansible-project/chapter_10.2
ansible@server:~/ansible-project/chapter_10.2$ cat <<EOT> ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ansible
ask_pass = false
inject_facts_as_vars = false
roles_path = ./roles
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
EOT
ansible@server:~/ansible-project/chapter_10.2$ cat <<EOT> inventory
[tnode]
tnode1
tnode2
tnode3
EOT
ansible@server:~/ansible-project/chapter_10.2$ touch ~/ansible-project/chapter_10.2/vars_hosts_info.yml
ansible@server:~/ansible-project/chapter_10.2$ ll
total 16
drwxrwxr-x 2 ansible ansible 4096 Feb 1 22:29 ./
drwxrwxr-x 5 ansible ansible 4096 Feb 1 22:28 ../
-rw-rw-r-- 1 ansible ansible 226 Feb 1 22:28 ansible.cfg
-rw-rw-r-- 1 ansible ansible 29 Feb 1 22:28 inventory
-rw-rw-r-- 1 ansible ansible 0 Feb 1 22:29 vars_hosts_info.yml
ansible@server:~/ansible-project/chapter_10.2$ cat vars_hosts_info.yml
tnodes:
- hostname: tnode1
fqdn: tnode1.local
net_ip: 10.10.1.11
- hostname: tnode2
fqdn: tnode2.local
net_ip: 10.10.1.12
- hostname: tnode3
fqdn: tnode3.local
net_ip: 10.10.1.13
state=present
)하거나 혹은 삭제(state=absent
)하며, 매칭되는 것이 없다면 line(내용)을 추가합니다.ansible@server:~/ansible-project/chapter_10.2$ touch ~/ansible-project/chapter_10.2/set_hostname.yml
ansible@server:~/ansible-project/chapter_10.2$ cat set_hostname.yml
---
- hosts: tnode
tasks:
- name: Set hostname from inventory
ansible.builtin.hostname:
name: "{{ inventory_hostname }}"
- hosts: all
vars_files: vars_hosts_info.yml
tasks:
- name: Add host ip to hosts
ansible.builtin.lineinfile:
path: /etc/hosts
line: "{{ item.net_ip }} {{ item.hostname }} {{ item.fqdn }}"
regexp: "^{{ item.net_ip }}"
loop: "{{ tnodes }}"
ansible@server:~/ansible-project/chapter_10.2$ ansible -m shell -a "cat /etc/hosts" tnode
tnode1 | CHANGED | rc=0 >>
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
tnode3 | CHANGED | rc=0 >>
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
tnode2 | CHANGED | rc=0 >>
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
ansible@server:~/ansible-project/chapter_10.2$ ansible-playbook --syntax-check set_hostname.yml
playbook: set_hostname.yml
ansible@server:~/ansible-project/chapter_10.2$ ansible-playbook set_hostname.yml
PLAY [tnode] ******************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [tnode3]
ok: [tnode1]
ok: [tnode2]
TASK [Set hostname from inventory] ********************************************************************************************************************************************************************************************
ok: [tnode1]
ok: [tnode2]
ok: [tnode3]
PLAY [all] ********************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [tnode1]
ok: [tnode2]
ok: [tnode3]
TASK [Add host ip to hosts] ***************************************************************************************************************************************************************************************************
changed: [tnode1] => (item={'hostname': 'tnode1', 'fqdn': 'tnode1.local', 'net_ip': '10.10.1.11'})
changed: [tnode3] => (item={'hostname': 'tnode1', 'fqdn': 'tnode1.local', 'net_ip': '10.10.1.11'})
changed: [tnode2] => (item={'hostname': 'tnode1', 'fqdn': 'tnode1.local', 'net_ip': '10.10.1.11'})
changed: [tnode1] => (item={'hostname': 'tnode2', 'fqdn': 'tnode2.local', 'net_ip': '10.10.1.12'})
changed: [tnode3] => (item={'hostname': 'tnode2', 'fqdn': 'tnode2.local', 'net_ip': '10.10.1.12'})
changed: [tnode2] => (item={'hostname': 'tnode2', 'fqdn': 'tnode2.local', 'net_ip': '10.10.1.12'})
changed: [tnode1] => (item={'hostname': 'tnode3', 'fqdn': 'tnode3.local', 'net_ip': '10.10.1.13'})
changed: [tnode3] => (item={'hostname': 'tnode3', 'fqdn': 'tnode3.local', 'net_ip': '10.10.1.13'})
changed: [tnode2] => (item={'hostname': 'tnode3', 'fqdn': 'tnode3.local', 'net_ip': '10.10.1.13'})
PLAY RECAP ********************************************************************************************************************************************************************************************************************
tnode1 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode2 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode3 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible@server:~/ansible-project/chapter_10.2$ ansible -m shell -a "hostname" tnode
tnode3 | CHANGED | rc=0 >>
tnode3
tnode1 | CHANGED | rc=0 >>
tnode1
tnode2 | CHANGED | rc=0 >>
tnode2
ansible@server:~/ansible-project/chapter_10.2$ ansible -m shell -a "cat /etc/hosts | grep tnode" tnode
tnode3 | CHANGED | rc=0 >>
10.10.1.11 tnode1 tnode1.local
10.10.1.12 tnode2 tnode2.local
10.10.1.13 tnode3 tnode3.local
tnode1 | CHANGED | rc=0 >>
10.10.1.11 tnode1 tnode1.local
10.10.1.12 tnode2 tnode2.local
10.10.1.13 tnode3 tnode3.local
tnode2 | CHANGED | rc=0 >>
10.10.1.11 tnode1 tnode1.local
10.10.1.12 tnode2 tnode2.local
10.10.1.13 tnode3 tnode3.local
ansible@server:~/ansible-project/chapter_10.2$ ssh tnode1 ping -c 1 tnode2
PING tnode2 (10.10.1.12) 56(84) bytes of data.
64 bytes from tnode2 (10.10.1.12): icmp_seq=1 ttl=64 time=1.04 ms
--- tnode2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.042/1.042/1.042/0.000 ms
ansible@server:~/ansible-project/chapter_10.2$ ssh tnode1 ping -c 1 tnode3.local
PING tnode3 (10.10.1.13) 56(84) bytes of data.
64 bytes from tnode3 (10.10.1.13): icmp_seq=1 ttl=64 time=0.843 ms
--- tnode3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.843/0.843/0.843/0.000 ms
ansible@server:~/ansible-project/chapter_10.2$ mkdir ~/ansible-project/chapter_10.3
cd ~/ansible-project/chapter_10.3
ansible@server:~/ansible-project/chapter_10.3$ cat <<EOT> ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ansible
ask_pass = false
inject_facts_as_vars = false
roles_path = ./roles
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
EOT
ansible@server:~/ansible-project/chapter_10.3$ cat <<EOT> inventory
[nfs_server]
tnode1
[nfs_client]
tnode2
tnode3
EOT
ansible@server:~/ansible-project/chapter_10.3$ ansible-galaxy role init --init-path ./roles myrole.nfs_server
- Role myrole.nfs_server was created successfully
ansible@server:~/ansible-project/chapter_10.3$ ansible-galaxy role init --init-path ./roles myrole.nfs_client
- Role myrole.nfs_client was created successfully
ansible@server:~/ansible-project/chapter_10.3$ ansible-galaxy role list
# /home/ansible/ansible-project/chapter_10.3/roles
- myrole.nfs_server, (unknown version)
- myrole.nfs_client, (unknown version)
ansible@server:~/ansible-project/chapter_10.3/roles/myrole.nfs_server/vars$ cat main.yml
---
# vars file for myrole.nfs-server
nfs_packages:
- nfs-kernel-server
ansible@server:~/ansible-project/chapter_10.3/roles/myrole.nfs_server/tasks$ cat main.yml
---
# tasks file for myrole.nfs_server
- name: Install NFS packages
ansible.builtin.apt:
name: "{{ item }}"
state: present
loop: "{{ nfs_packages }}"
- name: Create NFS export directory
ansible.builtin.file:
path: "{{ share_path }}"
state: directory
owner: root
group: root
mode: "0755"
- name: Configure NFS exports
ansible.builtin.lineinfile:
path: "/etc/exports"
line: "{{ share_path }} *(rw,sync)"
regexp: "^{{ share_path }}"
state: present
create: true
notify: Restart NFS Service
ansible@server:~/ansible-project/chapter_10.3/roles/myrole.nfs_server/handlers$ cat main.yml
---
# handlers file for myrole.nfs_server
- name: Restart NFS Service
ansible.builtin.service:
name: nfs-server
state: restarted
ansible@server:~/ansible-project/chapter_10.3/roles/myrole.nfs_client/vars$ cat main.yml
---
# vars file for myrole.nfs_client
apt_nfs_packages:
- nfs-common
dnf_nfs_packages:
- nfs-utils
ansible@server:~/ansible-project/chapter_10.3/roles/myrole.nfs_client/tasks$ cat main.yml
---
# tasks file for myrole.nfs-client
- name: Install NFS Packages on Ubuntu
ansible.builtin.apt:
name: "{{ item }}"
update_cache: true
state: present
loop: "{{ apt_nfs_packages }}"
when: ansible_facts.distribution == "Ubuntu"
- name: Install NFS Packages on Rhel
ansible.builtin.dnf:
name: "{{ item }}"
state: present
loop: "{{ dnf_nfs_packages }}"
when: ansible_facts.distribution == "RedHat"
- name: Create Mount Directory
ansible.builtin.file:
path: "{{ mount_path }}"
state: directory
- name: Mount NFS
ansible.posix.mount:
src: "{{ share_server }}:{{ share_path }}"
path: "{{ mount_path }}"
opts: rw,sync
state: mounted
fstype: nfs
ansible@server:~/ansible-project/chapter_10.3/roles/myrole.nfs_client/tasks$ touch ~/ansible-project/chapter_10.3/vars_share_path.yml
ansible@server:~/ansible-project/chapter_10.3$ cat vars_share_path.yml
---
share_server: tnode1
share_path: /mnt/nfs_shares
mount_path: /mnt/nfs_data
ansible@server:~/ansible-project/chapter_10.3$ touch ~/ansible-project/chapter_10.3/set_nfs_storage.yml
ansible@server:~/ansible-project/chapter_10.3$ vi set_nfs_storage.yml
ansible@server:~/ansible-project/chapter_10.3$ cat set_nfs_storage.yml
---
- hosts: nfs_server
vars_files: vars_share_path.yml
roles:
- role: myrole.nfs_server
- hosts: nfs_client
vars_files: vars_share_path.yml
roles:
- role: myrole.nfs_client
ansible@server:~/ansible-project/chapter_10.3$ ssh tnode2 df -h --type nfs4
df: no file systems processed
ansible@server:~/ansible-project/chapter_10.3$ ssh tnode3 df -h --type ext4
Filesystem Size Used Avail Use% Mounted on
/dev/root 29G 1.8G 28G 7% /
ansible@server:~/ansible-project/chapter_10.3$ ansible-playbook --syntax-check set_nfs_storage.yml
playbook: set_nfs_storage.yml
ansible@server:~/ansible-project/chapter_10.3$ ansible-playbook set_nfs_storage.yml
PLAY [nfs_server] *************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [tnode1]
TASK [myrole.nfs_server : Install NFS packages] *******************************************************************************************************************************************************************************
changed: [tnode1] => (item=nfs-kernel-server)
TASK [myrole.nfs_server : Create NFS export directory] ************************************************************************************************************************************************************************
changed: [tnode1]
TASK [myrole.nfs_server : Configure NFS exports] ******************************************************************************************************************************************************************************
changed: [tnode1]
RUNNING HANDLER [myrole.nfs_server : Restart NFS Service] *********************************************************************************************************************************************************************
changed: [tnode1]
PLAY [nfs_client] *************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [tnode3]
ok: [tnode2]
TASK [myrole.nfs_client : Install NFS Packages on Ubuntu] *********************************************************************************************************************************************************************
changed: [tnode3] => (item=nfs-common)
changed: [tnode2] => (item=nfs-common)
TASK [myrole.nfs_client : Install NFS Packages on Rhel] ***********************************************************************************************************************************************************************
skipping: [tnode2] => (item=nfs-utils)
skipping: [tnode2]
skipping: [tnode3] => (item=nfs-utils)
skipping: [tnode3]
TASK [myrole.nfs_client : Create Mount Directory] *****************************************************************************************************************************************************************************
changed: [tnode2]
changed: [tnode3]
TASK [myrole.nfs_client : Mount NFS] ******************************************************************************************************************************************************************************************
changed: [tnode2]
changed: [tnode3]
PLAY RECAP ********************************************************************************************************************************************************************************************************************
tnode1 : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode2 : ok=4 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
tnode3 : ok=4 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
# 실행 후 tnod2, tnode3 NFS 스토리지 마운트 확인
ansible@server:~/ansible-project/chapter_10.3$ ssh tnode2 df -h --type nfs4
Filesystem Size Used Avail Use% Mounted on
tnode1:/mnt/nfs_shares 29G 1.8G 28G 7% /mnt/nfs_data
ansible@server:~/ansible-project/chapter_10.3$ ssh tnode3 df -h --type ext4
Filesystem Size Used Avail Use% Mounted on
/dev/root 29G 1.8G 28G 7% /
ansible@server:~/ansible-project/chapter_10.3$ ssh tnode3 df -h --type nfs4
Filesystem Size Used Avail Use% Mounted on
tnode1:/mnt/nfs_shares 29G 1.8G 28G 7% /mnt/nfs_data
# tnode1에 nfs-server 확인
ansible@server:~/ansible-project/chapter_10.3$ ssh tnode1 systemctl status nfs-server
● nfs-server.service - NFS server and services
Loaded: loaded (/lib/systemd/system/nfs-server.service; enabled; vendor preset: enabled)
Active: active (exited) since Thu 2024-02-01 22:48:14 KST; 1min 53s ago
Process: 6764 ExecStartPre=/usr/sbin/exportfs -r (code=exited, status=0/SUCCESS)
Process: 6765 ExecStart=/usr/sbin/rpc.nfsd (code=exited, status=0/SUCCESS)
Main PID: 6765 (code=exited, status=0/SUCCESS)
CPU: 6ms
ansible@server:~/ansible-project/chapter_10.3$ ssh tnode1 sudo exportfs -s
/mnt/nfs_shares *(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)
root@server:/home/ansible/ansible-project# sudo su - ubuntu
ubuntu@server:~$ ssh tnode2 ls /mnt/nfs_data
ubuntu@server:~$ watch -d "ssh tnode2 ls -l /mnt/nfs_data"
-----
### 기존 터미널
ansible@server:~/ansible-project/chapter_10.3$ ssh tnode1
ansible@tnode1:~$ for i in {1..10}; do sudo touch /mnt/nfs_shares/deleteme.$i; done;
exit
이동 : https://galaxy.ansible.com/ui/standalone/roles/geerlingguy/mysql/
이동 : https://github.com/geerlingguy/ansible-role-mysql
ansible@server:~/ansible-project/chapter_10.3$ mkdir ~/ansible-project/chapter_10.4
cd ~/ansible-project/chapter_10.4
ansible@server:~/ansible-project/chapter_10.4$ cat <<EOT> ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ansible
ask_pass = false
roles_path = ./roles
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
EOT
ansible@server:~/ansible-project/chapter_10.4$ cat <<EOT> inventory
[db]
tnode2
[tnode]
tnode1
tnode2
tnode3
EOT
ansible@server:~/ansible-project/chapter_10.4$ ansible-galaxy role install -p ./roles geerlingguy.mysql
Starting galaxy role install process
- downloading role 'mysql', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-mysql/archive/4.3.4.tar.gz
- extracting geerlingguy.mysql to /home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql
- geerlingguy.mysql (4.3.4) was installed successfully
ansible@server:~/ansible-project/chapter_10.4$ ansible-galaxy role list
# /home/ansible/ansible-project/chapter_10.4/roles
- geerlingguy.mysql, 4.3.4
ansible@server:~/ansible-project/chapter_10.4/roles/geerlingguy.mysql/tasks$ cat main.yml
---
# Variable configuration.
- ansible.builtin.include_tasks: variables.yml
# Setup/install tasks.
- ansible.builtin.include_tasks: setup-RedHat.yml
when: ansible_os_family == 'RedHat'
- ansible.builtin.include_tasks: setup-Debian.yml
when: ansible_os_family == 'Debian'
- ansible.builtin.include_tasks: setup-Archlinux.yml
when: ansible_os_family == 'Archlinux'
- name: Check if MySQL packages were installed.
ansible.builtin.set_fact:
mysql_install_packages: "{{ (rh_mysql_install_packages is defined and rh_mysql_install_packages.changed)
or (deb_mysql_install_packages is defined and deb_mysql_install_packages.changed)
or (arch_mysql_install_packages is defined and arch_mysql_install_packages.changed) }}"
# Configure MySQL.
- ansible.builtin.include_tasks: configure.yml
- ansible.builtin.include_tasks: secure-installation.yml
- ansible.builtin.include_tasks: databases.yml
- ansible.builtin.include_tasks: users.yml
- ansible.builtin.include_tasks: replication.yml
AIX
Alpine
Altlinux
Archlinux
Darwin
Debian -----> Ubuntu 속해있습니다!
FreeBSD
Gentoo
HP-UX
Mandrake
RedHat
SMGL
Slackware
Solaris
Suse
Windows
ansible@server:~/ansible-project/chapter_10.4$ cat install_mysql.yml
---
- hosts: db
roles:
- role: geerlingguy.mysql
ansible@server:~/ansible-project/chapter_10.4$ ansible-playbook --syntax-check install_mysql.yml
## 시뮬레이션
ansible@server:~/ansible-project/chapter_10.4$ ansible-playbook --check install_mysql.yml
PLAY [db] *********************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
included: /home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql/tasks/variables.yml for tnode2
TASK [geerlingguy.mysql : Include OS-specific variables.] *********************************************************************************************************************************************************************
ok: [tnode2] => (item=/home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql/vars/Debian.yml)
TASK [geerlingguy.mysql : Define mysql_packages.] *****************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_daemon.] *******************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_slow_query_log_file.] ******************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_log_error.] ****************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_syslog_tag.] ***************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_pid_file.] *****************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_config_file.] **************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_config_include_dir.] *******************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_socket.] *******************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_supports_innodb_large_prefix.] *********************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
included: /home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql/tasks/setup-Debian.yml for tnode2
TASK [geerlingguy.mysql : Check if MySQL is already installed.] ***************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Update apt cache if MySQL is not yet installed.] ****************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Ensure MySQL Python libraries are installed.] *******************************************************************************************************************************************************
changed: [tnode2]
TASK [geerlingguy.mysql : Ensure MySQL packages are installed.] ***************************************************************************************************************************************************************
changed: [tnode2]
TASK [geerlingguy.mysql : Ensure MySQL is stopped after initial install.] *****************************************************************************************************************************************************
fatal: [tnode2]: FAILED! => {"changed": false, "msg": "Could not find the requested service mysql: host"}
PLAY RECAP ********************************************************************************************************************************************************************************************************************
tnode2 : ok=18 changed=2 unreachable=0 failed=1 skipped=1 rescued=0 ignored=0
-----------------
ansible@server:~/ansible-project/chapter_10.4$ ansible-playbook install_mysql.yml
PLAY [db] *********************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
included: /home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql/tasks/variables.yml for tnode2
TASK [geerlingguy.mysql : Include OS-specific variables.] *********************************************************************************************************************************************************************
ok: [tnode2] => (item=/home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql/vars/Debian.yml)
TASK [geerlingguy.mysql : Define mysql_packages.] *****************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_daemon.] *******************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_slow_query_log_file.] ******************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_log_error.] ****************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_syslog_tag.] ***************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_pid_file.] *****************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_config_file.] **************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_config_include_dir.] *******************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_socket.] *******************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Define mysql_supports_innodb_large_prefix.] *********************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
included: /home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql/tasks/setup-Debian.yml for tnode2
TASK [geerlingguy.mysql : Check if MySQL is already installed.] ***************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Update apt cache if MySQL is not yet installed.] ****************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Ensure MySQL Python libraries are installed.] *******************************************************************************************************************************************************
changed: [tnode2]
TASK [geerlingguy.mysql : Ensure MySQL packages are installed.] ***************************************************************************************************************************************************************
changed: [tnode2]
TASK [geerlingguy.mysql : Ensure MySQL is stopped after initial install.] *****************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Delete innodb log files created by apt package after initial install.] ******************************************************************************************************************************
skipping: [tnode2] => (item=ib_logfile0)
skipping: [tnode2] => (item=ib_logfile1)
skipping: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Check if MySQL packages were installed.] ************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
included: /home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql/tasks/configure.yml for tnode2
TASK [geerlingguy.mysql : Get MySQL version.] *********************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Copy my.cnf global MySQL configuration.] ************************************************************************************************************************************************************
changed: [tnode2]
TASK [geerlingguy.mysql : Verify mysql include directory exists.] *************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Copy my.cnf override files into include directory.] *************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Create slow query log file (if configured).] ********************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Create datadir if it does not exist] ****************************************************************************************************************************************************************
changed: [tnode2]
TASK [geerlingguy.mysql : Set ownership on slow query log file (if configured).] **********************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Create error log file (if configured).] *************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Set ownership on error log file (if configured).] ***************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Ensure MySQL is started and enabled on boot.] *******************************************************************************************************************************************************
changed: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
included: /home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql/tasks/secure-installation.yml for tnode2
TASK [geerlingguy.mysql : Ensure default user is present.] ********************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Copy user-my.cnf file with password credentials.] ***************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Disallow root login remotely] ***********************************************************************************************************************************************************************
ok: [tnode2] => (item=DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'))
TASK [geerlingguy.mysql : Get list of hosts for the root user.] ***************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Update MySQL root password for localhost root account (5.7.x).] *************************************************************************************************************************************
changed: [tnode2] => (item=localhost)
TASK [geerlingguy.mysql : Update MySQL root password for localhost root account (< 5.7.x).] ***********************************************************************************************************************************
skipping: [tnode2] => (item=localhost)
skipping: [tnode2]
TASK [geerlingguy.mysql : Copy .my.cnf file with root password credentials.] **************************************************************************************************************************************************
changed: [tnode2]
TASK [geerlingguy.mysql : Get list of hosts for the anonymous user.] **********************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : Remove anonymous MySQL users.] **********************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Remove MySQL test database.] ************************************************************************************************************************************************************************
ok: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
included: /home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql/tasks/databases.yml for tnode2
TASK [geerlingguy.mysql : Ensure MySQL databases are present.] ****************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
included: /home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql/tasks/users.yml for tnode2
TASK [geerlingguy.mysql : Ensure MySQL users are present.] ********************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : ansible.builtin.include_tasks] **********************************************************************************************************************************************************************
included: /home/ansible/ansible-project/chapter_10.4/roles/geerlingguy.mysql/tasks/replication.yml for tnode2
TASK [geerlingguy.mysql : Ensure replication user exists on master.] **********************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Check slave replication status.] ********************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Check master replication status.] *******************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Configure replication on the slave.] ****************************************************************************************************************************************************************
skipping: [tnode2]
TASK [geerlingguy.mysql : Start replication.] *********************************************************************************************************************************************************************************
skipping: [tnode2]
RUNNING HANDLER [geerlingguy.mysql : restart mysql] ***************************************************************************************************************************************************************************
[WARNING]: Ignoring "sleep" as it is not used in "systemd"
changed: [tnode2]
PLAY RECAP ********************************************************************************************************************************************************************************************************************
tnode2 : ok=36 changed=8 unreachable=0 failed=0 skipped=20 rescued=0 ignored=0
ansible@server:~/ansible-project/chapter_10.4$ ssh tnode2 systemctl status mysql
● mysql.service - MySQL Community Server
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2024-02-01 23:08:10 KST; 1min 12s ago
Process: 8871 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
Main PID: 8879 (mysqld)
Status: "Server is operational"
Tasks: 36 (limit: 4598)
Memory: 345.2M
CPU: 1.479s
CGroup: /system.slice/mysql.service
└─8879 /usr/sbin/mysqld
ansible@server:~/ansible-project/chapter_10.4$ ssh tnode2
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 6.2.0-1018-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Thu Feb 1 23:09:22 KST 2024
System load: 0.2724609375 Processes: 111
Usage of /: 8.1% of 28.89GB Users logged in: 0
Memory usage: 15% IPv4 address for ens5: 10.10.1.12
Swap usage: 0%
* Ubuntu Pro delivers the most comprehensive open source security and
compliance features.
https://ubuntu.com/aws/pro
Expanded Security Maintenance for Applications is not enabled.
2 updates can be applied immediately.
2 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
Last login: Thu Feb 1 23:08:08 2024 from 10.10.1.10
ansible@tnode2:~$ sudo mysql -u root -e "show databases;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
ansible@tnode2:~$ sudo mysql -u root mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.36-0ubuntu0.22.04.1 (Ubuntu)
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> status
--------------
mysql Ver 8.0.36-0ubuntu0.22.04.1 for Linux on x86_64 ((Ubuntu))
Connection id: 8
Current database: mysql
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 8.0.36-0ubuntu0.22.04.1 (Ubuntu)
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: utf8mb4
Conn. characterset: utf8mb4
UNIX socket: /var/run/mysqld/mysqld.sock
Binary data as: Hexadecimal
Uptime: 1 min 47 sec
Threads: 1 Questions: 47 Slow queries: 0 Opens: 1389 Flush tables: 3 Open tables: 49 Queries per second avg: 0.439
--------------
mysql> exit
Bye
ansible@tnode2:~$ exit
logout
Connection to tnode2 closed.