|
|
.使用playbook安装启用httpd服务5 @% n+ w# g, {7 W3 ^; B
首先编写xxx.yaml文件
; t* u! Y8 j' ~) E* p# X$ m/ P/ a) s1 Y
--- #多个yaml文件以---开头,以表明这是一个yaml文件,可省略
' v/ y$ T- l( F. J1 X$ H; c6 e- name: apache play #定义一个play的名称,可省略
+ }8 d9 ~5 L; h% J. @+ Q* c( @ gather_facts: false #设置不进行facts信息收集(即setup模块收集信息),这可以加快执行速度,如果不使用其中的信息可省略
9 Q( u; \5 s+ ^ F hosts: webservers #指定要执行任务的被管理主机组,如多个主机组用冒号:分隔
]; V5 l% q9 l7 ]* a1 L" E remote_user: root #指定被管理主机上执行任务的用户. W+ `, V! m/ L8 O
tasks: #定义任务列表,任务列表中的各任务按次序逐个在hosts中指定的主机上执行
7 I: m3 [' D- e2 O$ X& V$ j - name: disable selinux #自定义任务名称( T. }# A. g; l& \4 W$ w. N
command: '/usr/sbin/setenforce 0' 键值对,键是ansible模块,值是 -a 中的内容
& C" S+ g0 ~: l: e ignore_errors: true #如执行命令的返回值不为0,就会报错,tasks停止,可使用ignore_errors忽略失败的任务
, h& @% \* w( c; r
3 K, A2 Z5 b/ y7 H0 v. _ - name: disable firewalld) _( y1 F0 N8 a; M
service: name=firewalld state=stopped enabled=no2 [7 J) f$ f& E$ [6 [
: G0 _( x" j* b X5 p( H1 A; |
- name: prepare local repo
$ w9 a6 ~3 B( A6 F5 }0 \$ I/ r+ G copy: src=/etc/yum.repos.d/local.repo dest=/etc/yum.repos.d/local.repo
( v( s; b/ g2 Z+ i Z6 c/ T6 \
3 f9 { [, I" x1 {2 G4 `8 | - name: mount cdrom
9 y% h; j, X* x7 E& ]$ p1 j mount: src=/dev/sr0 path=/mnt fstype=iso9660 state=mounted) M1 T2 S' M; [( d! B8 B
- name: install apache
$ c' j2 w2 l% l8 O yum: name=httpd state=latest( V+ s; J9 `: G
- name: prepare httpd configuration file6 ]6 D9 n) f5 B% h) A
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf mode=644 owner=apache group=apache s( `1 Y/ v3 V; |8 C/ l, h2 \; h
notify: "restart httpd" #如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作+ p. y. l! t+ T# |& [ @
" t/ E, ]8 {, P- D - name: start httpd
2 |/ a5 f% J/ V+ b service: name=httpd state=started enabled=yes
4 P& V. c5 t- C9 u& p( ]) g% [9 U4 {+ S( i0 e' U
handlers: #handlers中定义的就是任务,此处handlers中的任务使用的是service模块# X: o1 z2 Q. M8 K& f
- name: restart httpd #notify和handlers中任务的名称必须一致
\1 q# M6 \! G( r( C) Z service: name=httpd state=restarted
. `4 n* e# ` q6 r6 G9 o运行playbook+ K3 A# |3 ]+ z* Q; v0 F; O( D
1 Z# F+ x" {' g' w. ]: }% H
ansible-playbook xxx.yaml
7 X" o2 f1 s; `9 e$ g3 J, Y( M- e7 L4 J
补充参数:
* H- M9 @, R# A, ?* m4 q" a -k(–ask-pass):用来交互输入ssh密码
+ q4 L( @1 y3 ?. T8 T8 Y% L) k8 N -K(-ask-become-pass):用来交互输入sudo密码) P8 M( G9 ?$ p9 U1 `: T# b
-u:指定用户
7 u4 c% s1 |9 H6 R# @5 S8 Q4 ?( m; h- }4 v) X" `, M4 V" d" A
% A$ i' U& B3 r: h
0 s' W% s( W# ~* T2 }' kAnsible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler,这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。
3 z# W( z+ c; ?! y1 H; @. A w
! g/ L6 B+ g* w: E9 z# i2.使用playbook安装启用nginx服务
8 {& b8 Z7 u3 M: P+ O+ X+ J1 v4 t首先编写xxx.yaml文件) V0 I9 y: F/ R' p/ U$ b0 x
% I" X: |) H/ X$ D7 X9 H0 {+ J5 u---3 U' i8 z+ K% X5 K
- name: nginx play, m9 o7 W9 _0 E, D2 t$ t* H
gather_facts: false
8 ^" W) l9 i8 _, O o% m9 J' t hosts: webservers
# _2 [. |: j2 P; O& z remote_user: root; p1 d0 \# x7 d* n
tasks:' b' ~! j! x( `! [5 p/ T- c
- name: test connection7 X# _4 f' _: c: q1 M6 o2 P
ping:' b- l/ q+ r1 ]! U
* q$ ^: e5 Y( _" Z$ v; l; [
- name: disable selinux
% l$ @5 v9 O5 o7 e1 j8 f) N command: '/usr/sbin/setenforce 0'
$ B2 _2 U) q2 d2 F ignore_errors: true/ L; _+ [$ A& l
- ^+ I2 \# X" `7 K, T& |
- name: disable firewalld
0 `2 O$ r( m4 ^% Z( F% p service: name=firewalld state=stopped enabled=no4 C7 V8 T, e. D2 B5 b: O
$ \* L0 t- z& Y u0 q
- name: prepare nginx repo- \; U1 t# j2 Y
copy: src=/etc/yum.repos.d/nginx.repo dest=/etc/yum.repos.d/nginx.repo7 i' j8 o8 \) i( j% G3 u& q: x
; u9 [" @8 P2 f3 v `2 T+ X y/ c
- name: add dns/ C9 L0 E W+ P4 P
copy: content="nameserver 8.8.8.8" dest=/etc/resolv.conf4 @' ?1 v: W; `7 M
- t+ h) Q6 H! |' ^# g% ~) p - name: install nginx
/ S( Y, N5 l2 K9 @6 ^# u0 d4 V0 i' d yum: name=nginx state=latest0 e) m# L% \: U& `2 ]6 Y5 p/ y
) M8 t* H/ e: Z; m
- name: prepare nginx configuration file
) K' ~% V, b; x" K4 p: J5 `- G1 h copy: src=/opt/nginx.conf dest=/etc/nginx/nginx.conf mode=644 owner=nginx group=nginx4 K' L' p3 f2 O& x
5 x/ `0 t" w5 R+ V( m9 S
- name: prepare nginx configuration.d file# i0 a/ P" i5 a; [
copy: src=/opt/default.conf dest=/etc/nginx/conf.d/default.conf mode=644 owner=nginx group=nginx
Q' y& [6 ^% B- y- l notify: "restart nginx"
# m: f6 A0 v! [. h0 ~$ W ]. K: ]7 S8 y# @* P) h2 {
- name: start nginx
! c0 H/ [) ~9 `# E |4 \3 B, M service: name=nginx state=started enabled=yes
0 \* o$ ]8 r$ o: \& |% ?+ ~/ a( X$ y# ~1 V
handlers:# n* g' N4 E& P5 c3 |
- name: restart nginx
+ D5 l6 N6 `4 ]3 D service: name=nginx state=restarted
0 m# A" p6 p2 M/ Z8 i1 n; q运行playbook7 h s- o Z2 Q$ d) N3 A
; N) I, n3 @$ [检查yaml文件的语法是否正确
% S h% \' \- f1 B( Sansible-playbook xxx.yaml --syntax-check 8 | F- D9 K; i
( P- J0 o3 K3 w3 x+ B* K
如果语法格式有问题会报错 ' v U+ |$ n% W" o: |/ V/ _" j
7 r0 e/ h% Z& M# E; [7 {2 t( \0 h" O! w/ p
" o, i* E5 e* b1 z2.检查tasks任务
* U3 a5 F( V/ E5 _ansible-playbook xxx.yaml --list-task, Z' G5 `5 i! a
8 i- W8 x9 O, F9 v如果任务列表中的语法格式有问题会报错 8 v5 H2 x& Q6 z3 B# |6 h$ w7 G5 @
E% a8 z5 n) u0 ^) r# v
# D/ s5 `1 X6 ?! k$ z
/ l; e4 }% }# ^2 A& V* B3.检查指定的主机0 U2 [8 P+ V5 f3 u! r% Q1 b9 ]; _: n
ansible-playbook test1.yaml --list-hosts: d1 c- U0 x' f
F8 X% i$ w( t
; _/ T% K$ m/ R2 u" P* r
& x+ W2 M% I3 u% T3 g9 o
4.指定从某个task开始运行
+ o' ^$ ^. r, D, A* I5 ~$ gansible-playbook xxx.yaml --start-at-task='任务名' 1 x+ S' q& A3 J# D' |5 l/ ~# H6 n4 @& A
; p8 G+ g5 u# {" g2 @4 U& n8 d
四、playbook进阶语法" Z! K3 l+ V. }1 x) s$ F* Q
1.引用变量
0 X( ^' j& @. {(1)自定义变量4 p' a* }) R* w5 Q7 p
编写文件" Z# \$ \0 P. g, [+ f, B
9 C( Q3 D5 D1 X; a/ v+ ~" C) P( Z. h# c2 E. ^* d3 j0 l
$ _. g6 s" i2 e9 U
运行playbook7 M% O2 K* \: m
, c- b3 s0 m$ ~; b0 m$ `0 G9 n$ y Q
/ p* e1 U+ p; I' j. C1 s
查看结果 j' q% M7 S7 }8 f( p( r! P+ s
% z6 ]' G1 A$ W% n- X0 y7 ^; l: P; b1 b7 V; m
; s' H! y, [2 h' [- F) ~# M
(2)引用setup模块信息中的变量0 ~# v/ k, p6 P/ {, i
编写文件
5 i8 U1 O8 D, U1 R- d% J
# u+ a. e2 Q0 }+ J- R
6 b. Q8 B Q# Q% c6 F2 R' w' N
1 @# o H6 ]0 R# t4 Q! C+ z运行playbook
* @7 O" J- Y6 G7 Z) x: X2 ]9 Z8 p: ]
* h! p: @2 C Y# E: @1 [" H* e2 I, \# `) O
t4 n; z- P: K$ c
查看结果
w8 c, p6 P3 ^1 c
7 U- [8 ]7 Z" E7 c& S) z/ ~8 p- `: n9 u6 _1 J% P
" r' g7 z; J" E" L
2.遍历值
0 }; i) P, I0 j* g* o9 s2 m& x Ansible提供了很多种循环结构,一般都命名为with_items,作用等同于 loop 循环。
: a9 J4 h9 W& S0 h2 o6 o
, Y/ m+ e) @0 \4 C# n0 s# `with_items:将每个列表中所有值遍历输出。* t8 s2 |# a- T6 N; n
6 f( G" I/ ?9 \
with_list:将每个列表作为一个整体输出。
1 w2 {& P# J3 f/ L% Z; t8 H/ g3 b8 l9 v$ s9 P( w
with_together:将每个列表中对应的值混合输出,如果个数不一致,将无法混合输出的值用null值填补组合的空缺。0 C/ x: A, B- O( R9 \
: v* U7 [, }5 g7 b7 X
with_nested:将每个列表中的每个值组合输出,类似多重循环。
( @6 v6 E6 Z) V% ~. e. @9 B6 i) d' k }7 f9 |, W
(1)遍历变量中的值9 D8 b5 x5 v) t9 }3 R' q
2 W* i, ~: _1 Z
9 B; g& }- E) H3 d9 B5 V% ^
" D6 }/ u9 E. c# k j# I- L
1 p4 }0 Z3 v7 K* x
(2)遍历指定的多个值
' Z$ {9 |0 N' V
) \: K. q: \- q( q6 N e4 Q! [/ {9 C0 J8 I, ?
指定方式,也可以是列表的格式2 O, K9 o$ L1 n2 E0 ]* \* N2 Q
" N0 l1 O. {0 G1 `1 r& ~9 T4 G8 u; h' n3 ]+ h
# Z- F* N! P- ]/ l(3)遍历参数列表 s" R/ v2 \- C9 D) I# w9 [, X
) K4 S0 I4 a& E, R
# G. a7 I# C& _. @9 W
格式也可以是 - {username: zhangsan, filename: 1.txt}
4 I. f7 Z. i) U4 H+ h j4 {! @2 _! l4 J5 g! L
' O) ^ g5 s7 C1 w+ x
; a5 _- k' }9 k' u; H/ z
3.条件判断0 ^' j$ d, v+ S+ z
在Ansible中,提供的唯一一个通用的条件判断是when指令,当when指令的值为true时,则该任务执行,否则不执行该任务。3 n; c* P# ]4 ~+ P- ^+ S7 K0 _
5 U A8 w H0 D: [9 o$ ^# U/ Q
when一个比较常见的应用场景是实现跳过某个主机不执行任务或者只有满足条件的主机执行任务。
e9 ` ]7 t' R* M+ o
2 r. p- Z* r( t' `* U- Z/ iwhen: ansible_default_ipv4.address 条件表达式 "ip地址" - j; m+ [1 R% n
when: inventory_hostname 条件表达式 "主机名"- O' y6 V" _( q" C. g/ s
* q- z" {4 y* O9 s' H: ?' u
$ |2 a# s% P4 `9 s& b; n( l' `$ r! R9 k" b' z5 T! z
/ b1 M$ b% g( ?
( ?/ y5 K( b! R$ B4.指定远程主机sudo切换用户+ U$ `& H! A" z7 O8 ?
当ssh不允许root用户登录时,打开普通用户sudo提权
& `. L0 _0 z6 E1 n. g
4 h0 s: q! d5 Q5 Q/ l6 i6 r L" U$ X: ?
* |& g: ^5 o1 T; h& {' ^0 g5.tags 模块 1 n# V9 x+ R* N4 f
可以在一个playbook中为某个或某些任务定义“标签”,在执行此playbook时通过ansible-playbook命令使用--tags选项能实现仅运行指定的tasks。; I) X1 d0 @) v8 Y+ g6 u/ _. M
" t# t1 D# j, @
playbook还提供了一个特殊的tags为always。作用就是当使用always作为tags的task时,无论执行哪一个tags时,定义有always的tags都会执行。
5 I2 o i2 ^. i# e; L
9 p$ A* Z/ D* w& H( d3 t/ T$ l6 O7 f$ e( |$ g6 q% s$ n$ U
. K2 d3 e' ?4 {* s" ^
2 f2 L0 x# H/ ?
3 U1 |. e" P8 E- t, v" v5 C6 O
C- B6 m6 W: L- F1 D% N0 o4 @% V' Q, ?" C$ V8 t1 {' U& A
' c2 {! P+ f" \* G% _( m( v7 b& e
3 b7 j$ e4 }6 r( i0 i
9 \# ^3 L1 h/ _3 p) V! \( e- s" d+ n
! P! o0 Z' I5 g& \ |
|