Two of the hottest topics in the Enable Sysadmin community are Podman and Ansible. It's no surprise as both bring compelling features and functionality for a variety of needs. With Podman, you have everything you need to manage your containers and pods, while Ansible offers everything you need to automate all the things. So what would be the product of the sum of the benefits of these two tools? Of course: automated and orchestrated management of your container and pod infrastructure!
Take, for instance, my article How to create multidomain web applications with Podman and Nginx. Although it's a relatively simple setup, imagine you need to replicate it in other environments or scale it to a large number of machines. Needless to say, doing all of that by hand is not practical at all, right? That's why automation is great for doing such things, and that's why I'll show how to use Ansible to automate Podman for container and pod deployments, using my previous article's environment as an example.
[ Download now: A system administrator's guide to IT automation. ]
Automate deploying prerequisites
Since I set out to automate everything, I'll automate creating the directories and files I previously created using this Ansible playbook (prereq.yaml
):
---
- name: "Playbook to create the prerequisites"
hosts: localhost
gather_facts: false
vars:
homedir: /home/localuser
hostip: 192.168.1.30
tasks:
- name: "Create the directories"
ansible.builtin.file:
path: "{{ homedir }}/{{ item }}"
state: directory
loop:
- syscom
- sysorg
- nginx
- name: "Create the httpd syscom file"
ansible.builtin.copy:
dest: "{{ homedir }}/syscom/index.html"
content: |
<html>
<header>
<title>SysAdmin.com</title>
</header>
<body>
<p>This is the SysAdmin website hosted on the .com domain</p>
</body>
</html>
- name: "Create the httpd sysorg file"
ansible.builtin.copy:
dest: "{{ homedir }}/sysorg/index.html"
content: |
<html>
<header>
<title>SysAdmin.org</title>
</header>
<body>
<p>This is the SysAdmin website hosted on the .org domain</p>
</body>
</html>
- name: "Create the Nginx syscom config"
ansible.builtin.copy:
dest: "{{ homedir }}/nginx/syscom.conf"
content: |
server {
listen 80;
server_name sysadmin.com;
location / {
proxy_pass http://{{ hostip }}:8080;
}
}
- name: "Create the Nginx sysorg config"
ansible.builtin.copy:
dest: "{{ homedir }}/nginx/sysorg.conf"
content: |
server {
listen 80;
server_name sysadmin.org;
location / {
proxy_pass http://{{ hostip }}:8081;
}
}
- name: "Create the Nginx default config"
ansible.builtin.copy:
dest: "{{ homedir }}/nginx/default.conf"
content: |
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
[ Write your first playbook in this hands-on interactive lab. ]
Before running it, update variables homedir
and hostip
to match your environment. Then, run the playbook to create the directories and files:
$ ansible-playbook prereq.yaml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Playbook to create the prerequisites] ***********************************
TASK [Create the directories] *************************************************
changed: [localhost] => (item=syscom)
changed: [localhost] => (item=sysorg)
changed: [localhost] => (item=nginx)
TASK [Create the httpd syscom file] *******************************************
changed: [localhost]
TASK [Create the httpd sysorg file] *******************************************
changed: [localhost]
TASK [Create the Nginx syscom config] *****************************************
changed: [localhost]
TASK [Create the Nginx sysorg config] *****************************************
changed: [localhost]
TASK [Create the Nginx default config] ****************************************
changed: [localhost]
PLAY RECAP ********************************************************************
localhost : ok=6 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ls -lR
.:
total 12
drwxr-xr-x. 2 localuser localuser 64 mar 2 13:13 nginx
-rw-r--r--. 1 localuser localuser 2541 mar 2 13:12 prereq.yaml
drwxr-xr-x. 2 localuser localuser 24 mar 2 13:13 syscom
drwxr-xr-x. 2 localuser localuser 24 mar 2 13:13 sysorg
./nginx:
total 12
-rw-r--r--. 1 localuser localuser 311 mar 2 13:13 default.conf
-rw-r--r--. 1 localuser localuser 116 mar 2 13:13 syscom.conf
-rw-r--r--. 1 localuser localuser 116 mar 2 13:13 sysorg.conf
./syscom:
total 4
-rw-r--r--. 1 localuser localuser 163 mar 2 13:13 index.html
./sysorg:
total 4
-rw-r--r--. 1 localuser localuser 163 mar 2 13:13 index.html
To proceed with the next steps, you'll need two distinct Ansible collections: ansible.posix to manipulate kernel parameters with sysctl
; and the collection containers.podman to automate Podman with Ansible. Install both collections:
$ for i in ansible.posix containers.podman; \
do ansible-galaxy collection install $i; \
done
Check the available modules for each of these collections:
$ ansible-doc -l | grep -e posix -e podman
ansible.posix.acl Set and retrieve ...
ansible.posix.at Schedule the exec...
ansible.posix.authorized_key Adds or removes a...
ansible.posix.firewalld Manage arbitrary ...
ansible.posix.firewalld_info Gather informatio...
ansible.posix.mount Control active an...
ansible.posix.patch Apply patch files...
ansible.posix.rhel_facts Facts module to s...
ansible.posix.rhel_rpm_ostree Ensure packages e...
ansible.posix.rpm_ostree_upgrade Manage rpm-ostree...
ansible.posix.seboolean Toggles SELinux b...
ansible.posix.selinux Change policy and...
ansible.posix.synchronize A wrapper around ...
ansible.posix.sysctl Manage entries in...
community.general.udm_user Manage posix user...
containers.podman.podman_container Manage podman con...
containers.podman.podman_container_info Gather facts abou...
containers.podman.podman_containers Manage podman con...
containers.podman.podman_export Export a podman c...
containers.podman.podman_generate_systemd Generate systemd ...
containers.podman.podman_image Pull images for u...
containers.podman.podman_image_info Gather info about...
containers.podman.podman_import Import Podman con...
containers.podman.podman_load Load image from a...
containers.podman.podman_login Login to a contai...
containers.podman.podman_login_info Return the logged...
containers.podman.podman_logout Log out of a cont...
containers.podman.podman_network Manage podman net...
containers.podman.podman_network_info Gather info about...
containers.podman.podman_play Play kubernetes Y...
containers.podman.podman_pod Manage Podman pod...
containers.podman.podman_pod_info Gather info about...
containers.podman.podman_save Saves podman imag...
containers.podman.podman_secret Manage podman sec...
containers.podman.podman_tag Add an additional...
containers.podman.podman_volume Manage Podman vol...
containers.podman.podman_volume_info Gather info about...
I won't detail what each of these modules do, as I'd need several articles for that. Instead, I'll focus on the containers.podman.podman_container
module for creating containers in an automated way.
Automate Podman with Ansible
To automate the creation of Podman containers using Ansible, create a playbook to deploy every single container with its proper parameters (as described in the previous article). Use the specific collections and respective modules for this. You'll also create another playbook to delete all containers when you don't need them anymore. Start with the playbook create_httpd_nginx.yaml
:
---
- name: "Playbook to create two httpd containers with one nginx container as a reverse proxy"
hosts: localhost
gather_facts: yes
vars:
homedir: /home/localuser
container_registry: docker.io/library
tasks:
- name: "Create the syscom container"
containers.podman.podman_container:
name: syscom
hostname: syscom
image: "{{ container_registry }}/httpd"
publish: 8080:80
volume:
- "{{ homedir }}/syscom:/usr/local/apache2/htdocs:Z"
state: started
- name: "Create the sysorg container"
containers.podman.podman_container:
name: sysorg
hostname: sysorg
image: "{{ container_registry }}/httpd"
publish: 8081:80
volume:
- "{{ homedir }}/sysorg:/usr/local/apache2/htdocs:Z"
state: started
- name: "Allow the nginx container to run in the 80 port of the host"
become: true
become_user: root
become_method: sudo
ansible.posix.sysctl:
name: net.ipv4.ip_unprivileged_port_start
value: "80"
sysctl_set: true
reload: true
- name: "Create the nginx container"
containers.podman.podman_container:
name: nginx
hostname: nginx
image: "{{ container_registry }}/nginx"
publish: 80:80
volume:
- "{{ homedir }}/nginx:/etc/nginx/conf.d:Z"
state: started
- name: "Disable the use of lower ports for containers again"
become: true
become_user: root
become_method: sudo
ansible.posix.sysctl:
name: net.ipv4.ip_unprivileged_port_start
value: "1024"
sysctl_set: true
reload: true
Then write a playbook called stop-remove_httpd_nginx.yaml
to stop and remove the containers:
---
- name: "Playbook to delete a container"
hosts: localhost
gather_facts: yes
tasks:
- name: "Stop and remove all containers"
containers.podman.podman_container:
name: "{{ item }}"
state: absent
loop:
- syscom
- sysorg
- nginx
Finally, test your playbooks by creating the containers and validating access to the applications. Use option -K
with the ansible-playbook
command to input the sudo
password, as this playbook changes the kernel setting to allow the Nginx container to bind to privileged port 80:
$ ansible-playbook create_httpd_nginx.yaml -K
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Playbook to create two httpd containers with one nginx container as a reverse proxy]
**********************************************************
TASK [Gathering Facts] ********************************************************
ok: [localhost]
TASK [Create the syscom container] ********************************************
changed: [localhost]
TASK [Create the sysorg container] ********************************************
changed: [localhost]
TASK [Allow the nginx container to run in the 80 port of the host] ************
changed: [localhost]
TASK [Create the nginx container] *********************************************
changed: [localhost]
TASK [Disable the use of lower ports for containers again] ********************
changed: [localhost]
PLAY RECAP ********************************************************************
localhost : ok=6 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2038ad4e5c9e docker.io/library/httpd:latest httpd-foreground 7 seconds ago Up 6 seconds 0.0.0.0:8080->80/tcp syscom
5a01d9bdc5ae docker.io/library/httpd:latest httpd-foreground 5 seconds ago Up 4 seconds 0.0.0.0:8081->80/tcp sysorgp
3c816ebb9bcb docker.io/library/nginx:latest nginx -g daemon o... 3 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp nginx
$ curl http://sysadmin.com
<html>
<header>
<title>SysAdmin.com</title>
</header>
<body>
<p>This is the SysAdmin website hosted on the .com domain</p>
</body>
</html>
$ curl http://sysadmin.org
<html>
<header>
<title>SysAdmin.org</title>
</header>
<body>
<p>This is the SysAdmin website hosted on the .org domain</p>
</body>
</html>
Nice and done. And to delete all of that, run the other playbook:
$ ansible-playbook stop-remove_httpd_nginx.yaml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Playbook to create a container] *****************************************
TASK [Gathering Facts] ********************************************************
ok: [localhost]
TASK [Stop and remove all containers] *****************************************
changed: [localhost] => (item=syscom)
changed: [localhost] => (item=sysorg)
changed: [localhost] => (item=nginx)
PLAY RECAP ********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ curl http://sysadmin.com
curl: (7) Failed to connect to sysadmin.com port 80 after 0 ms: Connection refused
$ curl http://sysadmin.org
curl: (7) Failed to connect to sysadmin.org port 80 after 0 ms: Connection refused
And just like that, you created and deleted the same environment as in my previous article, but faster, by leveraging the power of Ansible for Podman. Explore the other modules available in the containers.podman
collection to take advantage of the facilities it provides even more.
Wrap up
Podman and Ansible are very good tools individually for managing containers and automating all things respectively. They are even better together for enabling automation and orchestration of the container and pod lifecycles in simpler scenarios.
For more sophisticated scaling, orchestration, routing, balancing, and automation of many container-based applications and services, you can use a Kubernetes-based enterprise orchestration platform such as Red Hat OpenShift Container Platform.
저자 소개
Alexon has been working as a Senior Technical Account Manager at Red Hat since 2018, working in the Customer Success organization focusing on Infrastructure and Management, Integration and Automation, Cloud Computing, and Storage Solutions. He is a part of the TAM Practices LATAM team based in São Paulo, Brazil, where his job is partnering with, advocating, trust-advising, and supporting customers in their success goals while making use of the complete portfolio. He also contributes to produce and enhance documentation, knowledge-base articles, blog posts, presentations, webinars, and workshops. He is a member of numerous communities in addition to the Sudoers, like Red Hat Academy and Red Hat Accelerators. When he’s not at work, he enjoys spending quality time with his family (wife, daughter, and cat) and participating in several volunteer jobs.
채널별 검색
오토메이션
기술, 팀, 인프라를 위한 IT 자동화 최신 동향
인공지능
고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트
오픈 하이브리드 클라우드
하이브리드 클라우드로 더욱 유연한 미래를 구축하는 방법을 알아보세요
보안
환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보
엣지 컴퓨팅
엣지에서의 운영을 단순화하는 플랫폼 업데이트
인프라
세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보
애플리케이션
복잡한 애플리케이션에 대한 솔루션 더 보기
오리지널 쇼
엔터프라이즈 기술 분야의 제작자와 리더가 전하는 흥미로운 스토리
제품
- Red Hat Enterprise Linux
- Red Hat OpenShift Enterprise
- Red Hat Ansible Automation Platform
- 클라우드 서비스
- 모든 제품 보기
툴
체험, 구매 & 영업
커뮤니케이션
Red Hat 소개
Red Hat은 Linux, 클라우드, 컨테이너, 쿠버네티스 등을 포함한 글로벌 엔터프라이즈 오픈소스 솔루션 공급업체입니다. Red Hat은 코어 데이터센터에서 네트워크 엣지에 이르기까지 다양한 플랫폼과 환경에서 기업의 업무 편의성을 높여 주는 강화된 기능의 솔루션을 제공합니다.