{"id":7612,"date":"2023-12-04T10:54:20","date_gmt":"2023-12-04T16:54:20","guid":{"rendered":"https:\/\/gregsowell.com\/?p=7612"},"modified":"2023-12-04T10:59:57","modified_gmt":"2023-12-04T16:59:57","slug":"create-local-rocky-linux-repository-with-ascender-awx-or-aap","status":"publish","type":"post","link":"https:\/\/gregsowell.com\/?p=7612","title":{"rendered":"Create Local Rocky Linux Repository with Ansible and Ascender, AWX, or AAP"},"content":{"rendered":"<p><a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2023\/12\/thumbnail-template.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2023\/12\/thumbnail-template-300x169.jpg\" alt=\"\" width=\"300\" height=\"169\" class=\"aligncenter size-medium wp-image-7613\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2023\/12\/thumbnail-template-300x169.jpg 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2023\/12\/thumbnail-template-768x432.jpg 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2023\/12\/thumbnail-template-1024x576.jpg 1024w, https:\/\/gregsowell.com\/wp-content\/uploads\/2023\/12\/thumbnail-template.jpg 1280w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Whether for security reasons(you don\u2019t want hosts connecting directly to internet) and\/or for efficiency reasons(uses less of your internet connection), it\u2019s often valuable to create a local repository for your Rocky packages.  In short, keep a local copy of all the Rocky packages you use so that your servers will just pull from there instead of the internet.<\/p>\n<p>You can do that manually via this <a href=\"https:\/\/docs.rockylinux.org\/gemstones\/setup_local_repo\/\">useful article here<\/a>, or you can do it via automation as shown here using ansible playbooks and ascender.<\/p>\n<p>You need a Rocky host with access to the internet, a webserver running on it, and the rsync utility.  If you have the Rocky host, this automation can not only setup the rsync, but it can also install and configure the webserver if you like.<\/p>\n<h2>Demo Video<\/h2>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/-om8WugKTrU?si=Jh1YtJb8R1xFMVHv\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe><\/p>\n<h2>Playbook<\/h2>\n<p>All of my <a href=\"https:\/\/github.com\/gregsowell\/ascender-rocky-local-repo\/\">assets can be found here<\/a>.<br \/>\nThere\u2019s a playbook and a few templates.<\/p>\n<p>I\u2019ll break the playbook down portions of the playbook below:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">  vars:\r\n    # path to webserver directory to hold all files\r\n    web_path: \/var\/www\/local-repo\r\n    \r\n    # path to where scripts and script data should be stored\r\n    script_path: \/opt\/scripts\r\n    \r\n    # how frequent in hours to sync repo\r\n    sync_hours_freq: 4\r\n    \r\n    # would you like to install and configure an nginx webserver \r\n    configure_webserver: true\r\n\r\n    # configure selinux for webserver folder storing repo files\r\n    selinux_config: true\r\n\r\n    # sync the repo immediately instead of waiting for standard time interval\r\n    sync_now: false\r\n\r\n    # exclude objects from repository sync\r\n    # this list was kindly supplied by Jimmy Conner\r\n    repo_exclude: \r\n      - &#039;*\/Devel*&#039;\r\n      - &#039;*\/Live*&#039;\r\n      - &#039;*\/aarch64*&#039;\r\n      - &#039;*\/ppc64le\/*&#039;\r\n      - &#039;*\/s390x\/*&#039;\r\n      - &#039;*\/kickstart\/*&#039;\r\n      - &#039;*\/source\/*&#039;\r\n      - &#039;*\/debug\/*&#039;\r\n      - &#039;*\/images\/*&#039;\r\n      - &#039;*\/isos\/*&#039;\r\n      - &#039;*\/live\/*&#039;\r\n      - &#039;*\/Devel*&#039;\r\n      - &#039;8\/*&#039;\r\n      - &#039;8.4\/*&#039;\r\n      - &#039;8.5\/*&#039;\r\n      - &#039;8.6\/*&#039;\r\n      - &#039;9\/*&#039;\r\n      - &#039;9.0\/*&#039;<\/code><\/pre>\n<p>First I\u2019m setting up several variables.  The path variables are pretty straightforward; where do you want things stored.  The playbook will actually make sure those paths exist, and then place said files based on the templates in the templates folder.<\/p>\n<p>The <em>sync_hours_freq<\/em> variable sets how often the cronjob that does the rsync runs.  I\u2019ve currently got it set to 4 hours, which should be pretty solid.<\/p>\n<p>The <em>configure_webserver<\/em> variable(if set to true) will install an Nginx webserver, setup its config file, and configure the firewall to allow access to the server.<\/p>\n<p><em>selinux_config: true<\/em> will configure the selinux settings for the web root folder if a configure_webserver is also set to true.<\/p>\n<p><em>sync_now<\/em> will(when set to true) start the rsync immediately instead of waiting for the standard interval.  <\/p>\n<p>Last, the <em>repo_exclude<\/em> variable will set up a list of objects in the remote repository to ignore when performing the rsync.  The current list was created by my teammate Jimmy Conner, so be sure to thank him.<\/p>\n<p>The remainder of the playbook is pretty straightforward and well documented, so I\u2019ll skip discussing it here.<\/p>\n<h2>Conclusion<\/h2>\n<p>There are a LOT of benefits to running a local repo, and running this playbook(on average) takes about 40 seconds\u2026so what are you waiting for?  Granted, while the playbook runs quickly, it does take a little while for the rsync to complete, but should have its initial run completed in less than a couple hours.  After that, updates will move fairly rapidly.  As always, please reach out with any questions or comments.<\/p>\n<p>Happy automating and repo-ing!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Whether for security reasons(you don\u2019t want hosts connecting directly to internet) and\/or for efficiency reasons(uses less of your internet connection), it\u2019s often valuable to\u2026<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49],"tags":[],"class_list":["post-7612","post","type-post","status-publish","format-standard","hentry","category-ansible"],"_links":{"self":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/7612","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7612"}],"version-history":[{"count":5,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/7612\/revisions"}],"predecessor-version":[{"id":7618,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/7612\/revisions\/7618"}],"wp:attachment":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7612"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7612"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7612"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}