Configure Apache with Salt Stack

Updated by Linode Written by Linode

Contribute on GitHub

Report an Issue | View File | Edit File

Marquee image for Configure Apache with Salt Stack

Salt is a powerful configuration management tool. In this guide you will create Salt state files that are capable of installing and configuring Apache on Ubuntu 18.04, Debian 9, or CentOS 7.

Before You Begin

You will need at least two Linodes with Salt installed. If you have not already, read our Getting Started with Salt - Basic Installation and Setup Guide and follow the instructions for setting up a Salt master and minion.

The following steps will be performed on your Salt master.

Note
The steps in this guide require root privileges. Be sure to run the steps below as root or with the sudo prefix. For more information on privileges, see our Users and Groups guide.

Setting Up Your Salt Master and Managed Files

Salt Master SLS Files

  1. Create the /srv/salt directory if it does not already exist:

    mkdir /srv/salt
    
  2. Create a Salt top file in /srv/salt that will be Salt’s entry point to the Apache configuration:

    /srv/salt/top.sls
    1
    2
    3
    4
    5
    6
    7
    8
    
    base:
      'G@os_family:Debian':
        - match: compound
        - apache-debian
    
      'G@os:CentOS':
        - match: compound
        - apache-centos

    This top file uses compound matching to target your minions by operating system using Salt Grains. This will allow Salt to choose the appropriate Apache configuration depending on the Linux distribution. These matchers could be extended to be even more specific. For instance, if you wanted to only target minions with the ID of web-server that are running on Ubuntu, you can type web* and G@os:Ubuntu.

Pillar Files

  1. Create the /srv/pillar directory if it does not already exist:

    mkdir /srv/pillar
    
  2. Create a Pillar top file. This top file references the apache.sls Pillar file that you will create in the next step:

    /srv/pillar/top.sls
    1
    2
    3
    
    base:
      '*':
        - apache
  3. Create the apache.sls file that was referenced in the previous step. This file defines Pillar data that will be used inside our Apache state file in the next section, in this case your domain name. Replace example.com with your domain:

    /srv/pillar/apache.sls
    1
    
    domain: example.com

Website Files

  1. Create a directory for your website files in the /srv/salt directory. Replace example.com with your website domain name:

    mkdir /srv/salt/example.com
    

    This directory will be accessible from your Salt state files at salt://example.com.

  2. Create an index.html file for your website in the /srv/salt/example.com directory, substituting example.com for the folder name you chose in the previous step. You will use this file as a test to make sure your website is functioning correctly.

    /srv/salt/example.com/index.html
    1
    2
    3
    4
    5
    
    <html>
      <body>
        <h1>Server Up and Running!</h1>
      </body>
    </html>

