Re: new user - understanding arrays as variables in defined types

94 views
Skip to first unread message

Dusty Doris

unread,
Nov 20, 2012, 4:30:45 PM11/20/12
to puppet...@googlegroups.com


On Tuesday, November 20, 2012 3:51:07 PM UTC-5, Dusty Doris wrote:
Lets say I wanted to make a declared type for adding custom firewall rules on a per-node basis.


define myfirewall::accept($proto, $port, $sources=[]) {
  include defaultfirewall

  $sources.each do |source|
    
    firewall { "100 allow $proto $port for $source":
      proto  => $proto,
      dport => $dport,
      source => $source,
      action   => 'accept',
    }

  end
}

I could use it something like this:

node "mynode" {
  myfirewall:: accept { "http": 
    proto => 'tcp',
    port   => '80',
    sources => ['1.1.1.1','2.2.2.2']
  }
}


Is there any way to do something like this with puppet?  I'm new to this and quite confused.



aha.  I found I can do it using the $name parameter.

Is there anything inherently wrong with this type of usage?


define myfirewall::accept($proto, $port) {

  firewall { "100 $name $proto $port":
    proto => $proto,
    dport => $port,
    source => $name,
    action => 'accept'
  }


node 'mynode' {
  include firewall
  myfirewall::accept { ['node1', 'node2'] :
    proto => 'tcp',
    port  => '80'
  }
}

joe

unread,
Nov 20, 2012, 5:15:12 PM11/20/12
to puppet...@googlegroups.com
Nothing wrong with that. It's a very common practice.

One thing I would recommend is setting your array to a variable and passing that variable to the define. It just makes your code cleaner and easier to read:

node 'mynode' {
  include firewall
  $sources = ['node1', 'node2']
  myfirewall::accept { $sources :

Dusty Doris

unread,
Nov 20, 2012, 5:32:06 PM11/20/12
to puppet...@googlegroups.com
Thanks for the reply, I did run into one problem with duplicate declarations.  Say I wanted to include node1 and node2 in a group of servers for a particular rule.  Then wanted to just have node1 in a second rule.

eg:

node 'mynode' {
  include firewall

  $apps = ['node1', 'node2']
  $ssl    = 'node1'

  myfirewall::accept { $apps :
    proto => 'tcp',
    ports => ['80','8080']
  }

  myfirewall::accept { 'node1' :
   proto => 'tcp',
   ports => '443'
  }
}

When I run that I get a duplicate declaration error such as Myfirewall::Accept[node1].  How does one get around something like that?  I can't think of a way to do that without assigning a unique name and then iterating on a source variable that is passed in.

BTW - I am using the puppetlabs-firewall module and unfortunately it doesn't work correctly with an array for the source variable, so that's why I'm stuck here.

Guillermo

unread,
Nov 20, 2012, 8:33:54 PM11/20/12
to puppet...@googlegroups.com

Hi.

You try this:

node 'mynode' {
  include firewall

  myfirewall::accept { 'node2':
    proto => 'tcp',


    ports => ['80','8080']
  }

  myfirewall::accept { 'node1' :
   proto => 'tcp',

   ports => ['80','8080','443']
  }
}

It is more simple and so you don't duplicate a declaration.

Sorry for my english

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/ZpskRkRDbZoJ.
To post to this group, send email to puppet...@googlegroups.com.
To unsubscribe from this group, send email to puppet-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.

Dusty Doris

unread,
Nov 20, 2012, 9:35:33 PM11/20/12
to puppet...@googlegroups.com
Thanks Guillermo.  I appreciate your reply.  

I am trying to batch these entries, which is why I was originally asking about how to iterate on an array inside a defined type.  The reasoning for this, is that I will have somewhere between 20 and 40 IPs that need access to certain ports on certain nodes.  I'd rather not have to do them one by one on each node, so I'm trying to find an easy way to group them together.  Perhaps I need to rethink my approach.

I'm just starting at the basics now, trying to understand how puppet works.

This was my concept, which could be extracted into classes or modules or something.  

accept { $app_servers:
  proto => 'tcp',
  ports => ['80','3306','389','443']
}

accept { $backup_servers:
  proto => 'tcp'
  ports => ['873']
}

accept { $mail_relays:
  proto => 'tcp',
  ports => ['25','875']
}


Thanks for any suggestions.  I'll keep reading the docs and start looking at more code in the modules.
Reply all
Reply to author
Forward
0 new messages