在变量中传递值以在Ansible中运行特定命令

在变量中传递值以在Ansible中运行特定命令,ansible,Ansible,我有一个yml文件,它使用powershell在windows节点上安装ODBC连接。对于每种DB类型,我们都有不同的yml文件,每个yml都有针对不同数据库的安装脚本 因此,每当我们想要更改或添加一个新连接时,我们都会注释掉所有只需要执行的连接,这需要在更改或添加连接时进行大量手动操作 以下是我定义win_命令的方式: -名称:运行xxxx Oracle win_命令:powershell-executionpolicy无限制文件夹:\xxx.ps1-Server{XXXX_DB_Server

我有一个yml文件,它使用powershell在windows节点上安装ODBC连接。对于每种DB类型,我们都有不同的yml文件,每个yml都有针对不同数据库的安装脚本

因此,每当我们想要更改或添加一个新连接时,我们都会注释掉所有只需要执行的连接,这需要在更改或添加连接时进行大量手动操作

以下是我定义win_命令的方式:

-名称:运行xxxx Oracle
win_命令:powershell-executionpolicy无限制文件夹:\xxx.ps1-Server{XXXX_DB_Server}-UID{XXXX_Username}-PWD{{XXXXX}}-Database{{xxx_DB_NAME}-DSN{XXXXX_DSN}
注册号码:cmdXXXXX
-调试:var=cmdXXXX

在这个yml中,我有这样的命令用于几乎9个DBs。我想创建一个变量,该变量将在运行时提供,并且只应执行这些命令来安装DB连接。

如果您确实为所有DB参数创建了前缀为某个标识符名称的变量,这确实不理想。您通常会使用列表或dict在ansible中处理此类信息(如果您确实无法更改,您仍然有下面的解决方案)

这是一个示例变量声明

#带有列表的示例
我的\u odbc\u连接\u列表:
-姓名:XXXX
db_服务器:some.server.local
数据库名称:acooldb
用户名:someuser
密码:sosecret
dsn:一些dsn
-姓名:YYYY
db_服务器:other.server.local
数据库名称:ahypedb
用户名:otheruser
密码:verysecret
dsn:其他dsn
#以口述为例
我的\u odbc\u连接\u命令:
XXXX:
db_服务器:some.server.local
数据库名称:acooldb
用户名:someuser
密码:sosecret
dsn:一些dsn
YYYY:
db_服务器:other.server.local
数据库名称:ahypedb
用户名:otheruser
密码:verysecret
dsn:其他dsn
使用这些结构,通过一个任务和一个循环就可以轻松地完成所有要设置的连接。同样,对于上面的每个数据结构,这里有两个示例,以及在您的问题中使用的命令

-name:从列表中运行odbc声明命令
win\u命令:powershell-executionpolicy无限制文件夹:{{item.name}.ps1-Server{{item.db\u Server}-UID{{item.username}}-PWD{{item.password}-Database{{item.db{u name}-DSN{{item.DSN}
寄存器:odbc\u cmd
循环:“{my_odbc_connection_list}”
-名称:显示命令结果
调试:
msg:{{odbc_cmd.results}}”
-名称:从dict运行odbc声明命令
win\u命令:powershell-executionpolicy无限制文件夹:{{item.key}.ps1-Server{{item.value.db{u Server}-UID{{item.value.username}-PWD{{item.value.password}-Database{{item.value.db{u name}-DSN{item.value.DSN}
寄存器:odbc\u cmd
循环:{my_odbc_connection_dict|dict2items}”
-名称:显示命令结果
调试:
msg:{{odbc_cmd.results}}”
从那里,通过传递名称列表,只播放相关的连接命令是相当容易的。要在运行时提供它,最简单的方法是将
--extra var
作为逗号分隔的字符串列表传递给
ansible playbook
命令,例如

ansible-playbook -i inventory odbc_play.yml --extra_var names_to_declare=XXXX,YYYY
您可以在变量中提供单个元素。它将导致下面的单个元素列表

然后,您只需要过滤掉不在该名称列表中的所有元素。这基本上等同于使用以下表达式更改循环:

#如果使用数据作为列表
循环:“{my_odbc_connection_list}selectattr('name','in',names_to_declare.split(','))}”
#如果将数据用作dict
循环:“{my_odbc_connection_dict|dict2items|selectattr('key','in',names_to_declare.split(',')}”
请注意,如果用户输入了一个不存在的拼写错误,这将考虑过滤掉名称中的拼写错误

除了在
循环中直接过滤的“harcoding”(使用
set\u fact
声明其他变量,如果未提供,则应对
名称的默认值,即使用所有连接)之外,还有其他方法(即使用所有连接),但这有点超出了问题的范围


现在,如果你不能改变你的数据结构,你仍然有可能处理它。同时,您需要一个包含所有已知连接名称的列表(如果您添加了更多连接,则必须更新该列表),例如

已知的\u odbc\u连接\u列表:
-XXXX
-YYYY
这将使您能够循环使用稍微详细一点的现有变量:

-name:运行ocbc声明命令
变量:
名称:“{{item}}”
db_服务器:“{{lookup('vars',item+''U db_服务器')}”
用户名:“{{lookup('vars',item+'\u username')}”
密码:{{lookup('vars',item+'.\u password')}
db_名称:“{{lookup('vars',item+''U db_名称')}”
dsn:“{{lookup('vars',item+'.\u dsn')}”
win\u命令:powershell-executionpolicy无限制文件夹:{{name}.ps1-Server{{db\u Server}-UID{username}-PWD{{password}}-Database{db\u name}-DSN{DSN}
循环:“{{known\u odbc\u connection\u list}”
寄存器:odbc\u cmd
在运行时使用与上述相同的var,可以修改循环以筛选连接,如下所示:

循环:“{{known_odbc_connection_list|intersect(names_to_declare.split(','))}”

与上述两个其他解决方案一样,此最新表达式将在用户输入错误时过滤掉不存在的名称。

您可以创建一个var
dbs
,它是一个定义不同dbs参数的dict,然后使用
dbs[db\u name].server
而不是
XXXX\u db\u server
,其他人也是如此,然后在运行时通过命令行上的额外变量设置
db_name