{"id":15081,"date":"2022-09-26T05:13:35","date_gmt":"2022-09-26T05:13:35","guid":{"rendered":"https:\/\/www.insentragroup.com\/us\/?p=15081"},"modified":"2024-12-13T02:01:26","modified_gmt":"2024-12-13T02:01:26","slug":"introduction-to-ansible-builder","status":"publish","type":"post","link":"https:\/\/www.insentragroup.com\/us\/insights\/geek-speak\/modern-workplace\/introduction-to-ansible-builder\/","title":{"rendered":"Introduction to Ansible Builder\u00a0"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">What is Ansible Builder<\/h2>\n\n\n\n<p><a href=\"https:\/\/www.insentragroup.com\/us\/insights\/geek-speak\/modern-workplace\/ansible-my-new-found-friend\/\">Ansible<\/a> Builder is a command line tool which facilitates the development of Ansible Execution Environments (EEs).<\/p>\n\n\n\n<p>Let&#8217;s take a step back and talk about what Execution Environments are to fully appreciate the concepts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Execution Environments: A Quick Guide<\/h2>\n\n\n\n<p>Before the dawn of the Execution Environments, the Ansible Automation Platform execution system was executing jobs inside bubble wrap to separate processes. There were plenty of issues with this approach, including the requirement for all container-running jobs to execute in privileged mode on Red Hat OpenShift and Kubernetes.<\/p>\n\n\n\n<p>There were other problems, too. Users had a difficult time managing Ansible module dependencies and customised Python virtual environments while using Ansible Content Collections. The concept of Execution Environments, essentially container images which can be used as Ansible control nodes, is the answer to these issues.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Dawn of Ansible<\/h2>\n\n\n\n<p>Ansible Builder was created to automate the creation of Execution Environments so developers, contributors and consumers may benefit from this novel idea (it\u2019s even better when the experts are able to <a href=\"https:\/\/www.insentragroup.com\/us\/services\/professional-services\/\" target=\"_blank\" rel=\"noreferrer noopener\">implement the automation solution<\/a>!). It accomplishes this by utilising both the user-specified dependency information and those defined in other Ansible Content Collections. The container image build will use Ansible Builder to create a directory which serves as the build context and contains the Container file and any additional files required to be added to the image.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installation<\/h2>\n\n\n\n<p>The easiest way to install the ansible-builder is to run the following command:<\/p>\n\n\n\n<p>(Note: If you have Ansible Automation Platform Hub nodes, the builder should be already installed there.)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip3 install ansible-builder        <\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">How to Create Ansible Builder Definition<\/h2>\n\n\n\n<p>The &#8220;definition&#8221; in the realm of Ansible Builder is a YAML file which lists the dependencies at the Collection-level, the base image source and additional components which have to be overridden in the Execution Environment. The definition file is used as the input argument by the ansible-builder build command. It outputs the build context required to create an Execution Environment image, which is then utilised to actually build the final image. The same build context created during the build can be shared with other users to create environments with specific Ansible Collections.<\/p>\n\n\n\n<p>The following example presents a definition file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\nversion: 1\ndependencies:\n  galaxy: requirements.yml\n  python: requirements.txt\n  system: bindep.txt\n \nadditional_build_steps:\n  prepend: |\n    RUN pip3 install --upgrade pip setuptools\n  append:\n    - RUN ls -la \/etc\n<\/code><\/pre>\n\n\n\n<p>The ansible-builder build command will default to execution-environment.yml file. To override this behaviour, specify a different definition file, using -f (or \u2014file) flag.<\/p>\n\n\n\n<p>The elements which would be listed in the dependencies section might either be an absolute path or a relative path from the directory of the Execution Environment definition&#8217;s folder.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The following example requirements.yml file is a legitimate requirements file for the ansible-galaxy collection instal -r&#8230; command, and it contains the following information:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>---\ncollections:\n  - ansible.posix\n  - containers.podman\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>You can verify the file\u2019s configuration using the following command on a test server\/workstation:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>ansible-galaxy collection install -r requirements.yml<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>A Python requirements file for pip instal -r is referenced by the python entry under dependencies. The requirements.txt file might, for instance, have the following information:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code># requirements.txt\npsutil\nansible &gt;= 2.13\nfirewall &gt;= 0.2\n<\/code><\/pre>\n\n\n\n<p>In essence, all the collections\u2019 python dependencies should be added to the requirements.txt file. The python dependencies can be found on the Ansible page describing given module\/collection. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<p>Similarly, to collections, it is possible to test the file using pip3 install -r requirements.txt<\/p>\n\n\n\n<p>If there are any cross-platform requirements, they will be specified in the bindep requirements file. These are handled by bindep before being forwarded to dnf.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gcc\npython3-libselinux &#91;platform:redhat]\npython3            &#91;platform:dpkg]\n<\/code><\/pre>\n\n\n\n<p>The additional build steps section allows you to specify additional commands you can run either before (prepend) or after (append) the main build steps. The syntax must be either a list (as demonstrated by the sample definition file&#8217;s append section) or a multi-line text (as demonstrated in the prepend section).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\nversion: 1\ndependencies:\n  galaxy: requirements.yml\n  python: requirements.txt\n  system: bindep.txt\n \nadditional_build_steps:\n  prepend: |\n    RUN pip3 install --upgrade pip setuptools\n  append:\n    - RUN ls -la \/etc\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Start the Build<\/h2>\n\n\n\n<p>Let&#8217;s run the build command and see what happens! The following execution-environment.yml file will be used to build an execution image with collections required to manage podman containers and to use ansible posix modules.<\/p>\n\n\n\n<p>Ideally, you will create a separate directory with all the files described above. The following command will default to the execution-environment.yml file. The tag indicates the name of the image going to be built.<br>(Note: On Fedora and Red Hat servers, the ansible-builder will default to podman container engine. If another runtime should be used, it can be specific with \u2014container-runtime switch: \u2014container-runtime docker.)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Let's run the build command and see what happens! The following execution-environment.yml file will be used to build an execution image with collections required to manage podman containers and to use ansible posix modules. \nIdeally, you will create a separate directory with all the files described above. The following command will default to the execution-environment.yml file. The tag indicates the name of the image going to be built. \n(Note: On Fedora and Red Hat servers, the ansible-builder will default to podman container engine. If another runtime should be used, it can be specific with \u2014container-runtime switch: \u2014container-runtime docker.)\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>Once the image is built, it can be verified by using the following command:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;root@aap01 builder-firewalld-container]# podman images \nREPOSITORY                       TAG         IMAGE ID      CREATED         SIZE\nlocalhost\/podman_ee_image        latest      bffa0e361ef8  28 minutes ago  1.38 GB\n&lt;none&gt;                           &lt;none&gt;      b45f24b19dd2  30 minutes ago  1.39 GB\n&lt;none&gt;                           &lt;none&gt;      660c1af33d3b  32 minutes ago  819 MB\n&lt;none&gt;                           &lt;none&gt;      9e080b619dd9  47 minutes ago  782 MB\n&lt;none&gt;                           &lt;none&gt;      11cb3941f6c4  47 minutes ago  819 MB\n&lt;none&gt;                           &lt;none&gt;      a961697e193a  53 minutes ago  782 MB\n&lt;none&gt;                           &lt;none&gt;      54d20e308bfd  54 minutes ago  819 MB\nlocalhost\/vmware_ee_image        latest      591c14387c0a  8 days ago      1.68 GB\n&lt;none&gt;                           &lt;none&gt;      38a134fd1b95  8 days ago      1.72 GB\n&lt;none&gt;                           &lt;none&gt;      89b0325abbfd  8 days ago      824 MB\nquay.io\/ansible\/ansible-runner   latest      bec0dc171168  2 months ago    816 MB\nquay.io\/ansible\/ansible-builder  latest      b0348faa7f41  4 months ago    779 MB\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>If you are interested in how the image was put together, you can use the following command:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>podman inspect localhost\/podman_ee_image<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>As you can see in the output above, the podman_ee_image has been successfully built. In case you have the Ansible Automation Hub node, you can use the following command to push it to the Hub:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>podman login aap02.example.net\npodman push &lt;Image Id&gt; aap02.example.net\/podman_ee_image\npodman push bffa0e361ef8 aap02.example.net\/podman_ee_image\nGetting image source signatures\nCopying blob aadc47c09f66 skipped: already exists  \nCopying blob e0808177f5c4 skipped: already exists  \nCopying blob 699491b2659e skipped: already exists  \nCopying blob 6da2fb060681 skipped: already exists  \nCopying blob 5fa5c1c78a8e skipped: already exists  \nCopying blob 101e6c349551 skipped: already exists  \nCopying blob f8fd3a54d485 skipped: already exists  \nCopying blob d4df4b7e8eaf skipped: already exists  \nCopying blob 7dfd83b5170b skipped: already exists  \nCopying blob 32ad5db2dab5 skipped: already exists  \nCopying blob aa621dba5e87 skipped: already exists  \nCopying blob d32c18715b98 skipped: already exists  \nCopying blob a39c6baf08b1 skipped: already exists  \nCopying blob 1d211ae75d27 skipped: already exists  \nCopying blob 869dbc4797e2 skipped: already exists  \nCopying blob c3eeed63d6a9 skipped: already exists  \nCopying blob 2d4417eff75b skipped: already exists  \nCopying blob 22e51cce938f skipped: already exists  \nCopying blob 0e35fc86ad8c skipped: already exists  \nCopying blob 73373610159e skipped: already exists  \nCopying blob de0c9bd7ced9 skipped: already exists  \nCopying blob 5f70bf18a086 skipped: already exists  \nCopying config bffa0e361e done  \nWriting manifest to image destination\nStoring signatures\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>Verify if the image is visible in the AAP Hub\u2019s configuration. Open the browser and navigate to your hub\u2019s address:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"645\" height=\"279\" src=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-25.png\" alt=\"\" class=\"wp-image-15082\" srcset=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-25.png 645w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-25-300x130.png 300w\" sizes=\"(max-width: 645px) 100vw, 645px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>In the Automation Hub, navigate to \u2018Execution Environments\u2019 &gt; \u2018Execution Environments\u2019 and verify if podman_ee_image is visible:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"356\" src=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-26-1024x356.png\" alt=\"\" class=\"wp-image-15083\" srcset=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-26-1024x356.png 1024w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-26-300x104.png 300w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-26-768x267.png 768w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-26.png 1376w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The image is available.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Click on the image and navigate to the \u2018Detail\u2019 tab as indicated below:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"403\" src=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-27-1024x403.png\" alt=\"\" class=\"wp-image-15084\" srcset=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-27-1024x403.png 1024w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-27-300x118.png 300w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-27-768x302.png 768w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-27.png 1366w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Copy the image name after \u2018podman pull\u2019:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>aap02.example.net\/podman_ee_image:latest<\/code><\/pre>\n\n\n\n<p>You will use it to configure the Execution Environment on the controller.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Log into the Ansible Automation Controller node as admin and navigate to \u2018Administration\u2019 &gt; \u2018Execution Environments\u2019. Click \u2018Add\u2019 and input the following configuration:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"339\" src=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-28-1024x339.png\" alt=\"\" class=\"wp-image-15085\" srcset=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-28-1024x339.png 1024w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-28-300x99.png 300w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-28-768x255.png 768w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-28.png 1071w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Click \u2018Save\u2019.<\/li><li>To use the image in the Template, navigate to the template with the playbook\/role utilising the collections specified in the playbook and select \u2018Execution Environment\u2019:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"322\" src=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-29-1024x322.png\" alt=\"\" class=\"wp-image-15086\" srcset=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-29-1024x322.png 1024w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-29-300x94.png 300w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-29-768x241.png 768w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-29.png 1353w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Save the configuration and launch the job. The first run might take more time as the controller will need to pull the execution image:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"333\" src=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-30-1024x333.png\" alt=\"\" class=\"wp-image-15087\" srcset=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-30-1024x333.png 1024w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-30-300x98.png 300w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-30-768x250.png 768w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2022\/09\/image-30.png 1333w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Now you\u2019ve had chance to undertake this brief introduction on Ansible Builder, this officially concludes the guide. It really isn\u2019t that bad of a process!<\/p>\n\n\n\n<p>As always, if you have any questions on Ansible (or any other tech queries), please <a href=\"https:\/\/www.insentragroup.com\/us\/contact\/\">contact us<\/a>.<\/p>\n\n\n\n<p>Happy automating!<\/p>\n\n\n\n<style>\nbody .wp-block-code>code {\n    color: #000;\n    background: #ccc;\n}\n<\/style>\n","protected":false},"excerpt":{"rendered":"<p>What is Ansible Builder? Take a look at this introduction to Ansible to find out!<\/p>\n","protected":false},"author":67,"featured_media":15088,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"content-type":"","footnotes":""},"categories":[19],"tags":[],"class_list":["post-15081","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-workplace","entry"],"_links":{"self":[{"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/posts\/15081","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/users\/67"}],"replies":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/comments?post=15081"}],"version-history":[{"count":5,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/posts\/15081\/revisions"}],"predecessor-version":[{"id":15158,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/posts\/15081\/revisions\/15158"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/media\/15088"}],"wp:attachment":[{"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/media?parent=15081"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/categories?post=15081"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/tags?post=15081"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}