Apache 在通知另一个类中的资源时解析puppet中的循环依赖关系

Apache 在通知另一个类中的资源时解析puppet中的循环依赖关系,apache,puppet,puppet-enterprise,Apache,Puppet,Puppet Enterprise,我编写了一个apache类,它安装apache2并配置ssl,然后启动apache服务。我正在编写一个子类,它将配置一个虚拟主机,然后重新启动apache服务。当我试图在添加虚拟主机后通知apache2服务时,出现循环依赖项错误 我通过将require更改为include解决了这个错误,但这是否意味着apache类中的资源将在apache::no之前运行 如果不是,那么解决此依赖项错误的方法是什么 通知另一个类中的资源是一种好的做法吗 Error: Failed to apply catalog

我编写了一个apache类,它安装apache2并配置ssl,然后启动apache服务。我正在编写一个子类,它将配置一个虚拟主机,然后重新启动apache服务。当我试图在添加虚拟主机后通知apache2服务时,出现循环依赖项错误

我通过将require更改为include解决了这个错误,但这是否意味着apache类中的资源将在apache::no之前运行

如果不是,那么解决此依赖项错误的方法是什么

通知另一个类中的资源是一种好的做法吗

Error: Failed to apply catalog: Found 1 dependency cycle:
(Exec[no] => Service[apache2] => Class[Apache] => Class[Apache::No] => Exec[no])
Try the '--graph' option and opening the resulting '.dot' file in OmniGraffle or GraphViz
apache.pp

class apache {

    $listen_port="8181"
    $no_port="4143"
    #file { '/etc/apache2/ports.conf' :
        #ensure => present ,
        #content => template("apache/ports.conf.erb"),
        #require => Package['apache2'],
        #notify => Service['apache2'],
    #}->
    case $facts['osfamily'] {
    /^(Debian|Ubuntu)$/: {
    file { '/etc/apache2/sites-available/000-default.conf' :
        ensure => present ,
        content => template("apache/000-default.conf.erb"),
        require => Package['apache2'],
        notify => Service['apache2'],
        noop => true,
    }
    file { '/etc/apache2/sites-available/default-ssl.conf':
        ensure => present ,
        content => template("apache/default-ssl.conf.erb"),
        require => Package['apache2'],
        notify => Service['apache2'],
        #noop => true,
    }
    file { ['/etc','/etc/apache2','/etc/apache2/ssl'] :
        ensure => directory,
        require => Package['apache2'],
    }
    package { 'apache2' :
        ensure => latest,
        notify => Exec['ssl']
    } ->
    augeas { 'no' :
        context => "/files/etc/apache2/ports.conf",
        changes => [
                       "set /files/etc/apache2/sites-available/default-ssl.conf/IfModule/VirtualHost/directive[2]/arg localhost",
                       "set /files/etc/apache2/sites-available/default-ssl.conf/IfModule/VirtualHost/directive[8]/arg /etc/apache2/ssl/apache.key",
                       "set /files/etc/apache2/sites-available/default-ssl.conf/IfModule/VirtualHost/directive[7]/arg /etc/apache2/ssl/apache.crt",
                       "set /files/etc/apache2/ports.conf/IfModule[2]/directive/arg $$no_port",
                       "set /files/etc/apache2/ports.conf/IfModule[1]/directive/arg $no_port",
                       "set /files/etc/apache2/ports.conf/directive/arg 8181",
                       "set /files/etc/apache2/sites-available/000-default.conf/VirtualHost/arg *:8181",
                       "set /files/etc/apache2/sites-available/default-ssl.conf/IfModule/VirtualHost/arg *:$no_port",
                   ],
        require => Package['apache2'],
    } ->
    service { 'apache2' :
        ensure => running
    }
    package { 'openssl' :
        ensure => latest
    } ->
    exec { 'ssl' :
        path => ["/usr/local/sbin","/usr/local/bin","/usr/sbin","/usr/bin","/sbin","/bin"],
        command => 'openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt -subj "/C=GB/ST=London/L=London/O=Global Security/OU=IT Department/CN=example.com" ; a2enmod ssl ; a2ensite default-ssl ',
        notify => Service['apache2'],
        require => Augeas['no'],
        refreshonly => true,
    }
    }
}
没有


谢谢

您的代码确实不一致。由

require ::apache
。。。它坚持通过类
::apache
管理的所有内容都必须在当前类中声明任何内容之前进行管理,但是

Exec { 'no' :
   # ...
   notify => Service['apache2'],
   # ...
}
。。。要求在
服务['apache2']
之前管理
Exec['no']
,该服务由类
管理:apache2
。你不能两全其美

这个问题源于抽象层次的混合。在一个地方,您表达了与整个类的关系,而在另一个地方,您只表达了与该类的一部分的关系。有两种基本的方法可以解决这个问题:要么建立单独的类大小的块来声明单独的关系,要么直接与相关资源建立所有需要的关系(在这种情况下是
服务
)。后者是可以接受的,只是因为您在同一个模块中工作,但即使如此,前者可能更好。可能是这样的:

class apache {
  # declare variables ...
  include '::apache::software'
  include '::apache::config'
  include '::apache::service'

  Class['::apache::software'] -> Class['::apache::config']
  Class['::apache::config']   ~> Class['::apache::service']
}

# ... class apache::software manages ensuring the package is installed
# ... class apache::config manages the configuration file
# ... class apache::service manages the httpd service

class apache::no {
    require 'apache::config'
    # ...
  Exec { 'no' :
    # ...
    notify => Class['apache::service']
  }
}
class apache {
  # declare variables ...
  include '::apache::software'
  include '::apache::config'
  include '::apache::service'

  Class['::apache::software'] -> Class['::apache::config']
  Class['::apache::config']   ~> Class['::apache::service']
}

# ... class apache::software manages ensuring the package is installed
# ... class apache::config manages the configuration file
# ... class apache::service manages the httpd service

class apache::no {
    require 'apache::config'
    # ...
  Exec { 'no' :
    # ...
    notify => Class['apache::service']
  }
}