Lab 4.1 : Ad-hoc Command
"ansible all -m command -a "hostname"
"ansible pod-geralda-managed1 -m setup"
"ansible localhost -m command -a 'id'
ansible localhost -u student -m command -a 'id'"
"ansible pod-geralda-managed1 --become -u student -m copy -a "content='Executed by Ansible\n' dest=/etc/motd"
ansible pod-geralda-managed1 -u student -m command -a 'cat /etc/motd'"
"ssh pod-geralda-managed1"
Lab 4.2 : Manage Ansible Inventory
"mkdir ~/managing-inventory
cd ~/managing-inventory
vim inventory"
....
pod-geralda-controller
[Bogor]
pod-geralda-managed1
[Jakarta]
pod-geralda-managed2
[WebServers]
pod-geralda-managed[1:2]
[Testing]
pod-geralda-managed1
[Development]
pod-geralda-managed2
[Indonesia:children]
Jakarta
Bogor
"ansible all -i inventory --list-hosts
ansible ungrouped -i inventory --list-hosts
ansible pod-geralda-managed1 -i inventory --list-hosts
ansible Development -i inventory --list-hosts
ansible Testing -i inventory --list-hosts
ansible Indonesia -i inventory --list-hosts"
Lab 4.3 : Managing Ansible Configuration Files
"cd ~/
mkdir -p deploy-review
cd deploy-review"
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
remote_user = student
host_key_checking = False
"nano inventory"
...
[servers]
pod-geralda-managed1
pod-geralda-managed2
"ansible servers -m command -a 'id' -k"
"ansible servers -m copy -a "content='This server is managed by Ansible. \n' dest=/etc/motd" --become -k -K"
"ansible servers -m command -a 'cat /etc/motd' -k"
Lab 4.4 : Writing and Running Playbooks
"cd ~/
mkdir -p playbook-basic/files
cd playbook-basic"
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
remote_user = student
"nnao inventory"
...
[web]
pod-geralda-managed1
"echo "This is a test page." > files/index.html" (pod geralda-managed1)
"nano site.yml"
...
---
- name: Install and start Apache 2
hosts: web
become: true
tasks:
- name: apache2 package is present
apt:
name: apache2
state: present
- name: correct index.html is present
copy:
src: ./files/index.html
dest: /var/www/html/index.html
- name: Apache 2 is started
service:
name: apache2
state: started
enabled: true
"ansible-playbook site.yml -k -K"
Lab 4.5 : Managing Variables
"cd ~
mkdir data-variables/
cd data-variables/"
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
remote_user = student
host_key_checking = False
"nano inventory"
...
[webserver]
pod-geralda-managed2
"nano playbook.yml"
...
---
- name: Install and Ensure the Apache2 service started
hosts: webserver
become: true
vars:
web_pkg: apache2
web_service: apache2
python_pkg: python3-urllib3
tasks:
- name: Required packages are installed and up to date
apt:
update_cache: yes
force_apt_get: yes
name:
- "{{ web_pkg }}"
- "{{ python_pkg }}"
state: latest
- name: The {{ web_service }} service is started and enabled
service:
name: "{{ web_service }}"
enabled: true
state: started
- name: Web content is in place
copy:
content: "Hello World! ansible is fun."
dest: /var/www/html/index.html
- name: Verify the web server is accessible
hosts: localhost
tasks:
- name: Testing web server
uri:
url: http://pod-geralda-managed2
status_code: 200
return_content: yes
register: Result
- name: Print Output web server
debug:
var: Result.content
"ansible-playbook --syntax-check playbook.yml"
"ansible-playbook playbook.yml -k -K"
Lab 4.6 : Using Jinja 2 Template
"cd ~
mkdir jinja2-template
cd jinja2-template
vim inventory"
...
[webservers]
pod-geralda-managed1
"vim geralda.html.j2"
...
Hello World!
This is geralda site.
"nano sites.yml"
...
---
- name: install and start apache2
hosts: webservers
become: true
tasks:
- name: ensure apache2 package is present
apt:
name: apache2
state: present
update_cache: yes
force_apt_get: yes
- name: restart apache2 service
service:
name: apache2
state: restarted
enabled: yes
- name: copy index.html
template:
src: geralda.html.j2 # Match your template filename
dest: /var/www/html/geralda.html # Match your username
"ansible-playbook -i inventory site.yml -k -K"
Quiz 1 : Playbook
"cd ~
mkdir quiz-1
cd quiz-1"
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
remote_user = student
host_key_checking = False
"nano inventory"
...
[webservers]
pod-geralda-managed2
"nano quiz-1_playbook.yml"
...
---
- name: Quiz Playbook
hosts: webservers
remote_user: student
become: yes
tasks:
- name: Install required packages
apt:
name:
- apache2
- mariadb-server
- php
- php-mysql
state: latest
update_cache: yes
- name: Ensure services are enabled and running
service:
name: "{{ item }}"
state: started
enabled: yes
loop:
- apache2
- mariadb
- name: Deploy index.php
copy:
content: "Adinusa quiz Playbook - geralda"
dest: /var/www/html/index.php
- name: Verify web server
hosts: localhost
tasks:
- name: Test web service
uri:
url: http://pod-geralda-managed2/index.php
status_code: 200
return_content: yes
register: result
- name: Print result
debug:
var: result.content
"ansible-playbook quiz-1_playbook.yml -k -K"
Quiz 2 : Variables
"cd ~
mkdir quiz-2
cd quiz-2"
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
remote_user = student
host_key_checking = False
"nano inventory"
...
[webserver]
pod-geralda-managed2
"nano quiz-2_variables.yml"
"ansible-playbook quiz-2_variables.yml -k -K"
Quiz 3 : Jinja 2 Template
"cd ~
mkdir quiz-3
cd quiz-3"
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
remote_user = student
host_key_checking = False
"nano inventory"
...
[webservers]
pod-geralda-managed1
pod-geralda-managed2
"nano nginx.list.j2"
...
deb http://nginx.org/packages/ubuntu/ jammy nginx
deb-src http://nginx.org/packages/ubuntu/ jammy nginx
"nano mariadb.list.j2"
...
deb [signed-by=/usr/share/keyrings/mariadb-keyring.gpg] http://mirror.mariadb.org/repo/10.9/ubuntu/ jammy main
"nano quiz-3_j2template.yml"
...
---
- name: Configure repositories and install packages
hosts: webservers
become: true
tasks:
- name: Add Nginx repository
template:
src: nginx.list.j2
dest: /etc/apt/sources.list.d/nginx.list
- name: Add MariaDB repository
template:
src: mariadb.list.j2
dest: /etc/apt/sources.list.d/mariadb.list
- name: Update apt cache
apt:
update_cache: yes
- name: Install specific Nginx and MariaDB versions
apt:
name:
- nginx=1.23.1-1~jammy
- mariadb-server-10.9
- mariadb-client-10.9
state: present
- name: Ensure services are started and enabled
service:
name: "{{ item }}"
state: started
enabled: yes
loop:
- nginx
- mariadb-server
"ansible-playbook quiz-3_j2template.yml -k -K"
Lab 5.1 : Managing Roles
"mkdir -p ~/role-create/roles/myvhost/{files,templates,tasks,handlers}
cd ~/role-create"
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
remote_user = student
host_key_checking = False
"nano inventory"
...
[webservers]
pod-geralda-managed1
pod-geralda-managed2
"ansible-galaxy init roles/myvhost
rm -rf roles/myvhost/{defaults,vars,tests}"
"echo 'simple index vhost1 : pod-geralda' > roles/myvhost/files/html-1/index.html
echo 'simple index vhost2 : pod-geralda' > roles/myvhost/files/html-2/index.html"
"nano roles/myvhost/handlers/main.yml"
...
- name: restart apache2
service:
name: apache2
state: restarted
"nano roles/myvhost/templates/vhost-2.conf.j2"
...
<VirtualHost *:80>
ServerAdmin webmaster@vhost-2.{{ ansible_user }}
ServerName vhost-2.{{ ansible_user }}
DocumentRoot /var/www/vhosts/{{ ansible_user }}-2
ErrorLog ${APACHE_LOG_DIR}/vhost-2-error.log
CustomLog ${APACHE_LOG_DIR}/vhost-2-access.log combined
</VirtualHost>
"nano use-vhost-role.yml"
...
- name: Configure Apache Virtual Hosts
hosts: webservers
become: yes
roles:
- myvhost
"ansible-playbook use-vhost-role.yml --syntax-check"
"ansible-playbook use-vhost-role.yml"
Lab 5.2 : Managing Secrets
"mkdir ~/data-secret && cd ~/data-secret"
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
"nnao inventory"
...
[devservers]
pod-geralda-managed1
"nano secret.yml"
...
username: ansibleuser1
pw: adinusa88
"ansible-vault encrypt secret.yml"
"nano create_users.yml"
...
- name: Buat user dari secret.yml
hosts: devservers
become: true
vars_files:
- secret.yml
tasks:
- name: Buat user
user:
name: "{{ username }}"
password: "{{ pw | password_hash('sha512') }}"
"ansible-playbook --syntax-check --ask-vault-pass create_users.yml"
"echo 'adinusa88' > vault-pass
chmod 600 vault-pass"
"ansible-playbook --vault-password-file=vault-pass create_users.yml -k"
Lab 5.3 : Conditional and Loop
"mkdir ~/conditional-loop && cd ~/conditional-loop"
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
"nano inventory"
...
[database_servers]
pod-geralda-managed2
"nano database_setup.yml"
...
- name: Database Setup play
hosts: database_servers
become: true
vars:
min_ram_size_bytes: 1000000
supported_distros:
- Ubuntu
tasks:
- name: Setup Database tasks on supported hosts w/ Min. RAM
include_tasks: "{{ ansible_distribution }}_database_tasks.yml"
when:
- ansible_distribution in supported_distros
- ansible_memtotal_mb * 1024 * 1024 >= min_ram_size_bytes
- name: Pesan untuk distro tidak didukung
debug:
msg: "{{ inventory_hostname }} adalah {{ ansible_distribution }}, tidak didukung (harus {{ supported_distros }})"
when: ansible_distribution not in supported_distros
- name: Pesan untuk RAM tidak cukup
debug:
msg: "RAM {{ ansible_memtotal_mb }}MB di {{ inventory_hostname }} kurang dari {{ min_ram_size_bytes }} bytes"
when: ansible_memtotal_mb * 1024 * 1024 < min_ram_size_bytes
"nano Ubuntu_database_tasks.yml"
...
- name: Set fact db_service
set_fact:
db_service: mariadb
- name: Install MariaDB dan dependencies
apt:
name:
- mariadb-server
- python3-pymysql
state: present
- name: Start dan enable MariaDB
service:
name: "{{ db_service }}"
state: started
enabled: true
- name: Include task user
include_tasks: database_user_tasks.yml
"nano database_user_tasks.yml"
...
- name: Buat grup izin
group:
name: "{{ item }}"
state: present
loop: "{{ host_permission_groups }}"
- name: Buat user sistem
user:
name: "{{ item.username }}"
groups: "{{ item.role }}"
append: yes
state: present
loop: "{{ user_list }}"
when: item.role in host_permission_groups
- name: Buat user MySQL
mysql_user:
login_user: root
login_unix_socket: /var/run/mysqld/mysqld.sock
name: "{{ item.username }}"
password: "{{ item.password }}"
priv: '*.*:{{ item.access }}'
state: present
loop: "{{ user_list }}"
when: item.role in host_permission_groups
"nano group_vars/database_servers.yml"
...
host_permission_groups:
- dbadmin
- dbuser
"nano group_vars/all.yml"
...
user_list:
- name: Geralda Admin # Ganti dengan nama lengkap Anda
username: geralda
password: adinusa88
access: ALL
role: dbadmin
- name: Geralda User # Ganti dengan nama lengkap Anda
username: geralda
password: adinusa88
access: SELECT
role: dbuser
"ansible-playbook --syntax-check database_setup.yml"
"ansible-playbook database_setup.yml"
Quiz 4 : Roles
"mkdir ~/quiz-4 && cd ~/quiz-4"
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
remote_user = student
host_key_checking = False
"nano inventory"
...
[managed]
pod-geralda-managed1
pod-geralda-managed2
"mkdir -p roles/quiz-roles/{tasks,handlers,templates,files/html-quiz}"
"nano roles/quiz-roles/tasks/main.yml"
...
- name: Install apache2
apt:
name: apache2
state: present
- name: Start dan enable apache2
service:
name: apache2
state: started
enabled: yes
- name: Deploy template konfigurasi
template:
src: quiz-roles.conf.j2
dest: /etc/apache2/sites-available/quiz-roles.conf
- name: Enable konfigurasi
command: a2ensite quiz-roles.conf
notify: restart apache2
- name: Copy konten HTML
copy:
src: html-quiz/
dest: "/var/www/quiz-roles/{{ ansible_hostname }}"
"nano roles/quiz-roles/handlers/main.yml"
...
- name: restart apache2
service:
name: apache2
state: restarted
"nano roles/quiz-roles/templates/quiz-roles.conf.j2"
...
<VirtualHost *:80>
ServerName quiz-roles.{{ ansible_hostname }}-adinusa
DocumentRoot /var/www/quiz-roles/{{ ansible_hostname }}
<Directory /var/www/quiz-roles/{{ ansible_hostname }}>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
"nano roles/quiz-roles/files/html-quiz/index.html"
...
adinusa lab quiz roles - geralda
"nano quiz-4_roles.yml"
...
---
- name: Deploy webserver dengan role
hosts: managed
become: true
roles:
- quiz-roles
"ansible-playbook quiz-4_roles.yml -k"
Quiz 5 : Secrets
"mkdir ~/quiz-5 && cd ~/quiz-5"
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
remote_user = student
host_key_checking = False
"nano inventory"
...
[managed]
pod-geralda-managed1 # Ganti 'geralda' dengan username Anda
pod-geralda-managed2
"nano quiz-Secret.yml"
...
username: geralda # Ganti dengan username lab Anda
passwd: adinusa2023
"ansible-vault encrypt quiz-Secret.yml"
"nano quiz-5_secrets.yml"
...
---
- name: Buat user dari secret terenkripsi
hosts: managed
become: true
vars_files:
- quiz-Secret.yml
tasks:
- name: Buat user dengan password
user:
name: "{{ username }}"
password: "{{ passwd | password_hash('sha512') }}"
state: present
"echo 'adinusa' > quiz-pass
chmod 600 quiz-pass # Pastikan hanya pemilik yang bisa baca!"
"ansible-playbook --vault-password-file=quiz-pass quiz-5_secrets.yml"
Quiz 6 : Loop
"mkdir -p ~/quiz-6/group_vars && cd ~/quiz-6"
"nano group_vars/managed1-host-geralda.yml"
...
list_user_ops_managed1:
- ops1
- ops2
# ... (ops3 sampai ops50)
- ops50
list_user_dev_managed1:
- dev1
- dev2
# ... (dev3 sampai dev50)
- dev50
" nano group_vars/managed2-host-geralda.yml"
...
list_user_ops_managed2:
- ops51
- ops52
# ... (ops53 sampai ops100)
- ops100
list_user_dev_managed2:
- dev51
- dev52
# ... (dev53 sampai dev100)
- dev100
"nano inventory"
...
[managed1-host-geralda]
pod-geralda-managed1
[managed2-host-geralda]
pod-geralda-managed2
"nano secret.yml"
...
pass: adinusa88
"ansible-vault encrypt secret.yml --vault-password-file=vault-pass"
"nano quiz-6_loop.yml"
...
---
- name: Create users with loop
hosts: managed1-host-geralda,managed2-host-geralda
become: true
vars_files:
- secret.yml
tasks:
- name: Create users on managed1
user:
name: "{{ item }}"
password: "{{ pass | password_hash('sha512') }}"
state: present
loop: "{{ list_user_ops_managed1 + list_user_dev_managed1 }}"
when: inventory_hostname == 'pod-geralda-managed1'
- name: Create users on managed2
user:
name: "{{ item }}"
password: "{{ pass | password_hash('sha512') }}"
state: present
loop: "{{ list_user_ops_managed2 + list_user_dev_managed2 }}"
when: inventory_hostname == 'pod-geralda-managed2'
"nano ansible.cfg"
...
[defaults]
inventory = ./inventory
remote_user = geralda
host_key_checking = False
"ansible-playbook --vault-password-file=vault-pass quiz-6_loop.yml -k"
Lab 6.1 : Handling Task Failure
"mkdir managing-task-failure
cd managing-task-failure"
"nano ansible.cfg"
...
cat > ansible.cfg << EOF
[defaults]
inventory=inventory
remote_user=student
[privilege_escalation]
become=True
become_ask_pass=false
EOF
"nano inventory"
...
cat > inventory << EOF
[managed]
pod-geralda-managed1
EOF
"nano task-failure.yml"
...
cat > task-failure.yml << EOF
---
- name: Lab Task Failure
hosts: managed
vars:
web_pkg: apache
db_pkg: mariadb-server
db_svc: mariadb
tasks:
- name: Install {{ web_pkg }} package
apt:
name: "{{ web_pkg }}"
state: present
- name: Install {{ db_pkg }} package
apt:
name: "{{ db_pkg }}"
state: present
EOF
"ansible-playbook task-failure.yml -k"
Lab 6.2 : Implementing Handlers
"mkdir managing-handlers
cd managing-handlers"
"nano ansible.cfg"
...
[defaults]
inventory=inventory
remote_user=student
[privilege_escalation]
become=True
become_ask_pass=False
"nano inventory"
...
[managed]
pod-geralda-managed1
"nano installing_mariaDB.yml"
...
---
- name: Install mariaDB server
hosts: managed
vars:
required_pkgs:
- mariadb-server
- python3-pymysql
db_user: geralda
db_pw: adinusa
db_socket: /var/run/mysqld/mysqld.sock
tasks:
- name: "{{ required_pkgs }} packages are installed"
apt:
name: "{{ required_pkgs }}"
state: present
notify: restart service mariadb
- name: task that force handlers to run imediately
meta: flush_handlers
- name: set mariaDB user and password
mysql_user:
login_unix_socket: "{{ db_socket }}"
login_host: localhost
login_user: root
login_password: ''
name: "{{ db_user }}"
password: "{{ db_pw }}"
priv: "*.*:ALL,GRANT"
state: present
host: localhost
no_log: yes
notify: restart service mariadb
- name: add a data for database
copy:
src: ./dump.sql
dest: /tmp/dump.sql
notify:
- create database
- restart service mariadb
- name: task that force handlers to run imediately
meta: flush_handlers
- name: check if DB exists
shell: mysql --host=localhost --user={{ db_user }} --password={{ db_pw }} -e 'SHOW DATABASES;'
register: dbstatus
- name: show list existed databases
debug:
var: dbstatus.stdout_lines
handlers:
- name: restart service mariadb
service:
name: mariadb
state: restarted
enabled: yes
- name: create a new database
mysql_db:
name: testdb
state: present
login_unix_socket: "{{ db_socket }}"
login_user: "{{ db_user }}"
login_password: "{{ db_pw }}"
listen: "create database"
- name: insert a data into database
mysql_db:
name: testdb
state: import
target: /tmp/dump.sql
login_unix_socket: "{{ db_socket }}"
login_user: "{{ db_user }}"
login_password: "{{ db_pw }}"
listen: "create database"
"nano dump.sql"
...
CREATE TABLE IF NOT EXISTS test (
message varchar(255) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO test(message) VALUES('Adinusa - managing-handlers');
INSERT INTO test(message) VALUES('geralda');
INSERT INTO test(message) VALUES('Ansible is fun');
"ansible-playbook installing_mariaDB.yml -k"
Lab Challenge : Exploring Playbook Ansible
"mkdir challenge-1
cd challenge-1"
"nano ansible.cfg"
...
[defaults]
inventory=inventory
remote_user=student
[privilege_escalation]
become=True
become_ask_pass=False
"nano inventory"
...
[managed]
pod-geralda-managed1
"nano laravel.yaml"
...
---
- name: Deploy Laravel 8 Ecommerce
hosts: managed
become: true
vars:
app_dir: /var/www/laravel-8-ecommerce
tasks:
- name: Update apt cache
apt:
update_cache: yes
- name: Install required packages
apt:
name:
- php8.1
- php8.1-cli
- php8.1-mbstring
- php8.1-xml
- php8.1-curl
- php8.1-zip
- php8.1-mysql
- libapache2-mod-php8.1
- apache2
- mysql-server
- npm
- git
- unzip
- curl
state: present
- name: Enable Apache PHP module
shell: a2enmod php8.1
args:
warn: false
- name: Restart Apache to apply PHP 8.1
service:
name: apache2
state: restarted
- name: Install Composer
ansible.builtin.get_url:
url: https://getcomposer.org/installer
dest: /tmp/composer-setup.php
mode: '0755'
- name: Run Composer installer
shell: php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer creates=/usr/local/bin/composer
- name: Ensure app directory exists
file:
path: "{{ app_dir }}"
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Git Clone Laravel
git:
repo: https://github.com/kunal254/laravel-8-ecommerce.git
dest: "{{ app_dir }}"
force: true
update: yes
- name: Install Laravel Dependencies
composer:
command: install
working_dir: "{{ app_dir }}"
no_dev: yes
optimize_autoloader: yes
- name: Copy .env.example to .env
copy:
src: "{{ app_dir }}/.env.example"
dest: "{{ app_dir }}/.env"
remote_src: yes
force: yes
- name: Generate Laravel key
shell: php artisan key:generate
args:
chdir: "{{ app_dir }}"
- name: Set permissions for storage and bootstrap/cache
file:
path: "{{ app_dir }}/{{ item }}"
state: directory
owner: www-data
group: www-data
mode: '0775'
loop:
- storage
- bootstrap/cache
- name: Ensure MySQL is running
service:
name: mysql
state: started
enabled: yes
- name: Create database for laravel
mysql_db:
name: laravel
state: present
- name: Update .env DB settings
lineinfile:
path: "{{ app_dir }}/.env"
regexp: '^DB_(DATABASE|USERNAME|PASSWORD|HOST)='
line: "{{ item }}"
with_items:
- 'DB_DATABASE=laravel'
- 'DB_USERNAME=root'
- 'DB_PASSWORD='
- 'DB_HOST=127.0.0.1'
- name: Run Laravel migrations
shell: php artisan migrate --force
args:
chdir: "{{ app_dir }}"
- name: Build frontend assets
shell: npm install && npm run build
args:
chdir: "{{ app_dir }}"
environment:
HOME: /root
- name: Set Apache document root to Laravel public
copy:
dest: /etc/apache2/sites-available/000-default.conf
content: |
<VirtualHost *:80>
DocumentRoot {{ app_dir }}/public
<Directory {{ app_dir }}/public>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
notify: Restart Apache
handlers:
- name: Restart Apache
service:
name: apache2
state: restarted
"ansible-playbook -i inventory laravel.yaml -k"

Comments
Post a Comment