1 00:00:06,520 --> 00:00:09,190 - This video is about Fact Caching. 2 00:00:09,190 --> 00:00:11,990 So, after fact gathering, facts are kept in-memory 3 00:00:11,990 --> 00:00:15,210 and stay there for the duration of playbook execution. 4 00:00:15,210 --> 00:00:17,520 That is not very efficient, is it? 5 00:00:17,520 --> 00:00:19,670 But it is what is needed 6 00:00:19,670 --> 00:00:23,390 if you need your facts to reflect the accurate state. 7 00:00:23,390 --> 00:00:24,330 If that's not needed, 8 00:00:24,330 --> 00:00:28,237 you can use plugins to enable fact caching. 9 00:00:28,237 --> 00:00:29,510 And when you use a plugin, 10 00:00:29,510 --> 00:00:32,140 facts should be gathered manually or as a scheduled job 11 00:00:32,140 --> 00:00:36,120 that is executed after expiration of the fact cache. 12 00:00:36,120 --> 00:00:38,880 And next, all playbooks can run without fact gathering 13 00:00:38,880 --> 00:00:41,210 and access their facts from the fact cache. 14 00:00:41,210 --> 00:00:42,783 Until the cache has expired, 15 00:00:42,783 --> 00:00:44,670 then you will get an error message 16 00:00:44,670 --> 00:00:46,170 and then you will know 17 00:00:46,170 --> 00:00:48,263 that you need to do fact gathering again. 18 00:00:49,120 --> 00:00:51,480 I have listed all the steps that are required 19 00:00:51,480 --> 00:00:56,113 to set up redis-based fact cache, let me show you. 20 00:00:58,190 --> 00:00:59,950 So, to start with I'd like to show you, 21 00:00:59,950 --> 00:01:01,150 ansible-doc -t cache -l, 22 00:01:04,350 --> 00:01:06,800 where you can see all the different 23 00:01:06,800 --> 00:01:08,853 caching mechanisms that can be used. 24 00:01:09,760 --> 00:01:14,760 Definitely the easiest solutions are either based on redis 25 00:01:15,380 --> 00:01:17,680 or on memcached. 26 00:01:17,680 --> 00:01:21,110 Memcached is quite workable as well. 27 00:01:21,110 --> 00:01:26,110 And hey, ansible-doc -t cache redis, 28 00:01:26,470 --> 00:01:28,483 do we have any usable information? 29 00:01:29,360 --> 00:01:33,220 Well, as you can see it's showing some prefixes, 30 00:01:33,220 --> 00:01:37,360 but not really a very good documentation. 31 00:01:37,360 --> 00:01:39,743 So, let me be your documentation. 32 00:01:40,990 --> 00:01:44,023 To start with sudo dnf install -Y redis. 33 00:01:45,290 --> 00:01:47,120 I'm doing that on a control note 34 00:01:47,120 --> 00:01:49,720 and I'm doing that on a control note for a simple reason, 35 00:01:49,720 --> 00:01:53,780 that that is where you are going to run your fact cache. 36 00:01:53,780 --> 00:01:56,030 Of course, you can use a playbook as well to do this 37 00:01:56,030 --> 00:01:59,000 but hey, this time I'm going for the quick solution 38 00:01:59,000 --> 00:02:01,930 and I am just going to straight 39 00:02:01,930 --> 00:02:05,710 install these different components. 40 00:02:05,710 --> 00:02:10,190 So, sudo systemctl enable -- now redis 41 00:02:11,760 --> 00:02:15,950 will start the redis in-memory database. 42 00:02:15,950 --> 00:02:20,950 Redis in fact is a very simple in-memory key value store. 43 00:02:21,210 --> 00:02:24,740 So, it's a database, an in-memory database 44 00:02:24,740 --> 00:02:27,410 as simple as simple can be. 45 00:02:27,410 --> 00:02:29,460 The next command is an important one. 46 00:02:29,460 --> 00:02:32,390 We see sudo pip3 install redis. 47 00:02:32,390 --> 00:02:35,390 This is where we are using redis 48 00:02:35,390 --> 00:02:39,350 and we are adding redis functionality to Python. 49 00:02:39,350 --> 00:02:42,310 In order to do so we need pip3 install. 50 00:02:42,310 --> 00:02:46,130 You can safely ignore the warning that is shown here. 51 00:02:46,130 --> 00:02:48,840 I do want this redis part 52 00:02:48,840 --> 00:02:52,270 to be available throughout all my system. 53 00:02:52,270 --> 00:02:56,650 So, I am fetching it using sudo functionality. 54 00:02:56,650 --> 00:02:58,810 Now, this is interesting because you will notice 55 00:02:58,810 --> 00:03:01,298 and you will notice it over and over again 56 00:03:01,298 --> 00:03:05,910 in the next lessons that for enhanced functionality 57 00:03:05,910 --> 00:03:08,870 you need to install additional stuff in Python 58 00:03:08,870 --> 00:03:12,100 like right here, this redis stuff. 59 00:03:12,100 --> 00:03:13,920 So, we need to wait for a little bit 60 00:03:13,920 --> 00:03:17,540 until that is done and then we can continue. 61 00:03:17,540 --> 00:03:18,920 So, it is done. 62 00:03:18,920 --> 00:03:23,387 Let's configure this fact cache in ansible.cfg, 63 00:03:24,930 --> 00:03:28,280 and in ansible.cfg you do your fact caching 64 00:03:28,280 --> 00:03:30,930 under the defaults setting. 65 00:03:30,930 --> 00:03:35,070 So, use fact caching is redis 66 00:03:35,070 --> 00:03:39,970 and fact caching timeout 67 00:03:42,340 --> 00:03:47,340 is 3,600 or 36,000 if you want, that really depends. 68 00:03:48,770 --> 00:03:50,130 This fact caching timeout 69 00:03:50,130 --> 00:03:52,530 in fact is a very important parameter 70 00:03:52,530 --> 00:03:55,600 because this is the default timeout that you will be facing. 71 00:03:55,600 --> 00:03:57,960 And by default that will be an hour. 72 00:03:57,960 --> 00:04:01,940 If you want your fact to be more accurate, make it shorter. 73 00:04:01,940 --> 00:04:05,340 If you want your fact cache to be valid for a longer time, 74 00:04:05,340 --> 00:04:06,370 make it longer. 75 00:04:06,370 --> 00:04:10,400 All depends on the dynamics that you want 76 00:04:10,400 --> 00:04:13,420 from your fact cache. 77 00:04:13,420 --> 00:04:17,090 Next, I need to specify fact caching connection 78 00:04:17,090 --> 00:04:21,390 equals localhost:6379 which is the port :0, 79 00:04:24,100 --> 00:04:26,780 where zero is the redis instance. 80 00:04:26,780 --> 00:04:29,100 And that is what we need to do 81 00:04:29,100 --> 00:04:31,610 in order to configure the redis plugin. 82 00:04:31,610 --> 00:04:33,010 Let's get back to the slides 83 00:04:33,010 --> 00:04:35,513 to learn how we are going to use this fact cache. 84 00:04:36,540 --> 00:04:38,240 So, in order to use the fact cache, 85 00:04:38,240 --> 00:04:39,860 first step is to make sure 86 00:04:39,860 --> 00:04:42,450 that you have something in your fact cache. 87 00:04:42,450 --> 00:04:45,540 Then you can use a checkcache.py script, 88 00:04:45,540 --> 00:04:50,490 it is provided in the plugins Git repository directory. 89 00:04:50,490 --> 00:04:53,227 And next you can use ansible-playbook checkfacts.yaml 90 00:04:54,900 --> 00:04:57,530 to check how it is working. 91 00:04:57,530 --> 00:04:58,843 Let me demonstrate this. 92 00:05:00,570 --> 00:05:03,870 So, for your convenience in the Git repository, 93 00:05:03,870 --> 00:05:08,190 there is a separate subdirectory with the name fact cache. 94 00:05:08,190 --> 00:05:09,380 And in fact cache 95 00:05:09,380 --> 00:05:12,950 we have everything that we need for this demo. 96 00:05:12,950 --> 00:05:16,150 So, the first thing I would like to show you is checkcache. 97 00:05:17,512 --> 00:05:21,170 Checkcache is a simple Python script. 98 00:05:21,170 --> 00:05:24,540 And in this simple Python script, 99 00:05:24,540 --> 00:05:28,390 we can see key ansible_facts + kubuntu.2.4 ansible 1. 100 00:05:31,720 --> 00:05:33,030 This is going to work with 101 00:05:33,030 --> 00:05:36,480 the ansible facts that have been cached for ansible 1 102 00:05:36,480 --> 00:05:40,173 and we print ansible_memfree megabytes. 103 00:05:41,180 --> 00:05:42,790 So, what do you think is going to happen 104 00:05:42,790 --> 00:05:44,930 if I run it right now? 105 00:05:44,930 --> 00:05:49,930 I am getting a non-type pretty curious error message 106 00:05:50,240 --> 00:05:52,110 but the thing is that we are addressing 107 00:05:52,110 --> 00:05:54,000 something that does not exist. 108 00:05:54,000 --> 00:05:59,000 Now, I am going to use sudo systemctl status redis. 109 00:06:00,480 --> 00:06:03,430 I wanna make sure that it is up and running, it is. 110 00:06:03,430 --> 00:06:07,360 So, now I'm going to use ansible all -m setup 111 00:06:10,170 --> 00:06:13,620 which is going to populate the fact cache. 112 00:06:13,620 --> 00:06:16,970 And let me run this check cache Python script again 113 00:06:16,970 --> 00:06:19,000 and there we go, we have a value, 123 114 00:06:20,830 --> 00:06:23,480 and this is obtained from the fact cache. 115 00:06:23,480 --> 00:06:25,400 That's the point I want to make here. 116 00:06:25,400 --> 00:06:29,280 So next, we can have a look at checkfacts.yaml 117 00:06:29,280 --> 00:06:31,680 and what do we see in checkfacts.yaml? 118 00:06:31,680 --> 00:06:34,470 We see that gather facts is set to False 119 00:06:34,470 --> 00:06:36,900 and debug anyways is going to use 120 00:06:36,900 --> 00:06:39,470 the variable ansible_facts. 121 00:06:39,470 --> 00:06:41,670 That's a very simple playbook 122 00:06:41,670 --> 00:06:44,920 but it doesn't have to be any more complicated 123 00:06:44,920 --> 00:06:48,260 to show you that fact catching indeed is working. 124 00:06:48,260 --> 00:06:52,860 As you can see and wow, was that fast or wasn't it? 125 00:06:52,860 --> 00:06:54,430 It sure was. 126 00:06:54,430 --> 00:06:56,520 You can see that this playbook 127 00:06:56,520 --> 00:06:58,760 is working from the fact cache. 128 00:06:58,760 --> 00:07:02,000 Do notice that at some point sooner or later, 129 00:07:02,000 --> 00:07:03,840 the fact cache will expire. 130 00:07:03,840 --> 00:07:06,120 And if the fact cache is expired, 131 00:07:06,120 --> 00:07:10,860 you will need to run your fact cache again. 132 00:07:10,860 --> 00:07:14,020 So, it doesn't require a little bit of manual work. 133 00:07:14,020 --> 00:07:15,480 Fact caching is cool, 134 00:07:15,480 --> 00:07:18,240 if you don't need your facts to contain actual values 135 00:07:18,240 --> 00:07:21,710 but there's also a couple of things to watch out for. 136 00:07:21,710 --> 00:07:23,083 Let's go check that out. 137 00:07:24,180 --> 00:07:25,570 So, while using a fact cache, 138 00:07:25,570 --> 00:07:28,000 there's a couple of things to observe. 139 00:07:28,000 --> 00:07:29,900 First, once the fact cache expires, 140 00:07:29,900 --> 00:07:31,760 all playbooks that require facts 141 00:07:31,760 --> 00:07:34,690 and have gather_facts:False will fail, 142 00:07:34,690 --> 00:07:38,690 obviously because they will be facing undefined variables. 143 00:07:38,690 --> 00:07:40,650 So, you might want to run a scheduled job 144 00:07:40,650 --> 00:07:43,250 to refresh the fact cache automatically. 145 00:07:43,250 --> 00:07:46,490 And to ensure that a playbook does not use cache, 146 00:07:46,490 --> 00:07:48,400 but gather facts instead, 147 00:07:48,400 --> 00:07:50,550 you can use ansible-playbook 148 00:07:50,550 --> 00:07:54,299 whatever.yaml with --flush-cache option, 149 00:07:54,299 --> 00:07:56,730 - -flush cache option allows you to use 150 00:07:56,730 --> 00:07:59,860 the actual value of your facts. 151 00:07:59,860 --> 00:08:02,520 And that is something you definitely have to do 152 00:08:02,520 --> 00:08:04,630 if you have playbooks that depend on 153 00:08:04,630 --> 00:08:07,210 for instance the amount of available memory, 154 00:08:07,210 --> 00:08:08,830 that's a very dynamic value. 155 00:08:08,830 --> 00:08:10,240 You really must make sure 156 00:08:10,240 --> 00:08:12,723 that you are using the actual facts.