-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmy-super-post.html
559 lines (470 loc) · 42.6 KB
/
my-super-post.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="google-site-verification" content="w_Gq0a37aj_D2iAwIQodXXlrE7Aj8mF8-W5BpUsK6B4" />
<meta name="robots" content="index, follow" />
<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,400;0,700;1,400&family=Source+Sans+Pro:ital,wght@0,300;0,400;0,700;1,400&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="https://www.devlo.io/theme/stylesheet/style.min.css">
<link id="pygments-light-theme" rel="stylesheet" type="text/css"
href="https://www.devlo.io/theme/pygments/arduino.min.css">
<link rel="stylesheet" type="text/css" href="https://www.devlo.io/theme/font-awesome/css/fontawesome.css">
<link rel="stylesheet" type="text/css" href="https://www.devlo.io/theme/font-awesome/css/brands.css">
<link rel="stylesheet" type="text/css" href="https://www.devlo.io/theme/font-awesome/css/solid.css">
<link rel="stylesheet" type="text/css" href="https://www.devlo.io/extra/static/custom.css">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="theme/favicon.ico" type="image/x-icon">
<link href="https://www.devlo.io/feeds/all.atom.xml" type="application/atom+xml" rel="alternate" title="DevLo Software Blog Atom">
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-116740360-1', 'auto');
ga('send', 'pageview');
</script>
<meta name="author" content="Miguel Lopez" />
<meta name="description" content="SaltStack 101, Set up your first Salt-Master and Salt-Minion" />
<meta name="keywords" content="saltstack, aws, cloud">
<meta property="og:site_name" content="DevLo Software Blog"/>
<meta property="og:title" content="Introduction to SaltStack"/>
<meta property="og:description" content="SaltStack 101, Set up your first Salt-Master and Salt-Minion"/>
<meta property="og:locale" content="en_US"/>
<meta property="og:url" content="https://www.devlo.io/my-super-post.html"/>
<meta property="og:type" content="article"/>
<meta property="article:published_time" content="2018-03-22 00:00:00-07:00"/>
<meta property="article:modified_time" content="2018-04-16 00:00:00-07:00"/>
<meta property="article:author" content="https://www.devlo.io/author/miguel-lopez.html">
<meta property="article:section" content="automation"/>
<meta property="article:tag" content="saltstack"/>
<meta property="article:tag" content="aws"/>
<meta property="article:tag" content="cloud"/>
<meta property="og:image" content="/images/Devlo-Logo.png">
<title>DevLo Software Blog – Introduction to SaltStack</title>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script>
(adsbygoogle = window.adsbygoogle || []).push({
google_ad_client: "ca-pub-2119138261035978",
enable_page_level_ads: true
});
</script>
<script>
(function(w,d,s,l,i){
w[l]=w[l]||[];
w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});
var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';
j.async=true;
j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-T32GC6Q');
</script>
</head>
<body class="light-theme">
<noscript>
<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-T32GC6Q" height="0" width="0" style="display:none;visibility:hidden"></iframe>
</noscript>
<aside>
<div>
<a href="https://www.devlo.io/">
<img src="/images/Devlo-Logo.png" alt="" title="">
</a>
<h1>
<a href="https://www.devlo.io/"></a>
</h1>
<p>Lopez Brothers Blog</p>
<div class="authors-profiles">
<div>
<figure>
<img src="https://www.devlo.io/theme/img/miguel.png" alt="Miguel" title="Miguel">
<figcaption>Miguel</figcaption>
</figure>
<ul class="social">
<li>
<a class="sc-linkedin"
href="https://www.linkedin.com/in/lopezm1/"
target="_blank">
<i class="fa-brands fa-linkedin"></i>
</a>
</li>
<li>
<a class="sc-github"
href="https://github.com/lopezm1"
target="_blank">
<i class="fa-brands fa-github"></i>
</a>
</li>
</ul>
</div>
<div>
<figure>
<img src="https://www.devlo.io/theme/img/sergio.png" alt="Sergio" title="Sergio">
<figcaption>Sergio</figcaption>
</figure>
<ul class="social">
<li>
<a class="sc-linkedin"
href="https://www.linkedin.com/in/sergiolopezjr/"
target="_blank">
<i class="fa-brands fa-linkedin"></i>
</a>
</li>
<li>
<a class="sc-github"
href="https://github.com/sergoh"
target="_blank">
<i class="fa-brands fa-github"></i>
</a>
</li>
</ul>
</div>
</div>
<nav>
<ul class="list">
<li>
<a target="_self"
href="https://www.devlo.io/pages/about.html">
About
</a>
</li>
</ul>
</nav>
</div>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle ads-aside"
data-ad-client="ca-pub-2119138261035978"
data-ad-slot="7180191250"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</aside>
<main>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle ads-responsive"
data-ad-client="ca-pub-2119138261035978"
data-ad-slot="7180191250"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<nav>
<a href="https://www.devlo.io/">Home</a>
<a href="/archives.html">Archives</a>
<a href="/categories.html">Categories</a>
<a href="/tags.html">Tags</a>
<a href="https://www.devlo.io/feeds/all.atom.xml">Atom</a>
</nav>
<article class="single">
<header>
<h1 id="my-super-post">Introduction to SaltStack</h1>
<p>
Posted by <a href="https://www.devlo.io/author/miguel-lopez.html">Miguel Lopez</a> on Thu 22 March 2018 in <a href="https://www.devlo.io/category/automation.html">automation</a>
</p>
</header>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle ads-responsive"
data-ad-client="ca-pub-2119138261035978"
data-ad-slot="5952522457"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<div>
<p><em>Technical Environment: SaltStack v2018.3.0 , AWS EC2 (CentOS ami)</em></p>
<p><em>Difficulty: Easy</em></p>
<p><em>Read: 25 minutes</em></p>
<h2><strong>Introduction to SaltStack</strong></h2>
<p>TLDR; SaltStack rocks. Let Salt manage your infrastructure and you’ll look like a hero.</p>
<p>Configuration Management (as it pertains to software infrastructure) is this idea that you have a central node or tool that is responsible for managing the state of each individual node throughout your infrastructure. It makes your life 100% easier by automating startup scripts, ssh-key placement, symlinks, config files and much much more. </p>
<p>Have you ever found yourself in a situation where you’re constantly having to repeat the same tasks on a single VM or fleet of VMs? If so, then configuration management is probably something you need. </p>
<p>In this post, I’ll cover a few topics:</p>
<ul>
<li>Introduction to SaltMaster</li>
<li>How to create a salt master node</li>
<li>How to connect a salt minion to the master node</li>
<li>How to push states from the salt master to the minion</li>
</ul>
<p>Fair warning, all of this article covers how to use SaltStack in an AWS EC2 environment. It should be noted that SaltStack would work perfectly well on Azure, GCM, or any other datacenter model. </p>
<h2><strong>Key Terms</strong></h2>
<p><strong>Salt-Master:</strong> node used control your salt-minions accross your infrastructure. Salt-masters will push a desired state down.</p>
<p><strong>Salt-Minion:</strong> node that is controlled by a Salt-Master.</p>
<p><strong>Salt-State:</strong> a set of instructions passed down to a node. Could be anything from placing an SSH key, downloading yum packages or removing users access.</p>
<h2><strong>Installing Salt-Master</strong></h2>
<p><em>I'll assume you know how to create an EC2 instance and SSH inside</em> </p>
<ol>
<li>Launch EC2 Linux AMI and SSH inside</li>
</ol>
<div class="highlight"><pre><span></span><code><span class="n">ssh</span><span class="w"> </span><span class="n">ec2</span><span class="o">-</span><span class="n">user</span><span class="mf">@10.0.2.254</span><span class="w"> </span><span class="o">-</span><span class="n">i</span><span class="w"> </span><span class="n">privatekey</span><span class="p">.</span><span class="n">pem</span>
</code></pre></div>
<ol>
<li>Use Salt bootstrap script to install the Salt-Master agent</li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master ~</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">cd</span><span class="w"> </span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">ec2</span><span class="o">-</span><span class="k">user</span>
<span class="o">[</span><span class="n">root@salt-master ~</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">curl</span><span class="w"> </span><span class="o">-</span><span class="n">o</span><span class="w"> </span><span class="n">bootstrap</span><span class="o">-</span><span class="n">salt</span><span class="p">.</span><span class="n">sh</span><span class="w"> </span><span class="o">-</span><span class="n">L</span><span class="w"> </span><span class="nl">https</span><span class="p">:</span><span class="o">//</span><span class="n">bootstrap</span><span class="p">.</span><span class="n">saltstack</span><span class="p">.</span><span class="n">com</span>
<span class="o">[</span><span class="n">root@salt-master ~</span><span class="o">]</span><span class="n">#sudo</span><span class="w"> </span><span class="n">sh</span><span class="w"> </span><span class="n">bootstrap</span><span class="o">-</span><span class="n">salt</span><span class="p">.</span><span class="n">sh</span><span class="w"> </span><span class="o">-</span><span class="n">M</span><span class="w"> </span><span class="o">-</span><span class="n">N</span>
</code></pre></div>
<ol>
<li>Verify Salt-Master exists</li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master ~</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">salt</span><span class="o">-</span><span class="n">master</span><span class="w"> </span><span class="o">--</span><span class="n">version</span>
<span class="n">salt</span><span class="o">-</span><span class="n">master</span><span class="w"> </span><span class="mf">2018.3.0</span><span class="w"> </span><span class="p">(</span><span class="n">Oxygen</span><span class="p">)</span>
</code></pre></div>
<h2><strong>Installing Salt-Minions</strong></h2>
<ol>
<li>Create salt directory and the minion_id file</li>
</ol>
<div class="highlight"><pre><span></span><code>sudo -i;
mkdir -p /etc/salt/;
echo "dev-minion-01" > /etc/salt/minion_id;
</code></pre></div>
<ol>
<li>Use Salt bootstrap script to install the Salt-Minion agent</li>
</ol>
<div class="highlight"><pre><span></span><code><span class="nt">cd</span><span class="w"> </span><span class="o">/</span><span class="nt">home</span><span class="o">/</span><span class="nt">ec2-user</span><span class="o">;</span>
<span class="nt">curl</span><span class="w"> </span><span class="nt">-o</span><span class="w"> </span><span class="o">/</span><span class="nt">tmp</span><span class="o">/</span><span class="nt">bootstrap-salt</span><span class="p">.</span><span class="nc">sh</span><span class="w"> </span><span class="nt">-L</span><span class="w"> </span><span class="nt">https</span><span class="o">://</span><span class="nt">bootstrap</span><span class="p">.</span><span class="nc">saltstack</span><span class="p">.</span><span class="nc">com</span><span class="o">;</span>
<span class="nt">sh</span><span class="w"> </span><span class="o">/</span><span class="nt">tmp</span><span class="o">/</span><span class="nt">bootstrap-salt</span><span class="p">.</span><span class="nc">sh</span><span class="w"> </span><span class="nt">-i</span><span class="w"> </span><span class="nt">dev-minion-01</span><span class="w"> </span><span class="nt">-A</span><span class="w"> </span><span class="nt">10</span><span class="p">.</span><span class="nc">0</span><span class="p">.</span><span class="nc">2</span><span class="p">.</span><span class="nc">254</span><span class="o">;</span>
</code></pre></div>
<ul>
<li><code>-i</code> flag is used to pass the name of the minion</li>
<li>
<p><code>-A</code> flag is the IP of the Salt-Master node you wish to register to</p>
</li>
<li>
<p>Verify the Salt-Minion exists</p>
</li>
</ul>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">ec2-user@ip-10-0-1-31 ~</span><span class="o">]</span><span class="err">$</span><span class="w"> </span><span class="n">salt</span><span class="o">-</span><span class="n">minion</span><span class="w"> </span><span class="o">--</span><span class="n">version</span>
<span class="n">salt</span><span class="o">-</span><span class="n">minion</span><span class="w"> </span><span class="mf">2018.3.0</span><span class="w"> </span><span class="p">(</span><span class="n">Oxygen</span><span class="p">)</span>
</code></pre></div>
<h2><strong>Accept Salt-Minion</strong></h2>
<ol>
<li>Head back over to the Salt-Master and check if the key is listed.</li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master ~</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">salt</span><span class="o">-</span><span class="k">key</span><span class="w"> </span><span class="o">-</span><span class="n">L</span>
<span class="n">Accepted</span><span class="w"> </span><span class="nl">Keys</span><span class="p">:</span>
<span class="n">Denied</span><span class="w"> </span><span class="nl">Keys</span><span class="p">:</span>
<span class="n">Unaccepted</span><span class="w"> </span><span class="nl">Keys</span><span class="p">:</span>
<span class="n">dev</span><span class="o">-</span><span class="n">minion</span><span class="o">-</span><span class="mi">01</span>
<span class="n">Rejected</span><span class="w"> </span><span class="nl">Keys</span><span class="p">:</span>
</code></pre></div>
<ol>
<li>By this point you should see your minion key. Accept the key to put it under the Salt-Master's control.</li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master ~</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">salt</span><span class="o">-</span><span class="k">key</span><span class="w"> </span><span class="o">-</span><span class="n">a</span><span class="w"> </span><span class="n">dev</span><span class="o">-</span><span class="n">minion</span><span class="o">-</span><span class="mi">01</span>
<span class="n">The</span><span class="w"> </span><span class="n">following</span><span class="w"> </span><span class="n">keys</span><span class="w"> </span><span class="k">are</span><span class="w"> </span><span class="n">going</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="nl">accepted</span><span class="p">:</span>
<span class="n">Unaccepted</span><span class="w"> </span><span class="nl">Keys</span><span class="p">:</span>
<span class="n">dev</span><span class="o">-</span><span class="n">minion</span><span class="o">-</span><span class="mi">01</span>
<span class="n">Proceed</span><span class="vm">?</span><span class="w"> </span><span class="o">[</span><span class="n">n/Y</span><span class="o">]</span><span class="w"> </span><span class="n">y</span>
<span class="k">Key</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">minion</span><span class="w"> </span><span class="n">dev</span><span class="o">-</span><span class="n">minion</span><span class="o">-</span><span class="mi">01</span><span class="w"> </span><span class="n">accepted</span><span class="p">.</span>
<span class="o">[</span><span class="n">root@salt-master ~</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">salt</span><span class="o">-</span><span class="k">key</span><span class="w"> </span><span class="o">-</span><span class="n">L</span>
<span class="n">Accepted</span><span class="w"> </span><span class="nl">Keys</span><span class="p">:</span>
<span class="n">dev</span><span class="o">-</span><span class="n">minion</span><span class="o">-</span><span class="mi">01</span>
<span class="n">Denied</span><span class="w"> </span><span class="nl">Keys</span><span class="p">:</span>
<span class="n">Unaccepted</span><span class="w"> </span><span class="nl">Keys</span><span class="p">:</span>
<span class="n">Rejected</span><span class="w"> </span><span class="nl">Keys</span><span class="p">:</span>
</code></pre></div>
<p>At this point, your salt-master should be able to communicate to your salt-minion and vice-versa. </p>
<p><em>If you do not see the salt-minion key appear after a minute, head back over to your salt-minion box and run <code>salt-minion debug</code></em></p>
<div class="highlight"><pre><span></span><code>[<span class="nv">ERROR</span><span class="w"> </span>]<span class="w"> </span><span class="nv">The</span><span class="w"> </span><span class="nv">Salt</span><span class="w"> </span><span class="nv">Master</span><span class="w"> </span><span class="nv">has</span><span class="w"> </span><span class="nv">cached</span><span class="w"> </span><span class="nv">the</span><span class="w"> </span><span class="nv">public</span><span class="w"> </span><span class="nv">key</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nv">this</span><span class="w"> </span><span class="nv">node</span>,<span class="w"> </span><span class="nv">this</span><span class="w"> </span><span class="nv">salt</span><span class="w"> </span><span class="nv">minion</span><span class="w"> </span><span class="nv">will</span><span class="w"> </span><span class="k">wait</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="nv">seconds</span><span class="w"> </span><span class="nv">before</span><span class="w"> </span><span class="nv">attempting</span><span class="w"> </span><span class="nv">to</span><span class="w"> </span><span class="nv">re</span><span class="o">-</span><span class="nv">authenticate</span>
[<span class="nv">ERROR</span><span class="w"> </span>]<span class="w"> </span><span class="nv">The</span><span class="w"> </span><span class="nv">Salt</span><span class="w"> </span><span class="nv">Master</span><span class="w"> </span><span class="nv">has</span><span class="w"> </span><span class="nv">cached</span><span class="w"> </span><span class="nv">the</span><span class="w"> </span><span class="nv">public</span><span class="w"> </span><span class="nv">key</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nv">this</span><span class="w"> </span><span class="nv">node</span>,<span class="w"> </span><span class="nv">this</span><span class="w"> </span><span class="nv">salt</span><span class="w"> </span><span class="nv">minion</span><span class="w"> </span><span class="nv">will</span><span class="w"> </span><span class="k">wait</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="nv">seconds</span><span class="w"> </span><span class="nv">before</span><span class="w"> </span><span class="nv">attempting</span><span class="w"> </span><span class="nv">to</span><span class="w"> </span><span class="nv">re</span><span class="o">-</span><span class="nv">authenticate</span>
[<span class="nv">ERROR</span><span class="w"> </span>]<span class="w"> </span><span class="nv">The</span><span class="w"> </span><span class="nv">Salt</span><span class="w"> </span><span class="nv">Master</span><span class="w"> </span><span class="nv">has</span><span class="w"> </span><span class="nv">cached</span><span class="w"> </span><span class="nv">the</span><span class="w"> </span><span class="nv">public</span><span class="w"> </span><span class="nv">key</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nv">this</span><span class="w"> </span><span class="nv">node</span>,<span class="w"> </span><span class="nv">this</span><span class="w"> </span><span class="nv">salt</span><span class="w"> </span><span class="nv">minion</span><span class="w"> </span><span class="nv">will</span><span class="w"> </span><span class="k">wait</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="nv">seconds</span><span class="w"> </span><span class="nv">before</span><span class="w"> </span><span class="nv">attempting</span><span class="w"> </span><span class="nv">to</span><span class="w"> </span><span class="nv">re</span><span class="o">-</span><span class="nv">authenticate</span>
</code></pre></div>
<p>If you see the following error, it means your salt-master and salt-minion might not be able to communicate. Ensure that port 4505-4506 are open between the two instances. </p>
<p><em>Here is how I configured my SG in Terraform</em></p>
<div class="highlight"><pre><span></span><code>resource<span class="w"> </span>"aws_security_group"<span class="w"> </span>"sg_salt_stack"<span class="w"> </span>{
<span class="w"> </span>name<span class="w"> </span>=<span class="w"> </span>"sg_salt_stack"
<span class="w"> </span>vpc_id<span class="w"> </span>=<span class="w"> </span>"<span class="cp">${</span><span class="n">aws_vpc</span><span class="o">.</span><span class="n">sample</span><span class="o">-</span><span class="n">cloud</span><span class="o">-</span><span class="n">vpc</span><span class="o">.</span><span class="n">id</span><span class="cp">}</span>"
<span class="w"> </span>ingress<span class="w"> </span>{
<span class="w"> </span>from_port<span class="w"> </span>=<span class="w"> </span>"4505"
<span class="w"> </span>to_port<span class="w"> </span>=<span class="w"> </span>"4506"
<span class="w"> </span>protocol<span class="w"> </span>=<span class="w"> </span>"tcp"
<span class="w"> </span>self<span class="w"> </span>=<span class="w"> </span>true
<span class="w"> </span>}
<span class="w"> </span>egress<span class="w"> </span>{
<span class="w"> </span>from_port<span class="w"> </span>=<span class="w"> </span>0
<span class="w"> </span>to_port<span class="w"> </span>=<span class="w"> </span>0
<span class="w"> </span>protocol<span class="w"> </span>=<span class="w"> </span>"-1"
<span class="w"> </span>cidr_blocks<span class="w"> </span>=<span class="w"> </span>["0.0.0.0/0"]
<span class="w"> </span>}
<span class="w"> </span>tags<span class="w"> </span>{
<span class="w"> </span>Name<span class="w"> </span>=<span class="w"> </span>"sg_salt_stack"
<span class="w"> </span>}
}
</code></pre></div>
<h2><strong>Configure First Salt State</strong></h2>
<p>Head back over to Salt-Master. First things first, explore what's in side the /etc/salt folder. This is where the Salt-Master configuration files will live. </p>
<ol>
<li>Archive the premade configuration file located at <code>/etc/salt/master</code>. This file is full of instructions and definitions. It's useful to read but hard to maintain, therefore we will keep it around but create our own. </li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master salt</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">mv</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">salt</span><span class="o">/</span><span class="n">master</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">salt</span><span class="o">/</span><span class="n">master</span><span class="p">.</span><span class="n">orig</span>
</code></pre></div>
<ol>
<li>Create your own <code>/etc/salt/master</code> and define the bare minimum.</li>
</ol>
<div class="highlight"><pre><span></span><code><span class="n">timeout</span><span class="o">:</span><span class="w"> </span><span class="mi">60</span>
<span class="n">worker_threads</span><span class="o">:</span><span class="w"> </span><span class="mi">10</span>
<span class="n">ipv6</span><span class="o">:</span><span class="w"> </span><span class="n">False</span>
<span class="n">log_level_logfile</span><span class="o">:</span><span class="w"> </span><span class="n">debug</span>
<span class="n">presence_events</span><span class="o">:</span><span class="w"> </span><span class="kc">true</span>
<span class="err">#</span><span class="w"> </span><span class="n">Master</span><span class="w"> </span><span class="n">file_roots</span><span class="w"> </span><span class="n">configuration</span><span class="o">:</span>
<span class="n">file_roots</span><span class="o">:</span>
<span class="w"> </span><span class="n">base</span><span class="o">:</span>
<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="sr">/srv/salt/</span><span class="n">base</span>
<span class="n">default_include</span><span class="o">:</span><span class="w"> </span><span class="n">master</span><span class="o">.</span><span class="na">d</span><span class="o">/*.</span><span class="n">conf</span>
<span class="n">pillar_roots</span><span class="o">:</span>
<span class="w"> </span><span class="n">base</span><span class="o">:</span>
<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="sr">/srv/</span><span class="n">pillar</span>
<span class="n">module_dirs</span><span class="o">:</span>
<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="sr">/srv/salt/</span><span class="n">_modules</span>
<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="sr">/srv/salt/</span><span class="n">extmods</span>
</code></pre></div>
<p>For the sake of this tutorial, we will only be covering a state that lives in our <code>/srv/salt/base</code> file root. I will not be going <code>modules</code>, <code>pillars</code>, or <code>node_groups</code> just quite yet and will leave those for another post. </p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master salt</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">service</span><span class="w"> </span><span class="n">salt</span><span class="o">-</span><span class="n">master</span><span class="w"> </span><span class="n">restart</span>
</code></pre></div>
<p>Quickly restart the salt-master to load the new configurations. </p>
<ol>
<li>Our first state will live in our <code>base</code> environment. Go ahead and create a folder in the <code>/srv/salt/base</code> location. </li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master salt</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">cd</span><span class="w"> </span><span class="o">/</span><span class="n">srv</span><span class="o">/</span>
<span class="o">[</span><span class="n">root@salt-master srv</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">mkdir</span><span class="w"> </span><span class="n">salt</span>
<span class="o">[</span><span class="n">root@salt-master srv</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">cd</span><span class="w"> </span><span class="n">salt</span><span class="o">/</span>
<span class="o">[</span><span class="n">root@salt-master salt</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">mkdir</span><span class="w"> </span><span class="n">base</span>
<span class="o">[</span><span class="n">root@salt-master salt</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">cd</span><span class="w"> </span><span class="n">base</span>
<span class="o">[</span><span class="n">root@salt-master base</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">pwd</span>
<span class="o">/</span><span class="n">srv</span><span class="o">/</span><span class="n">salt</span><span class="o">/</span><span class="n">base</span>
</code></pre></div>
<p>This will be known as our <code>base</code> enviornment. <code>Base</code> environments are typically states that are applied across your each <code>dev</code>/<code>test</code>/<code>stage</code>/<code>prod</code> environment. I'll also cover how to create environment specific states in a future post. </p>
<ol>
<li>Create a <code>/srv/salt/base/touch-file</code> folder. </li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master base</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">mkdir</span><span class="w"> </span><span class="n">touch</span><span class="o">-</span><span class="k">file</span>
<span class="o">[</span><span class="n">root@salt-master base</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">vi</span><span class="w"> </span><span class="n">init</span><span class="p">.</span><span class="n">sls</span>
<span class="o">[</span><span class="n">root@salt-master base</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">pwd</span>
<span class="o">/</span><span class="n">srv</span><span class="o">/</span><span class="n">salt</span><span class="o">/</span><span class="n">base</span>
</code></pre></div>
<p>This folder will contain our first state that will create a "Hello World" text file on our minion. </p>
<ol>
<li>Inside the <code>touch-file</code> folder, create an <code>init.sls</code> file. Every folder must have an <code>init.sls</code> file. This file will contain the instructions for your state.</li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master base</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">vi</span><span class="w"> </span><span class="n">init</span><span class="p">.</span><span class="n">sls</span>
</code></pre></div>
<ol>
<li>Paste the following text inside. It's important to note that each <code>.sls</code> file is yml based. <strong>This means that spacing and tabs matter.</strong></li>
</ol>
<div class="highlight"><pre><span></span><code>/tmp/hello-world.txt:
file.managed:
- source:
- salt://touch-file/hello-world.txt
</code></pre></div>
<p>This state tells our salt-master to create a file at <code>/tmp/hello-world.txt</code> on our salt-minion box. As a <code>file.managed</code> state, it will create or replace the <code>hello-world.txt</code> file whenever it does not match the <code>hello-world.txt</code> file on the salt-master server. </p>
<p>Be sure to read all about salt-states <a href="https://docs.saltstack.com/en/latest/contents.html">on their official documentation</a></p>
<ol>
<li>Create the <code>hello-world.txt</code> file at <code>/srv/salt/base/touch-file</code></li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master base</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">echo</span><span class="w"> </span><span class="ss">"hello world"</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">hello</span><span class="o">-</span><span class="n">world</span><span class="p">.</span><span class="n">txt</span>
</code></pre></div>
<p>This satisfies the <code>source</code> requirement defined our in <code>init.sls</code> file. </p>
<ol>
<li>The last thing we need to do is create the <code>top.sls</code> file. We will need to <code>cd</code> back to our <code>/srv/salt/base</code>. And create it there. </li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master base</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">vi</span><span class="w"> </span><span class="k">top</span><span class="p">.</span><span class="n">sls</span>
</code></pre></div>
<p>Paste the following text inside. </p>
<div class="highlight"><pre><span></span><code>base:
'*':
- touch-file
</code></pre></div>
<p>The <code>top.sls</code> file will apply the <code>touch-file</code> state we just created to all salt-minions under our control. </p>
<p><code>top.sls</code> files are used to define instructions for all of your environments. It defines which states are applied to a salt-minion. </p>
<p>It's important to note that it can follow a regex pattern or a node-group. This means that it's extremely important to name your salt-minions accordingly. <code>'*'</code> will apply states to all minions whereas <code>'dev*'</code> would only those states to salt-minions prefixed with a <code>dev</code> name. </p>
<ol>
<li>We are now ready to run our first state. Run the following <code>state.show_top</code> command to see which states will be applied.</li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master base</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">salt</span><span class="w"> </span><span class="s1">'*'</span><span class="w"> </span><span class="k">state</span><span class="p">.</span><span class="n">show_top</span>
<span class="n">dev</span><span class="o">-</span><span class="n">minion</span><span class="o">-</span><span class="mi">01</span><span class="err">:</span>
<span class="w"> </span><span class="o">----------</span>
<span class="w"> </span><span class="nl">base</span><span class="p">:</span>
<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">touch</span><span class="o">-</span><span class="k">file</span>
</code></pre></div>
<p><em>I always run <code>state.show_top</code> before running a <code>state.apply</code> to double check my salt-master is doing what I want. I can't stress this enough. It has saved me so many times.</em></p>
<ol>
<li>If everything looks good, run the <code>state.apply</code> command to push the state down to the salt-minion.</li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@salt-master base</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">salt</span><span class="w"> </span><span class="s1">'*'</span><span class="w"> </span><span class="k">state</span><span class="p">.</span><span class="n">apply</span>
<span class="n">dev</span><span class="o">-</span><span class="n">minion</span><span class="o">-</span><span class="mi">01</span><span class="err">:</span>
<span class="o">----------</span>
<span class="w"> </span><span class="nl">ID</span><span class="p">:</span><span class="w"> </span><span class="o">/</span><span class="n">tmp</span><span class="o">/</span><span class="n">hello</span><span class="o">-</span><span class="n">world</span><span class="p">.</span><span class="n">txt</span>
<span class="w"> </span><span class="k">Function</span><span class="err">:</span><span class="w"> </span><span class="k">file</span><span class="p">.</span><span class="n">managed</span>
<span class="w"> </span><span class="k">Result</span><span class="err">:</span><span class="w"> </span><span class="k">True</span>
<span class="w"> </span><span class="nl">Comment</span><span class="p">:</span><span class="w"> </span><span class="k">File</span><span class="w"> </span><span class="o">/</span><span class="n">tmp</span><span class="o">/</span><span class="n">hello</span><span class="o">-</span><span class="n">world</span><span class="p">.</span><span class="n">txt</span><span class="w"> </span><span class="n">updated</span>
<span class="w"> </span><span class="nl">Started</span><span class="p">:</span><span class="w"> </span><span class="mi">06</span><span class="err">:</span><span class="mi">17</span><span class="err">:</span><span class="mf">46.887924</span>
<span class="w"> </span><span class="nl">Duration</span><span class="p">:</span><span class="w"> </span><span class="mf">70.182</span><span class="w"> </span><span class="n">ms</span>
<span class="w"> </span><span class="nl">Changes</span><span class="p">:</span>
<span class="w"> </span><span class="o">----------</span>
<span class="w"> </span><span class="nl">diff</span><span class="p">:</span>
<span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="k">file</span>
<span class="w"> </span><span class="nl">mode</span><span class="p">:</span>
<span class="w"> </span><span class="mi">0644</span>
<span class="n">Summary</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">dev</span><span class="o">-</span><span class="n">minion</span><span class="o">-</span><span class="mi">01</span>
<span class="o">------------</span>
<span class="nl">Succeeded</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">(</span><span class="n">changed</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="nl">Failed</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span>
<span class="o">------------</span>
<span class="n">Total</span><span class="w"> </span><span class="n">states</span><span class="w"> </span><span class="nl">run</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span>
<span class="n">Total</span><span class="w"> </span><span class="n">run</span><span class="w"> </span><span class="nc">time</span><span class="err">:</span><span class="w"> </span><span class="mf">70.182</span><span class="w"> </span><span class="n">ms</span>
</code></pre></div>
<p>If everything went well, you should see <code>Succeeded: 1 (changed=1)</code>. This means that your state was successfully applied. You should now head back over to your salt-minion and verify that the state was successfully pushed. </p>
<ol>
<li>Verify <code>/tmp/hello-world.txt</code> exists on the salt-minion exists. </li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@ip-10-0-1-97 ec2-user</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="n">tmp</span><span class="o">/</span><span class="n">hello</span><span class="o">-</span><span class="n">world</span><span class="p">.</span><span class="n">txt</span>
<span class="n">hello</span><span class="w"> </span><span class="n">world</span>
</code></pre></div>
<p>There you have it, your first salt state!</p>
<h2><strong>Terraform</strong></h2>
<p>In case you are familiar with Terraform, I've started to make some effort toward terraforming this whole process. Feel free to follow that progress on my <a href="https://github.com/lopezm1/terraform-101/blob/master/mgmt/main.tf">github</a>.</p>
<p>You can also find some salt-scripts that'll bootstrap autoscaling VMs as salt-minions <a href="https://github.com/lopezm1/salt-scripts">here</a>. </p>
<h2><strong>Conclusion</strong></h2>
<p>I've just scraped the surfrace with what you can do with Salt-Master. Over the next few weeks I'll be sure to add some more articles that will describe how to:</p>
<ul>
<li>configure different enviroments</li>
<li>use pillars</li>
<li>automatically push states to auto-scaling groups</li>
<li>using salt formulas to create modular states</li>
</ul>
<p>By this point, I hope you can understand how awesome Salt really is. SaltStack has been fantastic for our company and I hope it can do the same for you.</p>
<p>In case you are evaluating other tools, I recommend you check out <a href="https://www.chef.io/chef/">Chef</a>, <a href="https://www.ansible.com/">Ansible</a> and <a href="https://puppet.com/">Puppet</a> as they all have very similar functionality. </p>
<p>It takes time and patience to fully adopt a configuration manager but the payoff is totally worth it. </p>
</div>
<div class="tag-cloud">
<p>
<a href="https://www.devlo.io/tag/saltstack.html">saltstack</a>
<a href="https://www.devlo.io/tag/aws.html">aws</a>
<a href="https://www.devlo.io/tag/cloud.html">cloud</a>
</p>
</div>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle ads-responsive"
data-ad-client="ca-pub-2119138261035978"
data-ad-slot="5952522457"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</article>
<footer>
<p>© </p>
<p>
Built with <a href="http://getpelican.com" target="_blank">Pelican</a> using <a href="http://bit.ly/flex-pelican" target="_blank">Flex</a> theme
</p></footer> </main>
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "Blog",
"name": " DevLo Software Blog ",
"url" : "https://www.devlo.io",
"image": "/images/Devlo-Logo.png",
"description": "DevLo - Software Blog."
}
</script>
</body>
</html>