【问题标题】:Loop through array in Chef Template (ERB)在 Chef 模板 (ERB) 中循环遍历数组
【发布时间】:2016-10-31 21:59:26
【问题描述】:

我是chef 的新手,开始学习技巧,想知道以下是否可行以及如何实现。我来自过去 2 年一直在使用 ansible 的人。

我想知道如何操作.erb模板

ansible code - varible.yml

apache_vhosts:
  - servername: "{{ enterprise }}.test.io"
    serveralias: "{{ inventory_hostname }}"
    documentroot: "/var/www/test/current/web"
    symfony_prod: true
    redirect_https: true
  - servername: "{{ enterprise }}forms.test.io"
    documentroot: "/var/www/test/current/web"
    symfony_form: true
    redirect_https: true
  - servername: "{{ enterprise }}trk.test.io"
    documentroot: "/var/www/test/current/web"
    symfony_track: true
    redirect_https: true

ansible code - vhosts.conf.j2 (jinja template)

{% for vhost in apache_vhosts %}
<VirtualHost *:{{ apache_listen_port_http }}>
  ServerName {{ vhost.servername }}
{% if vhost.redirect_https is defined and vhost.redirect_https == true %}
  Redirect 301 / https://{{ vhost.servername }}/
  {% else %}
  DocumentRoot {{ vhost.documentroot }}
{% if vhost.serveradmin is defined %}
  ServerAdmin {{ vhost.serveradmin }}
{% endif %}

{% if vhost.symfony_dev is defined %}

  DirectoryIndex app_dev.php

  <Directory "{{ vhost.documentroot }}">
    AllowOverride None
    Options -Indexes +FollowSymLinks
    Order allow,deny
    Allow from all
    # Symfony2 rewriting rules
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule .? - [L]
    RewriteRule .? %{ENV:BASE}/app_dev.php [L]
  </Directory>
{% elif vhost.symfony_prod is defined %}

  DirectoryIndex app.php

  <Directory "{{ vhost.documentroot }}">
    AllowOverride None
    Options -Indexes +FollowSymLinks
    Order allow,deny
    Allow from all
    # Symfony2 rewriting rules
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule .? - [L]
    RewriteRule .? %{ENV:BASE}/app.php [L]
  </Directory>
{% else %}

  <Directory "{{ vhost.documentroot }}">
    AllowOverride All
    Options -Indexes +FollowSymLinks
    Order allow,deny
    Allow from all
  </Directory>

{% endif %}

{% if vhost.extra_parameters is defined %}
  {{ vhost.extra_parameters }}
{% endif %}

{% endif %}

</VirtualHost>

{% endfor %}

从上面的代码中,您可以看到我在.yml 文件中循环使用apache_vhosts,并在创建模板时使用内部对象。 .erb 可以做到这一点吗?我如何在.rb 属性文件中复制它。

目前我只有以下;

chef code - default.rb

# Apache attributes
default["altostack"]["apache_conf_path"] = "/etc/apache2/sites-enabled"
default["altostack"]["apache_redirect_https"] = false
default["altostack"]["apache_servername"] = "test.test.io"
default["altostack"]["apache_documentroot"] = "/var/www/test/current/web"
default["altostack"]["apache_ssl_crt_dir"] = case node.environment
when '_default'
  default["altostack"]["apache_ssl_crt_dir"] = "/etc/apache2/ssl/"
end

【问题讨论】:

    标签: ruby chef-infra ansible jinja2 erb


    【解决方案1】:

    要或多或少地复制您的ansible 格式:

    # Apache attributes
    
    default["altostack"]["test.test.io"]["apache_conf_path"] = "/etc/apache2/sites-enabled"
    default["altostack"]["test.test.io"]["apache_redirect_https"] = false
    default["altostack"]["test.test.io"]["apache_documentroot"] = "/var/www/test/current/web"
    default["altostack"]["test.test.io"]["apache_ssl_crt_dir"] = case node.environment
    when '_default'
       "/etc/apache2/ssl/"
    end
    
    #Alternative synteax with hash:
    
    default["altostack"]["test_2.test.io"]= {
      "apache_conf_path" => "/etc/apache2/sites-enabled",
      "apache_redirect_https" => false,
      "apache_documentroot" => "/var/www/test/current/web"
    }
    
    # For the case statement, better use the usual approach, easier to maitain IMHO
    default["altostack"]["test_2.test.io"]["apache_ssl_crt_dir"] = case node.environment
      when '_default'
         "/etc/apache2/ssl/"
      end
    

    在模板文件中:

    <% node['altostack'].each do |servername,properties| -%>
      <VirtualHost *:<%= properties['apache_redirect_https'] %>
        ServerName <%= servername %>
        <% if !properties['redirect_https'].nil? and properties['redirect_https'] == true -%>
      Redirect 301 / https://<%= servername %>/
      <% else -%>
      DocumentRoot <%= properties['documentroot'] %>
    <% if !properties['serveradmin'].nil? -%>
      ServerAdmin <%= properties['serveradmin'] %>
    <% endif -%>
    # Rest of template to be translated by yourself :)
    

    chef 中的模板语法使用 erb,它在 documentation here 中进行了介绍,并且在模板中接受纯 ruby​​。

    通常的建议是利用社区食谱,即apache2,它的自述文件中有一个很好的Usage 部分,以及web_app 资源的基本示例用法。

    【讨论】:

    • 感谢您,我避免过多关注社区食谱,因为我相信与同等的 ansible 银河角色相比,它们非常压倒性。我当然会研究它们的模式和结构。我的目标是理解语法并能够创建模板和使用属性,这样当我开始制作自己的食谱时,我就不会遇到任何意外。
    • @shady 在这种情况下,我强烈建议您通过learn.chef.io ;)
    • 我相信这更多地与了解ruby 语言和erb 引擎有关。同样学习ansible 不会教你如何使用jinja2 模板而不是你的python 除了模板引擎文档的知识
    • 对于模板,是的,但厨师文档涵盖了循环属性哈希时的基本用法。在您为 chef 编写复杂的提供程序之前,通常不需要高级 ruby​​
    • 也许我正在雄心勃勃地尝试将yaml 提升和转移到rb 哈哈。我需要创建散列的散列并循环以实现这一目标
    猜你喜欢
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 2023-03-20
    • 1970-01-01
    • 2021-01-19
    • 2015-01-15
    • 2016-07-01
    相关资源
    最近更新 更多