Firewall Dependency Cycle after Puppet 3 to 5 upgrade

asked 2018-09-21 09:33:26 -0500

atlas gravatar image

updated 2018-09-21 17:00:52 -0500

After upgrading from Puppet 3 to 5, we are seeing the following error:

Error: Found 1 dependency cycle:
(Firewall[001 INPUT allow loopback] => Firewall[001 INPUT allow loopback])\nCycle graph written to /opt/puppetlabs/puppet/cache/state/graphs/cycles.dot.
Error: Failed to apply catalog: One or more resource dependency cycles detected in graph

We have a module that leverages puppetlabs-firewall. The module has an init.pp which separately calls a pre.pp and a ip6pre.pp for IPv4 and IPv6 rulesets respectively. If the IPv4 and IPv6 rules are combined into one file, e.g. pre.pp, the error no longer persists. Here is what the original init.pp looked like:

class iptables_baseline(
  $purge = true,
){
  resources { [ 'firewall'] :
    purge => $purge,
  }
  Firewall {
    before  => Class['iptables_baseline::post', 'iptables_baseline::ip6post'],
    require => Class['iptables_baseline::pre', 'iptables_baseline::ip6pre'],
  }
  class{'iptables_baseline::pre':}
  class{'iptables_baseline::post':}
  class{'iptables_baseline::ip6pre':}
  class{'iptables_baseline::ip6post':}
  class { 'firewall':}

Here is the modified version that works with Puppet 5 where we had to combine the pre and post IPv4 and IPv6 manifests:

class iptables_baseline(
  $purge = true,
){
  resources { [ 'firewall'] :
    purge => $purge,
  }
  Firewall {
    before  => Class['iptables_baseline::post'],
    require => Class['iptables_baseline::pre'],
  }
  class{'iptables_baseline::pre':}
  class{'iptables_baseline::post':}
  class { 'firewall':}

Here is the original pre.pp:

class iptables_baseline::pre {
  Firewall {
    require => undef,
  }
  firewall { '000 accept icmp requests':
    proto    => 'icmp',
    action   => 'accept',
    provider => 'iptables',
  } ->
  firewall { '001 INPUT allow loopback':
    iniface  => 'lo',
    chain    => 'INPUT',
    action   => 'accept',
    proto    => 'all',
    provider => 'iptables',
  } ->
  firewall { '002 INPUT allow related and established':
    state    => ['RELATED', 'ESTABLISHED'],
    action   => 'accept',
    proto    => 'all',
    provider => 'iptables',
  } ->
  firewall { '100 allow ssh':
    state    => ['NEW'],
    dport    => '22',
    proto    => 'tcp',
    action   => 'accept',
    provider => 'iptables',
  }
}

Here is the original ip6pre.pp:

class iptables_baseline::ip6pre {
  Firewall {
    require => undef,
  }
  firewall { '000 ip6 accept all icmp requests':
    proto    => 'ipv6-icmp',
    action   => 'accept',
    provider => 'ip6tables',
  } ->
  firewall { '001 ip6 INPUT allow related and established':
    state    => ['RELATED', 'ESTABLISHED'],
    action   => 'accept',
    proto    => 'all',
    provider => 'ip6tables',
  }
}

Here is a list of the dependency cycle list:

digraph Resource_Cycles {
  label = "Resource Cycles"
"Firewall[001 INPUT allow loopback]" -> "Firewall[001 INPUT allow loopback]"
"Firewall[001 INPUT allow loopback]" -> "Firewall[001 ip6 INPUT allow related and established]" -> "Firewall[001 INPUT allow loopback]"
"Firewall[001 INPUT allow loopback]" -> "Firewall[002 INPUT allow related and established]" -> "Firewall[001 INPUT allow loopback]"
"Firewall[001 INPUT allow loopback]" -> "Firewall[002 INPUT allow related and established]" -> "Firewall[002 INPUT allow related and established]"
"Firewall[001 INPUT allow loopback]" -> "Firewall[100 allow ssh]" -> "Firewall[001 INPUT allow loopback]"
"Firewall[001 INPUT allow loopback]" -> "Firewall[100 allow ssh]" -> "Firewall[100 allow ssh]"

Thoughts on what may be causing the loop when using separate classes?

edit retag flag offensive close merge delete