【问题标题】:How to set Linux environment variables with Ansible如何使用 Ansible 设置 Linux 环境变量
【发布时间】:2023-04-05 20:42:01
【问题描述】:

您好,我正在尝试了解如何使用 Ansible 设置环境变量。

类似这样的简单 shell 命令:

EXPORT LC_ALL=C

尝试作为 shell 命令并得到一个错误 尝试使用环境模块,没有任何反应。

我错过了什么

【问题讨论】:

  • 您需要在特定帐户中设置它($HOME/.profile、默认值(/etc/profile)还是在安装或运行应用程序之前使其可用?
  • 我需要将其设置为以便我可以使用 mongodb 控制台。升起机器后,如果不导出此变量,我将无法进入控制台
  • 好吧,你说的是ansible中的mongodb模块,那为什么不直接在准备那个模块的时候(安装、设置配置文件或者启动它的服务)呢?
  • 设置环境变量和mongodb模块有什么关系。我根本没有使用它。我想要的只是安装 mongo 设置环境变量并启动服务
  • 所以你没有准备好那个 mongodb 模块?那么你需要先花时间在上面,然后你的问题就不是问题了。

标签: linux ansible


【解决方案1】:

有多种方法可以做到这一点,从您的问题来看,您还不清楚您需要什么。

1.如果您只需要为每个任务定义环境变量,请执行以下操作:

- hosts: dev
  tasks:
    - name: Echo my_env_var
      shell: "echo $MY_ENV_VARIABLE"
      environment:
        MY_ENV_VARIABLE: whatever_value

    - name: Echo my_env_var again
      shell: "echo $MY_ENV_VARIABLE"

请注意,MY_ENV_VARIABLE 仅适用于第一个任务,environment 不会在您的系统上永久设置它。

TASK: [Echo my_env_var] ******************************************************* 
changed: [192.168.111.222] => {"changed": true, "cmd": "echo $MY_ENV_VARIABLE", ... "stdout": "whatever_value"}

TASK: [Echo my_env_var again] ************************************************* 
changed: [192.168.111.222] => {"changed": true, "cmd": "echo $MY_ENV_VARIABLE", ... "stdout": ""}

希望很快在游戏级别上也可以使用environment,而不仅仅是上面的任务级别。 目前在 Ansible 的 GitHub 上有一个针对此功能的拉取请求:https://github.com/ansible/ansible/pull/8651

更新:它现在已于 2015 年 1 月 2 日合并。

2。如果您想要永久环境变量 + 系统范围/仅适用于某些用户

你应该看看你是如何在你的 Linux 发行版/shell 中做到这一点的,有很多地方可以做到这一点。例如,在 Ubuntu 中,您可以在文件中定义它,例如:

  • ~/.profile
  • /etc/environment
  • /etc/profile.d目录
  • ...

你可以在这里找到关于它的 Ubuntu 文档:https://help.ubuntu.com/community/EnvironmentVariables

毕竟是为了在 ex 中设置环境变量。在 Ubuntu 中,您可以使用 Ansible 中的 lineinfile 模块并将所需的行添加到某个文件中。请查阅您的操作系统文档以了解将其添加到何处以使其永久化。

【讨论】:

  • 第二个选项是我需要的。我自己找到了解决方案,但就是这样。
  • 快速更新:Ansible 的拉取请求 #8651 已合并,因此现在也可以在游戏级别执行此操作。
  • 那么没有办法通过Ansible设置持久化环境变量吗?
  • @DumpHole 为此,我使用了 Ansible Galaxy 中的“franklinkim.environment”角色。
  • 如果您只想为当前的 bash shell 设置环境变量怎么办?例如,可能会以这种方式使用解密的密码。
【解决方案2】:

我没有足够的声誉来发表评论,因此我添加了一个新答案。
Gasek 的回答非常正确。只有一件事:如果您正在更新.bash_profile 文件或/etc/profile,这些更改只会在您进行新登录后反映。 如果您想设置环境变量,然后在同一剧本的后续任务中使用它,请考虑将这些环境变量添加到 .bashrc 文件中。
我猜这背后的原因是登录和非登录 shell。
Ansible 在执行不同的任务时,从.bashrc 文件而不是.bash_profile/etc/profile 中读取参数。

例如,如果我更新了我的路径变量以将自定义二进制文件包含在相应用户的 .bash_profile 文件中,然后做了文件的源。 接下来的后续任务将无法识别我的命令。但是,如果您在 .bashrc 文件中更新,该命令将起作用。

 - name: Adding the path in the bashrc files
   lineinfile: dest=/root/.bashrc line='export PATH=$PATH:path-to-mysql/bin' insertafter='EOF' regexp='export PATH=\$PATH:path-to-mysql/bin' state=present
 
-  - name: Source the bashrc file
   shell: source /root/.bashrc

 - name: Start the mysql client
   shell: mysql -e "show databases";

这可行但如果我使用配置文件完成此操作,mysql -e "show databases" 会报错。

- name: Adding the path in the Profile files
   lineinfile: dest=/root/.bash_profile line='export PATH=$PATH:{{install_path}}/{{mysql_folder_name}}/bin' insertafter='EOF' regexp='export PATH=\$PATH:{{install_path}}/{{mysql_folder_name}}/bin' state=present

 - name: Source the bash_profile file
   shell: source /root/.bash_profile

 - name: Start the mysql client
   shell: mysql -e "show databases";

这个行不通如果我们将所有这些任务都放在同一个剧本中。

【讨论】:

  • 如果默认 shell 是 sh,source 可能不起作用。而不是source file. file
【解决方案3】:

这是一个在/etc/environment(系统范围内,所有用户)上永久设置键/值的快速本地任务:

- name: populate /etc/environment
  lineinfile:


    path: "/etc/environment"

    state: present
    regexp: "^{{ item.key }}="
    line: "{{ item.key }}={{ item.value}}"
  with_items: "{{ os_environment }}"

以及它的变量:

os_environment:
  - key: DJANGO_SETTINGS_MODULE 
    value : websec.prod_settings  
  - key: DJANGO_SUPER_USER 
    value : admin

而且,是的,如果您 ssh 退出并返回,env 会显示新的环境变量。

附言它曾经是dest,如:

    dest: "/etc/environment"

但看评论

【讨论】:

  • dest 已替换为 path,但根据 the docs 应该仍然有效。如果没有,请切换到path
【解决方案4】:

要持续设置环境变量,您可以使用 Ansible Galaxy 的现有角色之一。我推荐weareinteractive.environment

使用 ansible-galaxy:

$ ansible-galaxy install weareinteractive.environment

使用 requirements.yml:

- src: franklinkim.environment

然后在你的剧本中:

- hosts: all
  sudo: yes
  roles:
    - role: franklinkim.environment
      environment_config:
        NODE_ENV: staging
        DATABASE_NAME: staging

【讨论】:

  • @openCivilisation 更新!
  • 注意:weareinteractive.environment 写入 /etc/environment
【解决方案5】:

这是最好的选择。正如 Michal Gasek(第一个答案)所说,由于合并了拉取请求(https://github.com/ansible/ansible/pull/8651), 我们可以通过游戏级别轻松设置永久环境变量

- hosts: all
  roles:
     - php
     - nginx
  environment:
    MY_ENV_VARIABLE: whatever_value

【讨论】:

  • 环境是否在角色之前运行?因为我的查找仍然是空的。
  • 无论订单如何,我的查找都是空的
  • 唯一需要注意的是,剧本级别中的环境将在剧本运行之前解决。如果您事先知道所有值,这将很有用,但是如果您想动态地添加一个值,我建议您遵循 JL Peyret 的回答
【解决方案6】:

您还可以使用自定义 become plugin 设置 env

主机设置

ansible_become=yes
ansible_become_method=foo

become_plugins/foo.py

from ansible.plugins.become import BecomeBase

class BecomeModule(BecomeBase):
    def build_become_command(self, cmd, shell):
        cmd = 'PYTHONPATH="/foo/bar:$PYTHONPATH" ' + cmd
        return cmd

【讨论】:

    猜你喜欢
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多