Configuration Files

  1. Create a folder for your additional configuration files at /srv/salt/files. These files will be accessible at salt://files.

    mkdir /srv/salt/files
    
  2. Create a file called tune_apache.conf in /srv/salt/files and paste in the following block:

    /srv/salt/files/tune_apache.conf
    1
    2
    3
    4
    5
    6
    7
    
    <IfModule mpm_prefork_module>
    StartServers 4
    MinSpareServers 20
    MaxSpareServers 40
    MaxClients 200
    MaxRequestsPerChild 4500
    </IfModule>

    This MPM prefork module provides additional tuning for your Apache installation. This file will be managed by Salt and installed into the appropriate configuration directory in a later step.

  3. If you will be installing Apache on a CentOS machine, create a file called include_sites_enabled.conf in /srv/salt/files and paste in the following:

    /srv/salt/files/include_sites_enabled.conf
    1
    
    IncludeOptional sites-enabled/*.conf

    This file will allow us to use file directories like those found on Debian installations to help organize the Apache configuration.

Creating the Apache State File for Debian and Ubuntu

Individual Steps

This guide will be going through the process of creating the Apache for Debian and Ubuntu state file step by step. If you would like to view the entirety of the state file, you can view it at the end of this section.

  1. Create a state file named apache-debian.sls in /srv/salt and open it in a text editor of your choice.

  2. Instruct Salt to install the apache2 package and start the apache2 service:

    /srv/salt/apache-debian.sls
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    apache2:
      pkg.installed
    
    apache2 Service:
      service.running:
        - name: apache2
        - enable: True
        - require:
          - pkg: apache2
    
    ...

    Here Salt makes sure the apache2 package is installed with pkg.installed. Likewise, it ensures the apache2 service is running and enabled under service.running. Also under service.running, apache-debian.sls uses require to ensure that this command does not run before the apache2 package is installed. This require step will be repeated throughout apache-debain.sls.

    Lastly, a watch statement is employed to restart the apache2 service if your site’s configuration file changes. You will define that configuration file in a later step. Note that this configuration file is named using the domain you supplied when creating your Salt Pillar file in the first section. This Pillar data will be used throughout apache-debian.sls.

  3. Turn off KeepAlive:

    /srv/salt/apache-debian.sls
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    ...
    
    Turn Off KeepAlive:
      file.replace:
        - name: /etc/apache2/apache2.conf
        - pattern: 'KeepAlive On'
        - repl: 'KeepAlive Off'
        - show_changes: True
        - require:
          - pkg: apache2
    ...

    KeepAlive allows multiple requests to be sent over the same TCP connection. For the purpose of this guide KeepAlive will be disabled. To disable it, Salt is instructed to find the KeepAlive directive in /etc/apache2/apache2.conf by matching a pattern and replacing it with KeepAlive Off. show_changes instructs Salt to display any changes it has made during a highstate.

  4. Transfer tune_apache.conf to your minion and enable it:

    /srv/salt/apache-debian.sls
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    ...
    
    /etc/apache2/conf-available/tune_apache.conf:
      file.managed:
        - source: salt://files/tune_apache.conf
        - require:
          - pkg: apache2
    
    Enable tune_apache:
      apache_conf.enabled:
        - name: tune_apache
        - require:
          - pkg: apache2
    
    ...

    This step takes the tune_apache.conf file you created in the Configuration Files step and transfers it to your Salt minion. Then, Salt enables that configuration file with the apache_conf module.

  5. Create the necessary directories:

    /srv/salt/apache-debian.sls
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    ...
    
    /var/www/html/{{ pillar['domain'] }}:
      file.directory
    
    /var/www/html/{{ pillar['domain'] }}/log:
      file.directory
    
    /var/www/html/{{ pillar['domain'] }}/backups:
      file.directory
    
    /var/www/html/{{ pillar['domain'] }}/public_html:
      file.directory
    
    ...
  6. Disable the default virtual host configuration file:

    /srv/salt/apache-debian.sls
    1
    2
    3
    4
    5
    6
    7
    8
    
    ...
    
    000-default:
      apache_site.disabled:
        - require:
          - pkg: apache2
    
    ...

    This step uses Salt’s apache_site module to disable the default Apache virtual host configuration file, and is the same as running a2dissite on a Debian-based machine.

  7. Create your site’s virtual host configuration file:

    /srv/salt/apache-debian.sls
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    ...
    
    /etc/apache2/sites-available/{{ pillar['domain'] }}.conf:
      apache.configfile:
        - config:
          - VirtualHost:
              this: '*:80'
              ServerName:
                - {{ pillar['domain'] }}
              ServerAlias:
                - www.{{ pillar['domain'] }}
              DocumentRoot: /var/www/html/{{ pillar['domain'] }}/public_html
              ErrorLog: /var/www/html/{{ pillar['domain'] }}/log/error.log
              CustomLog: /var/www/html/{{ pillar['domain'] }}/log/access.log combined
    
    ...

    This step uses Salt’s apache module, (not to be confused with the apache_site module used in the previous step), to create your site’s virtual host configuration file. The this variable signifies what would traditionally be include with VirtualHost within angle brackets in an Apache configuration file: <VirtualHost *:80>.

  8. Enable your new virtual host configuration file:

    /srv/salt/apache-debian.sls
    1
    2
    3
    4
    5
    6
    7
    8
    
    ...
    
    {{ pillar['domain'] }}:
      apache_site.enabled:
        - require:
          - pkg: apache2
    
    ...

    This step uses the same apache_site module you used to disable the default virtual host file to enable your newly created virtual host file. apache_site.enabled creates a symlink from /etc/apache2/sites-available/example.com.conf to /etc/apache2/sites-enabled/example.com.conf and is the same as running a2ensite on a Debian-based machine.

  9. Transfer your index.html website file to your minion:

    /srv/salt/apache-debian.sls
    1
    2
    3
    4
    5
    
    ...
    
    /var/www/html/{{ pillar['domain'] }}/public_html/index.html:
      file.managed:
        - source: salt://{{ pillar['domain'] }}/index.html

    Any changes made to your index.html file on your Salt master will be propagated to your minion.

    Note

    Since Salt is not watching configuration files for a change to trigger a restart for Apache, you may need to use the command below from your Salt master.

    salt '*' apache.signal restart
    

Complete State File

The complete apache-debian.sls file looks like this:

/srv/salt/apache-debian.sls
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
apache2:
  pkg.installed

apache2 Service:
  service.running:
    - name: apache2
    - enable: True
    - require:
      - pkg: apache2

Turn Off KeepAlive:
  file.replace:
    - name: /etc/apache2/apache2.conf
    - pattern: 'KeepAlive On'
    - repl: 'KeepAlive Off'
    - show_changes: True
    - require:
      - pkg: apache2

/etc/apache2/conf-available/tune_apache.conf:
  file.managed:
    - source: salt://files/tune_apache.conf
    - require:
      - pkg: apache2

Enable tune_apache:
  apache_conf.enabled:
    - name: tune_apache
    - require:
      - pkg: apache2

/var/www/html/{{ pillar['domain'] }}:
  file.directory

/var/www/html/{{ pillar['domain'] }}/log:
  file.directory

/var/www/html/{{ pillar['domain'] }}/backups:
  file.directory

/var/www/html/{{ pillar['domain'] }}/public_html:
  file.directory

000-default:
  apache_site.disabled:
    - require:
      - pkg: apache2

/etc/apache2/sites-available/{{ pillar['domain'] }}.conf:
  apache.configfile:
    - config:
      - VirtualHost:
          this: '*:80'
          ServerName:
            - {{ pillar['domain'] }}
          ServerAlias:
            - www.{{ pillar['domain'] }}
          DocumentRoot: /var/www/html/{{ pillar['domain'] }}/public_html
          ErrorLog: /var/www/html/{{ pillar['domain'] }}/log/error.log
          CustomLog: /var/www/html/{{ pillar['domain'] }}/log/access.log combined

{{ pillar['domain'] }}:
  apache_site.enabled:
    - require:
      - pkg: apache2

/var/www/html/{{ pillar['domain'] }}/public_html/index.html:
  file.managed:
    - source: salt://{{ pillar['domain'] }}/index.html

Creating an Apache State File for CentOS

Individual Steps

  1. Create a file called apache-centos.sls in /srv/salt and open it in a text editor of your choice.

  2. On CentOS Apache is named httpd. Instruct Salt to install httpd and run the httpd service:

    /srv/salt/apache-centos.sls
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    httpd:
      pkg.installed
    
    httpd Service:
      service.running:
        - name: httpd
        - enable: True
        - require:
          - pkg: httpd
        - watch:
          - file: /etc/httpd/sites-available/{{ pillar['domain'] }}.conf
    
    ...

    Here Salt makes sure the httpd package is installed with pkg.installed. Likewise, it ensures the httpd service is running and enabled under service.running. Also under service.running, apache-debian.sls uses require to ensure that this command does not run before the httpd package is installed. This require step will be repeated throughout apache-centos.sls.

    Lastly, a watch statement is employed to restart the httpd service if your site’s configuration file changes. You will define that configuration file in a later step. Note that this configuration file is named using the domain you supplied when creating your Salt Pillar file in the first section. This Pillar data will be used throughout apache-centos.sls.

  3. Turn off KeepAlive:

    /srv/salt/apache-centos.sls
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    ...
    
    Turn Off KeepAlive:
      file.replace:
        - name: /etc/httpd/conf/httpd.conf
        - pattern: 'KeepAlive On'
        - repl: 'KeepAlive Off'
        - show_changes: True
        - require:
          - pkg: httpd
    ...

    KeepAlive allows multiple requests to be sent over the same TCP connection. For the purpose of this guide KeepAlive will be disabled. To disable it, Salt is instructed to find the KeepAlive directive in /etc/httpd/conf/httpd.conf by matching a pattern and replacing it with KeepAlive Off. show_changes instructs Salt to display any changes it has made during a highstate.

  4. Change the DocumentRoot:

    /srv/salt/apache-centos.sls
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    ...
    
    Change DocumentRoot:
      file.replace:
        - name: /etc/httpd/conf/httpd.conf
        - pattern: 'DocumentRoot "/var/www/html"'
        - repl: 'DocumentRoot "/var/www/html/{{ pillar['domain'] }}/public_html"'
        - show_changes: True
        - require:
          - pkg: httpd
    
    ...

    Similar to the last step, in this step salt-centos.sls instructs Salt to search for the DocumentRoot directive in Apache’s httpd.conf file, and replaces that line with the new document root. This allows for the use of a Debian-style site directory architecture.

  5. Transfer the tune_apache.conf and include_sites_enabled.conf to your minion.

    /srv/salt/apache-centos.sls
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    ...
    
    /etc/httpd/conf.d/tune_apache.conf:
      file.managed:
        - source: salt://files/tune_apache.conf
        - require:
          - pkg: httpd
    
    /etc/httpd/conf.d/include_sites_enabled.conf:
      file.managed:
        - source: salt://files/include_sites_enabled.conf
        - require:
          - pkg: httpd
    
    ...
  6. Create the necessary directories:

    srv/salt/apache-centos.sls
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    ...
    
    /etc/httpd/sites-available:
      file.directory
    
    /etc/httpd/sites-enabled:
      file.directory
    
    /var/www/html/{{ pillar['domain'] }}:
      file.directory
    
    /var/www/html/{{ pillar['domain'] }}/backups:
      file.directory
    
    /var/www/html/{{ pillar['domain'] }}/public_html:
      file.directory
    
    ...
  7. Create your site’s virtual host configuration file:

    /srv/salt/apache-centos.sls
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    ...
    
    /etc/httpd/sites-available/{{ pillar['domain'] }}.conf:
      apache.configfile:
        - config:
          - VirtualHost:
              this: '*:80'
              ServerName:
                - {{ pillar['domain'] }}
              ServerAlias:
                - www.{{ pillar['domain'] }}
              DocumentRoot: /var/www/html/{{ pillar['domain'] }}/public_html
      file.symlink:
        - target: /etc/httpd/sites-enabled/{{ pillar['domain'] }}.conf
        - force: True
    
    ...

    This step uses Salt’s apache module to create your site’s virtual host configuration file. The this variable signifies what would traditionally be include with VirtualHost within angle brackets in an Apache configuration file: <VirtualHost *:80>.

  8. Transfer your index.html website file to your minion:

    /srv/salt/apache-debian.sls
    1
    2
    3
    4
    5
    6
    7
    
    ...
    
    /var/www/html/{{ pillar['domain'] }}/public_html/index.html:
      file.managed:
        - source: salt://{{ pillar['domain'] }}/index.html
    
    ...

    Any changes made to your index.html file on your Salt master will be propigated to your minion.

  9. Configure your firewall to allow http and https traffic:

    /srv/salt/apache-centos.sls
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    ...
    
    Configure Firewall:
      firewalld.present:
        - name: public
        - ports:
          - 22/tcp
          - 80/tcp
          - 443/tcp
    Note
    It is imperative that you list all ports you need open to your machine in this section. Failure to list these ports will result in their closure by Salt.

Complete State File

The complete apache-centos.sls file looks like this:

/srv/salt/apache-centos.sls
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
httpd:
  pkg.installed

httpd Service:
  service.running:
    - name: httpd
    - enable: True
    - require:
      - pkg: httpd
    - watch:
      - file: /etc/httpd/sites-available/{{ pillar['domain'] }}.conf

Turn off KeepAlive:
  file.replace:
    - name: /etc/httpd/conf/httpd.conf
    - pattern: 'KeepAlive On'
    - repl: 'KeepAlive Off'
    - show_changes: True
    - require:
      - pkg: httpd

Change DocumentRoot:
  file.replace:
    - name: /etc/httpd/conf/httpd.conf
    - pattern: 'DocumentRoot "/var/www/html"'
    - repl: 'DocumentRoot "/var/www/html/{{ pillar['domain'] }}/public_html"'
    - show_changes: True
    - require:
      - pkg: httpd

/etc/httpd/conf.d/tune_apache.conf:
  file.managed:
    - source: salt://files/tune_apache.conf
    - require:
      - pkg: httpd

/etc/httpd/conf.d/include_sites_enabled.conf:
  file.managed:
    - source: salt://files/include_sites_enabled.conf
    - require:
      - pkg: httpd

/etc/httpd/sites-available:
  file.directory

/etc/httpd/sites-enabled:
  file.directory

/var/www/html/{{ pillar['domain'] }}:
  file.directory

/var/www/html/{{ pillar['domain'] }}/backups:
  file.directory

/var/www/html/{{ pillar['domain'] }}/public_html:
  file.directory

/etc/httpd/sites-available/{{ pillar['domain'] }}.conf:
  apache.configfile:
    - config:
      - VirtualHost:
          this: '*:80'
          ServerName:
            - {{ pillar['domain'] }}
          ServerAlias:
            - www.{{ pillar['domain'] }}
          DocumentRoot: /var/www/html/{{ pillar['domain'] }}/public_html
  file.symlink:
    - target: /etc/httpd/sites-enabled/{{ pillar['domain'] }}.conf
    - force: True

/var/www/html/{{ pillar['domain'] }}/public_html/index.html:
  file.managed:
    - source: salt://{{ pillar['domain'] }}/index.html

Configure Firewall:
  firewalld.present:
    - name: public
    - ports:
      - 22/tcp
      - 80/tcp
      - 443/tcp

Running the Apache State File

On your Salt master, issue a highstate command:

salt '*' state.apply

After a few moments you should see a list of Salt commands and a summary of their successes. Navigate to your website’s domain name if you have your DNS set up already, or your website’s public IP address. You should see your index.html file. You have now used Salt to configure Apache. Visit the links in the section below for more information.

More Information

You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

Join our Community

Find answers, ask questions, and help others.

This guide is published under a CC BY-ND 4.0 license.