published on 9 November 2010

Editor's Note: The Ruby DSL was deprecated in Puppet 3x, and is removed in Puppet 4.0.0.

Starting in Puppet 2.6.x, manifests can be written in Ruby.

Motivations:

  1. Developers can generate puppet resources without having to learn the Puppet DSL.
  2. Possible to overcome any limitations of the Puppet DSL.
  3. Ruby already has well known unit testing frameworks.

Methods:

Puppet's Ruby DSL introduces two types of methods:

Methods that create scopes:

  • define
    • Allows the user to implement a defined resource type in Ruby.

      define "services::port", :port, :protocol => 'tcp' do
        ...
      end
      

      port and protocols are accessible within the block as instance variables.

  • hostclass
    • Creates a class.

      hostclass :fooclass, :foo do
      
      end
      

  • node
    • Creates a node scope which can be used to associate resources with a certain node.

      node 'mynode' do
        include apache
      end
      

    Each of these methods accepts a block in which resources can be declared. Resources can only be declared in one of these blocks.

    Methods that create resources

  • Resources are create by calling a method with the same name as the resource.


    #/etc/puppet/manifests/blah.rb
    hostclass :blah do
      file '/tmp/blah', :content => 'bar'
    end
    node 'default' do
      include 'blah'
    end
    


    Now I can run puppet apply on the Ruby file to create the file:


    # puppet /etc/puppet/manifests/blah.rb
    notice: /Stage[main]/Blah/File[/tmp/blah]/ensure: defined content as '{md5}37b51d194a7513e45b56f6524f2d51f2'
    


    Attributes passed to a defined resource or hostclass will be available as instance variables within the block.


    define :foo, :bar do
      notify @name, :message => @bar
    end
    


    Examples

    One of the oldest open tickets in Puppet requests mkdir_p functionality (It's #86 :) ). We can easily code this with the Ruby DSL since Ruby can iterate over all directory subpaths to create File resources.


    define :mkdir_p do
      name = @name
      until name == '/'
        file name, :ensure => 'directory'
        name = File.dirname(name)
      end
    end
    node 'default' do
      mkdir_p '/tmp/foo/bar/baz'
    end
    


    Now puppet will create all directories in this path!


    $ puppet mkdir_p.rb
    notice: /Stage[main]//Node[default]/Mkdir_p[/tmp/foo/bar/baz]/File[/tmp/foo]/ensure: ensure changed 'file' to 'directory'
    notice: /Stage[main]//Node[default]/Mkdir_p[/tmp/foo/bar/baz]/File[/tmp/foo/bar]/ensure: created
    notice: /Stage[main]//Node[default]/Mkdir_p[/tmp/foo/bar/baz]/File[/tmp/foo/bar/baz]/ensure: created
    
    


    Now, we could use this defined resource type in a function to create a file with its parent directories:

    define :with_parents do
      mkdir_p File.dirname(@name)
      file @name, :ensure => 'present'
    end
    
    define :mkdir_p do
      name = @name
      until name == '/'
        file name, :ensure => 'directory'
        name = File.dirname(name)
      end
    end
    
    node 'default' do
      with_parents '/tmp/foo/bar/baz/myfile'
    end
    


  • Share via:
    Posted in:

    First a small note. The manifests are not fully declarative but they produce a catalog that is. We decided that it was more valuable to add iteration to the Puppet Language as this was the main reason for using the Ruby DSL.

    The Ruby DSL was also very limited in what could be expressed.
    There was an attempt of reaching the same level of functionality in the Ruby DSL as in the Puppet manifests. It did not quite succeed, and the result was far more unsafe (small mistakes could have grave consequences like stopping, hanging or crashing the puppet master). This attempt was reverted and never released and the remaining very limited (earlier released) Ruby DSL was deprecated, and subsequently removed.

    Hi,
    I understand that RubyDSL support has been removed. But I guess "pure ruby" support is now available. Am I wrong in my understanding ?
    I came to this conclusion from below link.

    https://docs.puppetlabs.com/guides/faq.html#why-does-puppet-have-its-ow…

    "As for just using Ruby as the input format, Puppet 2.6.0 actually added this functionality, and manifests can now be written in pure Ruby. However, this capability should be used carefully and avoided where possible: the full grammar of Ruby is often too much functionality, and we believe systems administrators should be able to model their datacenters in a higher-level system"

    Hi, SpareSlant,

    That bit of the FAQ is outdated and should have been removed when we deprecated the Ruby DSL, which it is referring to. It is possible to use Ruby for some things, like writing custom facts.

    Sorry for the confusion (and the outdated FAQ). I filed a ticket to make more general updates to that document.

    Add new comment

    The content of this field is kept private and will not be shown publicly.

    Restricted HTML

    • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
    • Lines and paragraphs break automatically.
    • Web page addresses and email addresses turn into links automatically.