Vagrant多SSH用户执行多Ansible Playbook配置问题
解决方案:分阶段配置两个Ansible Provisioner
我刚好处理过几乎一模一样的场景,核心思路就是把配置拆成两个独立的Ansible阶段:先用默认的vagrant用户完成新用户的创建和权限配置,再切换到新用户执行后续的核心配置(包括删除vagrant用户)。下面是具体的实现步骤和代码示例:
第一步:初始阶段 - 创建provisioner用户(以vagrant身份执行)
首先我们需要一个初始化Playbook(比如initial_setup.yml),用来创建provisioner用户、配置SSH密钥并赋予sudo权限:
# initial_setup.yml - name: 创建provisioner用户并配置权限 hosts: all become: yes tasks: - name: 创建provisioner用户 user: name: provisioner shell: /bin/bash create_home: yes groups: sudo - name: 给provisioner用户配置免sudo权限 lineinfile: path: /etc/sudoers.d/provisioner line: "provisioner ALL=(ALL) NOPASSWD: ALL" create: yes mode: 0440 - name: 生成provisioner用户的SSH密钥对 user: name: provisioner generate_ssh_key: yes ssh_key_bits: 2048 ssh_key_file: .ssh/id_rsa - name: 复制provisioner的私钥到Vagrant主机(方便后续连接) fetch: src: /home/provisioner/.ssh/id_rsa dest: ./provisioner_key flat: yes mode: 0600
然后在Vagrantfile里配置第一个Ansible Provisioner,用默认的vagrant用户执行这个初始化脚本:
# Vagrantfile片段 Vagrant.configure("2") do |config| # 虚拟机基础配置(略) config.vm.box = "ubuntu/focal64" # 第一阶段:用vagrant用户执行初始化Playbook config.vm.provision "ansible_initial", type: "ansible" do |ansible| ansible.playbook = "initial_setup.yml" # 这里用默认的vagrant用户和密钥,不需要额外配置 end
第二步:主配置阶段 - 切换到provisioner用户执行
接下来是核心配置的Playbook(比如main_config.yml),里面包含删除vagrant用户的任务:
# main_config.yml - name: 执行系统核心配置 hosts: all become: yes tasks: - name: 删除不安全的vagrant用户 user: name: vagrant state: absent remove: yes # 其他系统配置任务...
然后在Vagrantfile里添加第二个Ansible Provisioner,显式指定用provisioner用户和刚才生成的私钥连接:
# Vagrantfile继续添加 # 第二阶段:切换到provisioner用户执行主配置 config.vm.provision "ansible_main", type: "ansible" do |ansible| ansible.playbook = "main_config.yml" # 指定新的SSH用户 ansible.raw_arguments = ["--user=provisioner"] # 指定刚才复制到主机的私钥路径 ansible.ssh_private_key_path = "./provisioner_key" # 关闭主机密钥检查(开发环境可选,生产环境不建议) ansible.raw_arguments << "-o StrictHostKeyChecking=no" end end
关键细节提醒
- 一定要确保
provisioner用户有免sudo权限,不然执行删除vagrant用户这类需要root权限的任务会失败; - 私钥的权限必须是
0600,不然SSH会拒绝使用; - 如果你的环境不允许把私钥复制到Vagrant主机,也可以在初始化阶段把你本地的公钥加到
provisioner用户的authorized_keys里,然后指定本地的私钥路径; - 第二阶段的Provisioner必须在第一阶段之后执行,Vagrant会按配置顺序运行provisioner。
这样配置后,Vagrant会先以vagrant用户完成新用户的创建,再自动切换到provisioner用户执行核心配置,完美解决你的需求。
内容的提问来源于stack exchange,提问作者Rob Carpenter
相关产品推荐
相关产品推荐

