Answers:
我从没使用过Ansible,但是从几周以来,我试图弄清楚与壳牌相比,Ansible有什么好处-至少在我的情况下,这证明了它们运行的困扰很大的广告系列是有效的!经过多次不成功的尝试(证明他们的文档如何未能回答最明显的问题之一),我想我终于明白了:
现在,让我们观看介绍视频,并以潜在的新用户随机浏览Ansible ans的介绍材料,让我们将其与熟练的Shell程序员可以立即生产的内容进行比较。
我的结论是,通过外壳脚本编写,Ansible本质上提供了1.检查系统是否符合期望状态的可能性,2.与Ansible Tower集成的能力,Ansible Tower是一个付费系统,似乎包含监视功能。在某些重要情况下,例如在实现不可变服务器模式时,点1可能不是很有用,因此列表很薄。
我的结论是,正如文档所介绍的那样,Ansible通过shell脚本提供的好处在少数几个可用模块很好涵盖的乐观情况下是明智的,但在一般情况下很小甚至是假设的。对于熟练的Shell程序员来说,这些好处很可能会被其他折衷方案所抵消。
但这也许只能证明介绍材料有多糟糕!
有一个快速入门视频。它始于一个页面,声称……好吧,这些并不是真正的声明,而是项目符号列表,这是一种人工制品,通常用于暂停演示文稿中的批判性判断(因为未显示逻辑,因此不能批评!)
1.1人工可读的自动化–规范是技术文档,如何
name: upgrade all packages
yum:
name: '*'
state: latest
比在shell脚本中找到相应的yum调用更容易阅读?此外,任何与AppleScript接触过的人在阅读“人类可读的自动化”时都会死于笑声。
1.2不需要特殊的编码技能–如果不编写正式规范,编码是什么?它们具有条件和变量,那么如何不编码呢?为什么我需要我无法编程的东西,从那以后就变得僵硬了?声明很不正确!
1.3按顺序执行任务–好吧,也许某些代码高尔夫爱好者意识到可以无序执行任务的语言,但是按顺序执行任务看起来并不例外。
1.4快速提高生产力–熟练的shell程序员现在可以高效地工作。这种反论点与最初的论点一样严重。
销售艺术品的流行推销员技巧是欺骗人们,使他们相信他们将获得这些艺术品的“力量”。汽车或等渗饮料的广告历史应提供令人信服的示例清单。
在这里Ansible可以进行“应用程序部署” –但是shell脚本肯定可以进行“配置管理”,但这仅是对工具用途的说明,而不是功能,以及“工作流程编排”的描述虽然有点自命不凡,但没有例子超越了GNU Parallel的能力。
为了填充该列,他们以三种不同的方式写道,这仅需要ssh,众所周知,ssh是一个守护程序,与遍布世界配置管理的这些代理无关!
视频的其余部分介绍了清单,清单是资源(例如服务器)的静态列表,并演示了如何在三台服务器上同时部署Apache。这确实与我的工作方式不匹配,在我的工作方式中资源是高度动态的,并且可以由我的云提供程序提供的命令行工具枚举,并由我使用管道|
运算符的shell函数使用。另外,我不会同时在三台服务器上部署Apache,而是构建一个主实例映像,然后使用该映像启动三个实例,它们是另一个实例的精确副本。因此,论证的“编排”部分看起来并不十分相关。
EC2是Amazon的计算服务,与之交互是受Ansible模块支持的。(还提供了其他流行的云计算提供商):
# demo_setup.yml
- hosts: localhost
connection: local
gather_facts: False
tasks:
- name: Provision a set of instances
ec2:
key_name: my_key
group: test
instance_type: t2.micro
image: "{{ ami_id }}"
wait: true
exact_count: 5
count_tag:
Name: Demo
instance_tags:
Name: Demo
register: ec2
相应的shell脚本与由JSON替换的YAML本质上是相同的:
provision_a_set_of_instances()
{
aws --output=text ec2 run-instances --image-id …
}
或JSON版本
provision_a_set_of_instances()
{
aws --output=text ec2 run-instances --cli-input-json "$(provision_a_set_of_instances__json)"
}
provision_a_set_of_instances__json()
{
cat <<EOF
{
"ImageId": …
}
EOF
}
两种版本本质上是相同的,有效负载的大部分是YAML或JSON结构中的初始化值的枚举。
本指南的最大部分没有显示任何真正有趣的功能:它引入了变量(IIRC,shell脚本也具有变量)!,并且Ansible模块处理mysql,因此,如果不是在搜索“我如何创建mysql用户”之后进行搜索,拥有XY权限”并以类似
# Create Application DB User
mysql --host "${mysql_host}" --user "${mysql_user}" --password "${mysql_password}" "${mysql_table}" <<EOF
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
EOF
您在“如何在ansible中创建具有XY特权的mysql用户”之后搜索,最后得到
- name: Create Application DB User
mysql_user: name={{ dbuser }} password={{ upassword }}
priv=*.*:ALL host='%' state=present
区别可能仍然不是很有意义。在该页面上,我们还发现Ansible具有模板元编程语言
{% for host in groups['monitoring'] %}
-A INPUT -p tcp -s {{ hostvars[host].ansible_default_ipv4.address }} --dport 5666 -j ACCEPT
{% endfor %}
当我看到这个时,我碰巧真的在我的舒适区。这种用于声明性语言的简单元编程与BSD Makefile完全一样,是一种理论范例!我碰巧广泛的编程本文节选说明一个YAML文件的工作的承诺被打破(这样我就可以不通过YAML分析器,运行我的剧本如)。它也向我们表明,Ansible必须讨论评估顺序的微妙技巧:我们必须确定变量是在语言的“声明部分”还是在语言的“命令性”元部分扩展的。在这里,shell编程更简单,除了显式 eval
或外部脚本采购之外,没有元编程。假设的等效外壳摘录为
enumerate_group 'monitoring' | {
while read host; do
…
done
}
与Ansible变体相比,它的复杂性是可以忍受的:它仅使用该语言的普通,常规,无聊的构造。
最后,我们遇到了 Ansible 的第一个真正有趣的功能:“ Ansible资源是期望状态的模型。这样,就不必测试服务是否已启动,软件包是否已安装或其他类似的东西。Ansible是将确保这些事情在声明上是正确的系统。而是在您的剧本中声明这些内容。”现在开始有点有趣,但是:
除了可用模块容易实现的少数标准情况外,我还必须自己提供实现测试的位,这很可能涉及一些shell命令。
在实现不可变服务器模式的情况下,检查安装的一致性可能不是很重要:通常所有运行的系统都是从主映像(例如,实例映像或docker映像)生成的,并且从不更新-而是由替换新的代替。
Ansible的入门资料忽略了可维护性的问题。在基本没有类型系统的情况下,shell脚本可以轻松实现JavaScript,Lisp或Python的可维护性:只有在广泛的自动化测试套件的帮助下才能成功实现广泛的重构,或者至少需要允许简单的交互式测试的设计。就是说,尽管shell脚本是系统配置和维护的通用语言,但几乎每种编程语言都具有与shell的接口。因此,通过使用高级语言将外壳配置位的各个位粘合在一起来利用高级语言的可维护性优势是完全可行的。对于OCaml,我写了Rashell 基本上为子流程提供了常见的交互模式,这使得配置脚本到OCaml的翻译非常简单。
从Ansible的角度来看,剧本的结构非常薄弱,并且存在元编程功能,这使得情况基本上和shell脚本一样糟糕,但要点是,如何为Ansible编写单元测试并不明显,并且不能模仿引入临时高级语言的论点。
Ansible的文档提请注意编写幂等配置步骤的必要性。更准确地说,应该编写配置步骤,以便可以将步骤序列aba简化为ab,即,我们不需要重复配置步骤。这比幂等要强。由于Ansible允许剧本使用任意的shell命令,因此Ansible本身无法保证会遵守此更严格的条件。这仅取决于程序员的纪律。
当您这样说时,即使Ansible具有某些固有的优势,使用其熟悉的工具(在本例中为Shell脚本)的好处也必须被抵消。我认为对此没有明确的答案。
如果团队可以使用Shell实现Ansible提供的功能:
那么他们可能会坚持自己所知道的。
毕竟,您可以在BASH中实施“守卫”。您可以在那里找到许多BASH现有工作来解决各种服务器配置任务(实际上,任何Dockerfile都有90%bash安装代码)。您可以非常接近Ansible / Salt / Chef-Zero提供的功能,而无需实际将整个现有解决方案移植到这些工具。
这是NIH(此处未发明)趋势与抛出好的,已建立的脚本以支持更健壮的解决方案之间的一种平衡行为。
需要牢记的最后一个考虑因素:当您尝试向团队招募更多人员时,您的技术堆栈如何衡量。寻找具有Ansible经验的人比寻找具有您自己的特定脚本CM工具经验的人要容易得多。严格来说,这不是技术上的考虑,而是文化上的考虑。您想成为发明自己的Ansible的怪异组织,还是想成为找到合适工作工具的合理组织?这些决定会影响您吸引人才的能力。
上面的答案涵盖了其中的一部分,但是却忽略了其中一个重要要素:收敛设计。我前一阵子在https://coderanger.net/thinking/在Chef的上下文中写了一些关于这个的单词,但是简短的版本是bash脚本是一组指令,而Ansible剧本(或Chef的食谱,Salt)状态等)是对所需状态的描述。通过记录所需的状态而不是要达到的状态,您可以应对更多的起始状态。这是很久以前在CFEngine中概述的Promise Theory的核心,并且我们(配置管理工具)此后一直在复制设计。
tl; dr Ansible代码说明了您想要的东西,bash代码说明了如何做某事。
现在是2019年,我在ansible学习曲线上花了几天时间,这是绝对的事实:Ansible不值得为此烦恼。
它尚未完成,无法在Windows上运行,并且YAML配置和误导性错误消息的组合会使您流血。这似乎是故意的,我是认真的。显然,这是redhat sysadmins沮丧的开发人员端项目的产物。可能是一个时髦。
如果您不需要除配置之外的任何其他功能,而您仅在一个特定的操作系统上进行配置。为了可惜,写一个像样的shell.script。
截至目前,整个项目使我想起了早期的Linux论坛,那里的菜鸟被告知RTFM,并被嘲笑为什么有人不能编写用于配置图形设置的GUI。你就是不明白吗?你应该坚持窗户...也许我会交配..快乐的VI-ing。
使用Docker。优先于任何事物。Docker非常简单而强大。
但是,如果您绝对必须提供预先存在的锡该怎么办?真正的替代品是什么?
好吧...还没有。但我会向您保证,除非ansible变得更好,否则很快就会出现。因为不管狂热者多么努力地推销它,并原谅它的失败……努力中的十分之五。
SCP制作了一个bash脚本,并避免了麻烦。