如果只使用一个playbook,那么Ansible无法自动安装依赖角色。至少根据这个SO thread的说法。
但是,我有使用Vagrant和Vagrant的Ansible本地 provisioner的“优势”。有什么技巧可以应用吗?
如果只使用一个playbook,那么Ansible无法自动安装依赖角色。至少根据这个SO thread的说法。
但是,我有使用Vagrant和Vagrant的Ansible本地 provisioner的“优势”。有什么技巧可以应用吗?
随着软件的发展,我无法保证以下所有的“旧内容/答案”仍然可靠,并且不会引起你的机器火灾(笑)。但是,我维护了一个在GitHub上的Vagrantfile,它可以自动安装Ansible Galaxy角色,因此,这个文件应该被视为唯一的真理(在文件中向下滚动一点)。如果GitHub文件对您不起作用,请在GitHub跟踪器上提交问题,我会解决的。
类似于这样(Vagrantfile
):
config.vm.provision 'ansible', run: 'always', type: :ansible_local do |ansible|
ansible.galaxy_role_file = 'requirements.yml'
ansible.playbook = 'playbook.yml'
end
requirements.yml
内容如下:
---
- src: mongrelion.docker
请注意,我的一个角色是在一个单独的文件中指定的,这完全是过度设计。我想在 Vagrantfile 中指定角色,而不必再添加一个安装 Ansible 的 shell 脚本,并运行 galaxy 安装命令之前,让 Vagrant 有机会来安装 Ansible。我发现让 Vagrant 安装 Ansible 非常方便,每增加一个“脚本”都会让人感觉很糟糕,因为 Ansible 应该是 provisioner lol。
需要记录的是,ansible-galaxy install
不需要指定一个角色 文件; 在命令中指定一个角色 名称 就足够了,此时角色将被下载 (文档)。
我尝试花了大约半天时间去hack和修改各种可以设置的 Vagrant 选项,例如galaxy_command
,但每次新的trickery都会导致一个新的问题,这是Vagrant的一个硬性停止(听起来熟悉吗??哈哈哈)。
如果你找到了一种在不依赖于另一个文件或在 Vagrantfile 中嵌入的 night-hacked shell 脚本的情况下设置角色的方法,请给我发个消息 =)
默认情况下,Ansible Galaxy 将角色文件下载到项目的子目录:./roles/
。当解析 playbook 文件时,Ansible 会自动在此子目录中查找角色。
我认为这个位置不太方便,因为我的个人目标是保持项目文件夹干净,并尽可能不提交垃圾到代码库中。幸运的是,可以通过将 galaxy_roles_path
设置为 Ansible 用于查找角色的其他位置(例如 /etc/ansible/roles/
),从而更改 Galaxy 的下载路径。
如果只是那么容易就好了。
[至少在我的机器上:] 当 Vagrant 安装 Ansible 时,该文件夹仅对 root 用户具有写权限。也就是说,当ansible-galaxy install
1分钟后运行并下载角色时,由于权限不足,一切都会崩溃。或者换句话说,Ansible 不能将内容放入自己的“主文件夹”中。实际上这有点搞笑。
解决方法是在 Ansible 自己搞砸之前向文件夹中注入一些chmod
魔法:
config.vm.provision 'preemptively give others write access to /etc/ansible/roles', type: :shell, inline: <<~'EOM'
mkdir /etc/ansible/roles -p
chmod o+w /etc/ansible/roles
EOM
config.vm.provision 'ansible', run: 'always', type: :ansible_local do |ansible|
ansible.galaxy_role_file = 'requirements.yml'
ansible.galaxy_roles_path = '/etc/ansible/roles'
ansible.playbook = 'playbook.yml'
end
我发现让Ansible provisioner 始终 运行是一个好习惯。这样它就可以做它的事情,所谓的“做它的事情”。终端输出显示,在每次运行vagrant up
时都会下载并安装角色。这真的很让我烦恼。
galaxy_command
默认使用--force
标志——为什么?我也不知道。但是移除它可以解决问题。现在我们得到了一个警告:
[WARNING]: - mongrelion.docker (master) is already installed - use --force to change version to unspecified
很烦人。我应该感到受宠若惊,而不是被警告;) Vagrant可能添加了--force
标志来抑制此警告?通过偶然的机会,我找到了另一种解决方案。在角色定义中添加一个显式的版本标签(文档),然后就可以得到一个可爱的替代警告:
- mongrelion.docker (6a4fe8fc18550bfff8eeecd89888cf817cdf4bfc) is already installed, skipping.
如果您仍然收到警告消息,则是因为在显式添加版本标签之前已安装了另一个版本。所以,现在您必须至少使用一次--force
来强制更新或手动删除旧的(ansible-galaxy remove stupid.role
)。
总之,这是我最终使用的内容。。
Vagrantfile:config.vm.provision 'preemptively give others write access to /etc/ansible/roles', type: :shell, inline: <<~'EOM'
sudo mkdir /etc/ansible/roles -p
sudo chmod o+w /etc/ansible/roles
EOM
config.vm.provision 'ansible', run: 'always', type: :ansible_local do |ansible|
ansible.galaxy_role_file = 'requirements.yml'
ansible.galaxy_roles_path = '/etc/ansible/roles'
ansible.galaxy_command = 'ansible-galaxy install --role-file=%{role_file} --roles-path=%{roles_path}'
ansible.playbook = 'playbook.yml'
end
---
- src: mongrelion.docker
version: 6a4fe8fc18550bfff8eeecd89888cf817cdf4bfc