{"id":2134,"date":"2024-06-30T12:03:25","date_gmt":"2024-06-30T10:03:25","guid":{"rendered":"https:\/\/robermb.com\/blog\/?p=2134"},"modified":"2024-06-30T21:36:44","modified_gmt":"2024-06-30T19:36:44","slug":"understanding-and-using-ansible-custom-facts","status":"publish","type":"post","link":"https:\/\/robermb.com\/blog\/geeks\/understanding-and-using-ansible-custom-facts\/","title":{"rendered":"Understanding and Using Ansible Custom Facts"},"content":{"rendered":"\n<p>One of the lesser-known but <strong>extremely<\/strong> <strong>useful<\/strong> <strong>features<\/strong> of <strong>Ansible<\/strong> is the ability to use <strong>custom facts<\/strong>. In this post, we\u2019ll explore what custom facts are, how to create them, and provide a practical example to help you get started.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What are Ansible Custom Facts?<\/h3>\n\n\n\n<p><strong>Ansible facts <\/strong>are <strong>pieces<\/strong> <strong>of<\/strong> <strong>information<\/strong> about remote systems that <strong>Ansible collects when<\/strong> it <strong>runs<\/strong> a <strong>playbook<\/strong>. These facts include details such as <strong>IP addresses<\/strong>, <strong>OS versions<\/strong>, and <strong>hardware<\/strong> <strong>information<\/strong>. <strong>Custom facts<\/strong> allow you to extend this functionality by defining your own facts to meet your <strong>specific<\/strong> <strong>needs<\/strong>. These can be particularly useful for setting environment-specific variables or for custom configuration management tasks.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How to Use Ansible Custom Facts<\/h3>\n\n\n\n<p><strong>Custom facts<\/strong> in Ansible are typically <strong>written<\/strong> in <strong>JSON<\/strong> or <strong>INI<\/strong> <strong>format<\/strong> and placed in specific directories on the remote systems. Here\u2019s a step-by-step guide on how to create and use custom facts in Ansible:<\/p>\n\n\n\n<ul>\n<li><strong>Create<\/strong> the<strong> Template<\/strong> (<code>custom.fact.j2<\/code>) in the&nbsp;<code>templates<\/code>&nbsp;directory.<\/li>\n<\/ul>\n\n\n\n<p>templates\/custom.fact.j2<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"environment\": \"{{ my_env }}\",\n  \"application_version\": \"1.2.3\",\n  \"datacenter\": \"us-west\"\n}<\/code><\/pre>\n\n\n\n<ul>\n<li><strong>Deploy<\/strong> the\u00a0<code>custom.fact<\/code>\u00a0file using the template and make sure that the facts directory exists.<\/li>\n<\/ul>\n\n\n\n<p>Create a playbook that uses the&nbsp;<code>my_env<\/code>&nbsp;variable and the template file to generate and copy the&nbsp;<code>custom.fact<\/code>&nbsp;file to the appropriate hosts, ensuring that the directory&nbsp;<code>\/etc\/ansible\/facts.d<\/code>&nbsp;exists.<\/p>\n\n\n\n<p>Playbook (deploy_custom_facts.yml)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\n- name: Deploy custom facts\n  hosts: all\n  become: yes  # Enable privilege escalation\n  vars:\n    my_env: \"{{ my_env }}\"\n  tasks:\n    - name: Ensure facts directory exists\n      file:\n        path: \/etc\/ansible\/facts.d\n        state: directory\n        mode: '0755'\n\n    - name: Create custom fact from template\n      template:\n        src: templates\/custom.fact.j2\n        dest: \/etc\/ansible\/facts.d\/custom.fact\n        mode: '0644'<\/code><\/pre>\n\n\n\n<p><strong>Access the Custom Facts<\/strong>: Once the custom facts are deployed, you can access them in your playbooks using the&nbsp;<code>ansible_local<\/code>&nbsp;variable. Here\u2019s an example playbook that uses the custom facts:<\/p>\n\n\n\n<p>Playbook (facts_playbook.yml)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\n- name: Use custom facts\n  hosts: all\n  tasks:\n    - name: Print custom facts\n      debug:\n        msg: \"Environment: {{ ansible_local.custom.environment }}, Application Version: {{ ansible_local.custom.application_version }}, Datacenter: {{ ansible_local.custom.datacenter }}\"\n\n    - name: Show Custom Fact in hostvars\n      debug:\n        msg: \"{{ hostvars&#91;ansible_hostname].ansible_local.custom.environment }}\"<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Example:<\/h3>\n\n\n\n<ul>\n<li>Deploying custom facts:<\/li>\n<\/ul>\n\n\n\n<p>Assuming that we are going to deploy the custom fact on the hosts in the <strong>ubuntu<\/strong> <strong>group<\/strong> and the <strong>environment<\/strong> is &#8220;<strong>development<\/strong>&#8220;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ ansible-playbook -i hosts -l ubuntu deploy_custom_facts.yml -e my_env=development<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>PLAY &#91;Deploy custom facts] **********************************************************************************************************************************************************\n\nTASK &#91;Gathering Facts] **************************************************************************************************************************************************************\nok: &#91;ubuntu1]\nok: &#91;ubuntu3]\nok: &#91;ubuntu2]\n\nTASK &#91;Ensure facts directory exists] ************************************************************************************************************************************************\nchanged: &#91;ubuntu1]\nchanged: &#91;ubuntu2]\nchanged: &#91;ubuntu3]\n\nTASK &#91;Create custom fact from template] *********************************************************************************************************************************************\nchanged: &#91;ubuntu1]\nchanged: &#91;ubuntu2]\nchanged: &#91;ubuntu3]\n\nPLAY RECAP **************************************************************************************************************************************************************************\nubuntu1                    : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   \nubuntu2                    : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   \nubuntu3                    : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 <\/code><\/pre>\n\n\n\n<ul>\n<li>Showing custom facts:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>$ ansible-playbook -i hosts -l ubuntu facts_playbook.yml<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>PLAY &#91;Use custom facts] *************************************************************************************************************************************************************\n\nTASK &#91;Gathering Facts] **************************************************************************************************************************************************************\nok: &#91;ubuntu2]\nok: &#91;ubuntu3]\nok: &#91;ubuntu1]\n\nTASK &#91;Print custom facts] ***********************************************************************************************************************************************************\nok: &#91;ubuntu1] => {\n    \"msg\": \"Environment: development, Application Version: 1.2.3, Datacenter: us-west\"\n}\nok: &#91;ubuntu2] => {\n    \"msg\": \"Environment: development, Application Version: 1.2.3, Datacenter: us-west\"\n}\nok: &#91;ubuntu3] => {\n    \"msg\": \"Environment: development, Application Version: 1.2.3, Datacenter: us-west\"\n}\n\nTASK &#91;Show Custom Fact 1 in hostvars] ***********************************************************************************************************************************************\nok: &#91;ubuntu1] => {\n    \"msg\": \"development\"\n}\nok: &#91;ubuntu2] => {\n    \"msg\": \"development\"\n}\nok: &#91;ubuntu3] => {\n    \"msg\": \"development\"\n}\n\nPLAY RECAP **************************************************************************************************************************************************************************\nubuntu1                    : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   \nubuntu2                    : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   \nubuntu3                    : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the lesser-known but extremely useful features of Ansible is the ability to use custom facts. In this post, &hellip; <a href=\"https:\/\/robermb.com\/blog\/geeks\/understanding-and-using-ansible-custom-facts\/\" class=\"more-link\">More <span class=\"screen-reader-text\">Understanding and Using Ansible Custom Facts<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":1806,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[103,2],"tags":[106,112,126],"_links":{"self":[{"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/posts\/2134"}],"collection":[{"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/comments?post=2134"}],"version-history":[{"count":14,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/posts\/2134\/revisions"}],"predecessor-version":[{"id":2155,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/posts\/2134\/revisions\/2155"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/media\/1806"}],"wp:attachment":[{"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/media?parent=2134"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/categories?post=2134"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/tags?post=2134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}