One place for hosting & domains

      Secrets Management with Salt


      Updated by Linode Contributed by Linode

      Salt is a powerful configuration management tool which helps you manage your server deployments with configuration state files. These files are easily shared with others on your team and can be checked in to version control systems like Git.

      A common problem when working with Salt’s state files is the need access to sensitive data, like API keys and database passwords, within those files. Directly embedding that information as plain-text inside your state files can represent a security vulnerability, especially if you were to check those files into version control. This guide will explore some common methods for securing your secrets within Salt.

      Salt Pillar

      A primary method for storing secrets in Salt is to keep them in Salt’s Pillar feature. Salt Pillar is designed to maintain secrets and other variable information in a single location (generally, on the Salt master) and then deliver that information to specific minions. If you separate your secrets out from your states and into pillar files, you can ignore those files in your version control system.

      Note

      In addition to storing secrets, Salt Pillar can also maintain non-sensitive data; for example, the versions of the packages you want to install on your minions. So, you may still want to track some pillar files in version control.

      To handle this distinction, you could create a special directory at /srv/pillar/secrets and add set your version control system to ignore that directory (when using Git, list this directory in your .gitignore file). Keep all sensitive data inside pillar files within this directory, and maintain non-sensitive data in pillar files in /srv/pillar or another subfolder.

      Anatomy of Pillar Data Files

      Pillar data is kept in .sls files which are written in the same YAML syntax as states. These are generally stored within /srv/pillar on the Salt master, but this location can be configured via the pillar_roots option in your master’s configuration.

      For example, let’s say your minion runs an application which accesses the Linode API. This example pillar file records your API token in a variable called linode_api_token:

      /srv/pillar/app_secrets.sls
      1
      
      linode_api_token: YOUR_API_TOKEN

      As with state files, a top file (separate from your states’ top file) maps pillar data to minions. This example top file maps your app_secrets pillar data to your app server:

      /srv/pillar/top.sls
      1
      2
      3
      
      base:
        'appserver':
          - app_secrets

      Note

      You may want to create a pillar.example file (like those provided by Salt formulas) that lists all the known variable keys for your pillar but does not contain the actual secrets. If you check this file into your version control, other users that clone your states’ repository can duplicate this example pillar file and more quickly set up their own deployments.

      Accessing Pillar Data inside Salt States

      To inject pillar data into your states, use Salt’s Jinja template syntax. While Salt uses the YAML syntax for state and pillar files, the files are first interpreted as Jinja templates (by default).

      This example state embeds the API token in a file on your Linode; the data is accessed through the pillar dictionary:

      /srv/salt/setup_app.sls
      1
      2
      3
      4
      
      api_token:
        file.managed:
          - name: /var/your_app/api_token
          - contents: {{ pillar['linode_api_token'] }}

      Caution

      There are times when pillar data could show up in the output that Salt generates, like when file.managed displays diffs of a modified file. To avoid displaying these diffs, you can set file.managed’s show_diff flag to false.

      Passing Pillar Data at the Command Line

      You can also supply pillar values as a dictionary through the command line, and those values will override any values set in your pillar files. This example command would apply the A_DIFFERENT_API_TOKEN value instead of the original YOUR_API_TOKEN from the previous example:

      salt '*' state.apply pillar='{"linode_api_token": "A_DIFFERENT_API_TOKEN"}'
      

      Environment Variables

      Another way to keep sensitive values out of version control is to use environment variables. The method for passing environment variables to your states is similar to how pillar data can be passed via the command line. The environment variable prefixes your salt command, as in this example:

      LINODE_API_TOKEN="YOUR_API_TOKEN" salt 'appserver' state.apply setup_app
      

      The environment variable is referenced by a Salt state file through the salt['environ.get']('ENVIRONMENT_VARIABLE_NAME') syntax. The previous setup_app example state can be adapted to use an environment variable as follows:

      /srv/salt/setup_app.sls
      1
      2
      3
      4
      
      api_token:
        file.managed:
          - name: /var/your_app/api_token
          - contents: {{ salt['environ.get']('LINODE_API_TOKEN') }}

      As with the previous pillar example, you’ll want to keep file.managed’s diffs from appearing on screen when dealing with sensitive information by setting show_diff: false. For more information, see Using Environment Variables in SLS Modules.

      GPG Encryption

      You can use Salt’s GPG renderer to decrypt GPG ciphers that are located in your pillar files. This decryption step happens before your pillar data is passed to your minions. As a result, any value in a pillar file can be encrypted. Because the values are encrypted, you can store your pillar files in version control securely.

      This approach requires that the GPG secret key is stored on your Salt master. It also makes sense to include the public key in version control so that your team members can use it to encrypt new data for your pillar files.

      SDB

      Salt comes with a database interface called SDB that was initially created to store non-minion-specific data, such as passwords. It was designed to connect to a package like Salt’s keyring module, but other options are available, such as Consul and Vault.

      These databases are set up using a configuration profile in /srv/salt/master.d. To access data, you supply an sdb:// url, such as password: sdb://mysecrets/mypassword. For more information on SDB, reference the Salt SDB documentation.

      Note

      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.

      Find answers, ask questions, and help others.

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



      Source link

      Use and Modify Official SaltStack Formulas


      Updated by Linode Contributed by Linode

      Salt State Files

      The SaltStack Platform is made up of two primary components: A remote execution engine which handles bi-directional communication for any node within your infrastructure (master and minions), and a configuration management system which maintains all infrastructure nodes in a defined state. Salt’s configuration management system is known as the Salt State system. A Salt state is declared within a Salt State file (SLS) using YAML syntax and represents the information Salt needs to configure minions. A Salt Formula is a collection of related SLS files that will achieve a common configuration.

      SaltStack’s GitHub page contains Salt formulas for commonly needed configurations, like creating and managing SSL/TLS certificates, installing and configuring the Apache HTTP Server, installing and configuring a WordPress site and many other useful formulas. You can easily add any of these pre-written formulas to your own Salt state tree using GitHub.

      This guide will use GitHub to fork and modify SaltStack’s timezone formula and then use the formula on a Salt master to configure the time zone on two minions.

      Before You Begin

      1. If you are new to SaltStack, read A Beginner’s Guide to Salt to familiarize yourself with basic Salt concepts.

      2. Download Git on your local computer by following our How to Install Git on Linux, Mac or Windows guide.

      3. Familiarize yourself with Git using our Getting Started with Git guide.

      4. Make sure you have configured git on your local computer.

      5. Use the Getting Started with Salt – Basic Installation and Setup guide to set up a Salt Master and two Salt minions: one running Ubuntu 18.04 and the second running CentOS 7.

      6. Complete the sections of our Securing Your Server to create a standard user account, harden SSH access and remove unnecessary network services.

      Note

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

      Overview of the SaltStack Time Zone Formula

      In this section, we will take a closer look at SaltStack’s timezone-formula, which can be used to configure a minion’s time zone. A high-level overview of all the formula’s state files and Jinja templates will be provided. Salt best practices recommends that formulas should separate the data that a state needs from the state itself to increase the flexibility and reusability of state files. We will observe how this is achieved in the time zone formula.

      1. In your browser, navigate to the timezone-formula on SaltStack’s GitHub page. The README file is displayed and contains basic information about the formula. It notes the following details:

        • The purpose of the formula: to configure the time zone.
        • The available states: timezone
        • The provided default values: timezone: 'Europe/Berlin' utc: True

        The repository’s FORMULA file includes additional details, including the supported OS families (Debian, RedHat, SUSE, Arch, FreeBSD), a summary, description and release number.

      2. Viewing the timezone-formula, click on the timezone directory to view its contents. You should see the following files:

        View the time zone formula files

      3. Take a look at the contents of the init.sls file that defines the timezone state:

        timezone/init.sls
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        
        # This state configures the timezone.
        
        {%- set timezone = salt['pillar.get']('timezone:name', 'Europe/Berlin') %}
        {%- set utc = salt['pillar.get']('timezone:utc', True) %}
        {% from "timezone/map.jinja" import confmap with context %}
        
        timezone_setting:
          timezone.system:
            - name: {{ timezone }}
            - utc: {{ utc }}
        
        timezone_packages:
          pkg.installed:
            - name: {{ confmap.pkgname }}
        
        timezone_symlink:
          file.symlink:
            - name: {{ confmap.path_localtime }}
            - target: {{ confmap.path_zoneinfo }}{{ timezone }}
            - force: true
            - require:
              - pkg: {{ confmap.pkgname }}
            

        Salt will interpret the name of this file as timezone, since any init.sls file in a subdirectory is referred to by the path of the directory.

        This state file contains three state declarations, timezone_setting, timezone_packages and timezone_symlink. Below is a description of the configuration each declaration will accomplish on a Salt minion.

        • timezone.system: This state uses Salt’s timezone state module to manage the timezone for the minion. The values for name and utc are derived from the corresponding Salt master’s Pillar file. This is accomplished in the two variable assignment at the top of the file: {%- set timezone = salt['pillar.get']('timezone:name', 'Europe/Berlin') %} and {%- set utc = salt['pillar.get']('timezone:utc', True) %}.

        • timezone_packages: This state ensures that the package needed to configure time zones is installed on the minion. This value is derived from the confmap variable that is imported from the map.jinja file. The import is declared at the top of the file with the {% from "timezone/map.jinja" import confmap with context %} import statement. Later in this section, you will inspect the map.jinja file.

        • timezone_symlink: This state creates a symbolic link from the path defined in name to the location defined in target. This state will only execute if the timezone_packages state is executed successfully. This requirement is denoted by the require statement.

      4. Next, inspect the map.jinja file:

        timezone/map.jinja
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        16
        
        {% import_yaml "timezone/defaults.yaml" as defaults %}
        {% import_yaml "timezone/osfamilymap.yaml" as osfamilymap %}
        
        {% set osfam = salt['grains.filter_by'](
                                                osfamilymap,
                                                grain='os_family'
                                                ) or {} %}
        
        {% do salt['defaults.merge'](defaults, osfam) %}
        
        {%- set confmap = salt['pillar.get'](
                                        'timezone:lookup',
                                        default=defaults,
                                        merge=True,
                                        ) %}
              

        The map.jinja file allows the formula to abstract static defaults into a dictionary that contains platform specific data. The two main dictionaries are defined in the repository’s timezone/defaults.yaml and timezone/osfamilymap.yaml files. The defaults.yml file serves as a base dictionary containing values shared by all OSes, while the osfamilymap.yml file stores any values that are different from the base values. Any file throughout the formula could make use of these dictionary values by importing the map.jinja file. In addition, any dictionary values can be overridden in a Pillar file. Overidding dictionary values will be discussed in the Modify Your SaltStack Formula section.

      5. Open the timezone/defaults.yaml file and the timezone/osfamilymap,yaml file to view the data stored in those files:

        timezone/defaults.yaml
        1
        2
        3
        4
        
            path_localtime: /etc/localtime
            path_zoneinfo: /usr/share/zoneinfo/
            pkgname: tzdata
              
        timezone/osfamilymap.yaml
        1
        2
        3
        4
        5
        6
        7
        
            Suse:
              pkgname: timezone
            FreeBSD:
              pkgname: zoneinfo
            Gentoo:
              pkgname: sys-libs/timezone-data
              

        The values defined in these YAML files are used in the init.sls file.

      6. Open the pillar.example file to review its contents:

        pillar.example
        1
        2
        3
        4
        
          timezone:
            name: 'Europe/Berlin'
            utc: True
              

        This file provides an example for you to use when creating your own Pillar file on the Salt master. The init.sls file uses the values for name and utc in its timezone_setting state declaration. The value for name will set the time zone for your minion. The boolean value for utc determines whether or not to set the minion’s hardware clock to UTC.

        Refer to tz database time zones to view a list of all available time zones. Since Pillar files contain sensitive data, you should not version control this file. In the Create the Pillar section, you will create a Pillar file directly on your Salt master.

        Now that you understand the structure of the SaltStack time zone formula, in the next section you will fork the formula’s repository on GitHub and clone the forked formula to your local computer.

      Fork and Clone the SaltStack TimeZone Formula

      In this section you will fork the timezone-formula from the official SaltStack GitHub page to your GitHub account and clone it to a local repository.

      1. In your browser, navigate to the timezone-formula on SaltStack’s GitHub page. If you have not yet logged into your GitHub account, click on the Sign in link at the top of the page and log in.

      2. Fork the timezone-formula from the SaltStack formula’s GitHub page:

        Fork SaltStack timezone formula

        Once the formula has been forked, you will be redirected to your GitHub account’s own fork of the timezone formula.

      3. Viewing your fork of the timezone formula, click on the Clone or download button and copy the URL:

        Fork SaltStack timezone formula

      4. On your local computer, clone the timezone formula:

        git clone https://github.com/my-github/timezone-formula.git
        
      5. Move into the timezone-formula directory:

        cd timezone-formula
        
      6. Display the contents of the timezone-formula directory:

        ls
        

        You should see the following output:

          
              FORMULA        README.rst     pillar.example timezone
              
        
      7. When you clone a repository, Git will automatically set the origin remote to the location of the forked repository. Verify the configured remotes for your timezone-formula repository:

        git remote -v
        

        Your output should be similar to what is displayed below, however, it will point to your own fork of the timezone-formula repository:

          
          origin	https://github.com/my-github/timezone-formula.git (fetch)
          origin	https://github.com/my-github/timezone-formula.git (push)
              
        

        You can add the official SaltStack timezone formula as the upstream remote, so you can easily pull any changes made to the formula by the repository’s maintainers or contribute back to the project. This step is not required.

        git remote add upstream https://github.com/saltstack-formulas/timezone-formula
        

        You now have a local copy of your forked timezone-formula. In the next section, you will modify the formula to update the init.sls file.

      Modify Your SaltStack Formula

      In this section, you will modify the time zone formula to improve how the formula follows Salt best practices related to lookup dictionaries. You can similarly modify any SaltStack formula for your infrastructure’s specific requirements, if needed.

      As discussed in the Overview of the SaltStack Time Zone Formula section, the timezone/defaults.yaml file and the timezone/osfamily.map file provide dictionaries of values that are used by the init.sls state. These YAML file dictionary values can be overridden in a Pillar file that also stores any sensitive data needed by the init.sls state.

      When structuring Pillar data, Salt’s official documentation states that it is a best practice to make formulas expect all formula-related parameters to be placed under a second-level lookup key. Currently, the init.sls file’s timezone and utc variables expect the Pillar data to be structured differently. You will update these two variable statements to expect a second-level lookup key.

      1. Create a new branch in your local repository to begin modifying the timezone-formula:

        git checkout -b update-variable-statements
        
      2. Open the init.sls file in a text editor and modify its timezone and utc variable statements to match the example file:

        timezone/init.sls
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        
        # This state configures the timezone.
        
        {%- set timezone = salt['pillar.get']('timezone:lookup:name', 'Europe/Berlin') %}
        {%- set utc = salt['pillar.get']('timezone:lookup:utc', True) %}
        {% from "timezone/map.jinja" import confmap with context %}
        
        timezone_setting:
          timezone.system:
            - name: {{ timezone }}
            - utc: {{ utc }}
        
        timezone_packages:
          pkg.installed:
            - name: {{ confmap.pkgname }}
        
        timezone_symlink:
          file.symlink:
            - name: {{ confmap.path_localtime }}
            - target: {{ confmap.path_zoneinfo }}{{ timezone }}
            - force: true
            - require:
              - pkg: {{ confmap.pkgname }}
              

        The init.sls file now expects a second-level lookup key when retrieving the specified Pillar values. Following this convention will make it easier to override dictionary values in your Pillar file. You will create a Pillar file in the Installing a Salt Formula section of this guide.

      3. Use Git to view which files have been changed before staging them:

        git status
        

        Your output should resemble the following:

          
        On branch update-variable-statements
        Changes not staged for commit:
          &nbsp&nbsp(use "git add &ltfile&gt..." to update what will be committed)
          &nbsp&nbsp(use "git checkout -- &ltfile&gt..." to discard changes in working directory)
        
          &nbsp&nbspmodified:   timezone/init.sls
        
        no changes added to commit (use "git add" and/or "git commit -a")
            
        
      4. Stage and commit the changes you made to the init.sls file.

        git add -A
        git commit -m 'My commit message'
        
      5. Push your changes to your fork:

        git push origin update-variable-statements
        
      6. Navigate to your timezone formula’s remote GitHub repository and create a pull request against your fork’s master branch.

        Submit a pull request

        Make sure you select your own fork of the time zone formula as the base fork, otherwise you will submit a pull request against the official SaltStack timezone formula’s repository, which is not the intended behavior for this example.

        Create a pull request

        If you are satisfied with the changes in the pull request, merge the pull request into your master branch.

        Merge a pull request

      In the next section, you will add your forked timezone-formula to your Salt master, create a Pillar file for the timezone-formula and apply the changes to your minions.

      Install a Salt Formula

      There are two ways to use a Salt Formula: you can add the formula as a GitFS Remote, which will allow you to directly serve the files hosted on your GitHub account, or you can add the formula directly to the Salt master using Git’s clone mechanism. This section will cover both ways to use Salt formulas.

      Manually Add a Salt Formula to your Master

      1. Navigate to your fork of the timezone-formula, click on the Clone or download button and copy the repository’s URL to your clipboard.

      2. SSH into your Salt master. Replace the username with your limited user account and replace 198.51.100.0 with your Linode’s IP address:

        ssh username@198.51.100.0
        
      3. Create a formulas directory and go to the new directory:

        mkdir -p /srv/formulas
        cd /srv/formulas
        
      4. If your Salt master does not already have Git installed, install Git using your system’s package manager:

        Ubuntu/Debian

        apt-get update
        apt-get install git
        

        Centos

        yum update
        yum install git
        
      5. Clone the repository into the /srv/formulas directory. Make sure you replace git-username with your own username:

        git clone https://github.com/git-username/timezone-formula.git
        

      Add a Salt Formula as a GitFS Remote

      GitFs allows Salt to serve files directly from remote git repositories. This is a convenient way to use Salt formulas with the added flexibility and power that remote version control systems provide, like collaboration and easy rollback to previous versions of your formulas.

      1. On the Salt master, install the Python interface to Git:

        sudo apt-get install python-git
        
      2. Edit the Salt master configuration file to use GitFs as a fileserver backend. Make sure the lines listed below are uncommented in your master configuration file:

        /etc/salt/master
        1
        2
        3
        
        fileserver_backend:
          - gitfs
          - roots

        When using multiple backends, you should list all backends in the order you want them to be searched. roots is the fileserver backend used to serve files from any of the master’s directories listed in the file_roots configuration.

      3. In the same Salt master configuration file, add the location of your timezone formula’s GitHub repository. Ensure you have uncommented gitfs_remote:

        /etc/salt/master
        1
        2
        
        gitfs_remotes:
          - https://github.com/git-username/timezone-formula.git
      4. Uncomment the gitfs_provider declaration and set its value to gitpython:

        /etc/salt/master
        1
        
        gitfs_provider: gitpython
      5. Restart the Salt master to apply the new configurations:

        sudo systemctl restart salt-master
        

      Add a Salt Formula to the Top File

      To include your timezone formula in your Salt state tree, you must add it to your top file.

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

        mkdir /srv/salt
        
      2. Add the timezone state declared in the timezone-formula to your top file:

        /srv/salt/top.sls
        1
        2
        3
        4
        
        base:
          '*':
            - timezone
            

        The example Top file declares one environment, the base environment that targets all minions and applies the timezone state to them. This top file could easily contain several states that already exist in your state tree, like an apache state, a wordpress state, etc., and several environments that target different minions. Any Salt formula can be easily dropped-in to the top file and will be applied to the targeted minions the next time you run a highstate.

      Create the Pillar

      1. Create a directory to store your formula’s Pillar file:

        mkdir -p /srv/pillar
        
      2. Create a Pillar file to store the data that will be used by your timezone formula:

        /srv/pillar/timezone.sls
        1
        2
        3
        4
        5
        6
        7
        8
        9
        
        timezone:
          lookup:
            {%- if grains['os_family'] == 'Debian' %}
            name: America/New_York
            {%- else %}
            name: 'Europe/Berlin'
            {%- endif %}
            utc: True
            

        The timezone.sls Pillar file was created from the pillar.example file provided in the SaltStack timezone formula. The example was modified to add Jinja control statements that will assign a different timezone on any minion that is a Debian family OS. You can replace any of the timezone name values to your preferred timezone or add additional Jinja logic, if necessary. For an introduction to Jinja, read the Introduction to Jinja Templates for Salt.

        You can also override any of the dictionary values defined in the timezone/defaults.yaml or timezone/osfamilymap.yaml in the Pillar file using Salt’s lookup dictionary convention. For example, if you wanted to override the pkgname value defined in timezone/defaults.yaml your Pillar file might look like the following example:

        /srv/pillar/timezone.sls
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        
        timezone:
          lookup:
            {%- if grains['os_family'] == 'Debian' %}
            name: America/New_York
            {%- else %}
            name: 'Europe/Berlin'
            {%- endif %}
            utc: True
            pkgname: timezone
            
      3. If you cloned the timezone-formula to your master instead of adding the formula as a GitFS remote, add the timezone-formula’s directory to the Salt master’s file_roots configuration:

        /etc/salt/master
        1
        2
        3
        4
        5
        
        file_roots:
          base:
            - /srv/salt/
            - /srv/formulas/timezone-formula
            
      4. Add the Pillar to the Pillar’s top file:

        /srv/pillar/top.sls
        1
        2
        3
        4
        
        base:
          '*':
            - timezone
            
      5. Configure the location of the Pillar file:

        /etc/salt/master
        1
        2
        3
        4
        
        pillar_roots:
          base:
            - /srv/pillar
            
      6. Restart the Salt master for the new configurations to take effect on the Salt master:

        sudo systemctl restart salt-master
        
      7. Run a highstate to your minion to apply the state defined in the timezone formula:

        sudo salt '*' state.apply
        

      Next Steps

      To learn how to create your own Salt formulas and how to organize your formula’s states in a logical and modular way, read our Automate Static Site Deployments with Salt, Git, and Webhooks guide.

      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.

      Find answers, ask questions, and help others.

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



      Source link

      Install Plex Media Server on Ubuntu 18.04 Using Salt Masterless


      Updated by Linode Contributed by Linode

      Plex is a media server that allows you to stream video and audio content that you own to many different types of devices. In this guide you will learn how to use a masterless Salt minion to set up a Plex server, attach and use a Block Storage Volume, and how to connect to your media server to stream content to your devices.

      Before You Begin

      1. Familiarize yourself with our Getting Started guide and complete the steps for setting your Linode’s hostname and timezone.

      2. Follow the steps in the How to Secure Your Server guide.

      3. Update your system:

        sudo apt-get update && sudo apt-get upgrade
        
      4. You will need to create a Block Storage Volume and attach it to your Linode. You will format and mount the drive as part of this guide. This volume will be used to store your media, so you should pick a size that’s appropriate for your media collection, though you can resize the volume later if you need more storage. For more on Block Storage, see our How to Use Block Storage guide.

      5. Plex requires an account to use their service. Visit the Plex website to sign up for an account if you do not already have one.

      Note

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

      Prepare the Salt Minion

      1. On your Linode, create the /srv/salt and /srv/pillar directories. These are where the Salt state files and Pillar files will be housed.

        mkdir /srv/salt && mkdir /srv/pillar
        
      2. Install salt-minion via the Salt bootstrap script:

        curl -L https://bootstrap.saltstack.com -o bootstrap_salt.sh
        sudo sh bootstrap_salt.sh
        
      3. The Salt minion will use the official Plex Salt Formula, which is hosted on the SaltStack GitHub repository. In order to use a Salt formula hosted on an external repository, you will need GitPython installed. Install GitPython:

        sudo apt-get install python-git
        

      Modify the Salt Minion Configuration

      1. Because the Salt minion is running in masterless mode, you will need to modify the minion configuration file (/etc/salt/minion) to instruct Salt to look for state files locally. Open the minion configuration file in a text editor, uncomment the line #file_client: remote, and set it to local:

        /etc/salt/minion
        1
        2
        3
        4
        5
        6
        7
        8
        9
        
        ...
        
        # Set the file client. The client defaults to looking on the master server for
        # files, but can be directed to look at the local file directory setting
        # defined below by setting it to "local". Setting a local file_client runs the
        # minion in masterless mode.
        file_client: local
        
        ...
      2. There are some configuration values that do not normally exist in /etc/salt/minion which you will need to add in order to run your minion in masterless mode. Copy the following lines into the end of /etc/salt/minion:

        /etc/salt/minion
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        
        ...
        
        fileserver_backend:
          - roots
          - gitfs
        
        gitfs_remotes:
          - https://github.com/saltstack-formulas/plex-formula.git
        
        gitfs_provider: gitpython

        The fileserver_backend block instructs the Salt minion to look for Salt configuration files in two places. First, it tells Salt to look for Salt state files in our minion’s roots backend (/srv/salt). Secondly, it instructs Salt to use the Git Fileserver (gitfs) to look for Salt configuration files in any Git remote repositories that have been named in the gitfs_remotes section. The address for the Plex Salt formula’s Git repository is included in the gitfs_remotes section.

        Note

        It is best practice to create a fork of the Plex formula’s Git repository on GitHub and to add your fork’s Git repository address in the gitfs_remotes section. This will ensure that any further changes to the upstream Plex formula which might break your current configuration can be reviewed and handled accordingly, before applying them.

        Lastly, GitPython is specified as the gitfs_provider.

      Create the Salt State Tree

      1. Create a Salt state top file at /srv/salt/top.sls and copy in the following configuration. This file tells Salt to look for state files in the plex folder of the Plex formula’s Git repository, and for a state files named disk.sls and directory.sls, which you will create in the next steps.

        /srv/salt/top.sls
        1
        2
        3
        4
        5
        
        base:
          '*':
            - plex
            - disk
            - directory
      2. Create the disk.sls file in /srv/salt:

        /srv/salt/disk.sls
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        
        disk.format:
          module.run:
            - device: /dev/disk/by-id/scsi-0Linode_Volume_{{ pillar['volume_name'] }}
            - fs_type: ext4
        
        /mnt/plex:
          mount.mounted:
            - device: /dev/disk/by-id/scsi-0Linode_Volume_{{ pillar['volume_name'] }}
            - fstype: ext4
            - mkmnt: True
            - persist: True

        This file instructs Salt to prepare your Block Storage Volume for use with Plex. It first formats your Block Storage Volume with the ext4 filesystem type by using the disk.format Salt module, which can be run in a state file using module.run. Then disk.sls instructs Salt to mount your volume at /mnt/plex, creating the mount target if it does not already exist with mkmnt, and persisting the mount to /etc/fstab so that the volume is always mounted at boot.

      3. Create the directory.sls file in /srv/salt:

        /srv/salt/directory.sls
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        
        /mnt/plex/plex-media:
          file.directory:
            - require:
              - mount: /mnt/plex
            - user: username
            - group: plex
        
        /mnt/plex/plex-media/movies:
          file.directory:
            - require:
              - mount: /mnt/plex
            - user: username
            - group: plex
        
        /mnt/plex/plex-media/television:
          file.directory:
            - require:
              - mount: /mnt/plex
            - user: username
            - group: plex

        The directories that are created during this step are for organizational purposes, and will house your media. Make sure you replace username with the name of the limited user account you created when following the How to Secure Your Server guide. The location of the directories is the volume you mounted in the previous step. If you wish to add more directories, perhaps one for your music media, you can do so here, just be sure to include the - require block, as this prevents Salt from trying to create the directory before the Block Storage Volume has been mounted.

      4. Go to the Plex Media Server download page and note the most recent version of their Linux distribution. At the time of writing, the most recent version is 1.13.9.5456-ecd600442. Create the plex.sls Pillar file in /srv/pillar and change the Plex version number and the name of your Block Storage Volume as necessary:

        /srv/pillar/plex.sls
        1
        2
        3
        
        plex:
          version: 1.13.9.5456-ecd600442
        volume_name: plex
      5. Create the Salt Pillar top file in /srv/pillar. This file will instruct Salt to look for the plex.sls Pillar file you created in the previous step.

        /srv/pillar/top.sls
      6. Apply your Salt state locally using salt-call:

        salt-call --local state.apply
        

        You should see a list of the changes Salt applied to your system. You have successfully installed Plex using Salt.

      Set Up Plex

      Initial Configuration

      1. You’ll need to create an SSH tunnel to your Linode to connect to Plex’s web UI. On your local computer, run the following command, replacing <your_ip_address> with your Plex server’s IP address.:

        ssh username@<your_ip_address> -L 8888:localhost:32400
        
      2. In a browser, navigate to http://localhost:8888/web/.

      3. Sign in with your Plex username and password.

      4. Name your media server. This example uses the name linode-plex. Be sure to check the box that reads Allow me to access my media outside my home and then click Next.

        Name your media server

      Organize Your Media

      1. Click on the Add Library button:

        Click on Add Media

      2. Select Movies and click Next:

        Select Movies and click next

      3. Click Browse for Media Folder and select the appropriate folder at /mnt/plex/plex-media/movies. Then click Add:

        Select the appropriate folder

      4. Repeat the process to add your ‘Television’ folder.

      5. When you are done adding your libraries, click Add Library.

      6. To continue the configuration process, click Next.

      7. Click on Get Plex Apps to download the appropriate Plex client for your device. Then click Done.

        Download the appropriate client for your device

      8. In the future you can add more libraries by hovering over the menu and clicking the plus sign (+) next to LIBRARIES.

        Add more libraries

      DLNA is a protocol that incorporates Universal Plug and Play (or UPnP) standards for digital media sharing across devices. If you do not wish to make use of it, it’s recommended that you disable this feature, as it is openly connectable on port 1900. From the Plex web interface, click the wrench icon in the upper right corner, and navigate to the DLNA section under SETTINGS. Uncheck Enable the DLNA server, and click Save Changes:

      Disable DLNA

      Connect to Your Plex Server

      1. Visit the Plex Apps download page or the app store on your device to download Plex Media Player if you have not already done so.

      2. Open your Plex app. The example provided here will use the Plex Media Player for macOS.

      3. Sign in to Plex.

      4. On the left there’s a dropdown menu where you can select your server by the name you chose. Select your server.

        Connect to your Plex Server

      5. You are now able to stream your content with Plex.

        Plex's macOS App

      1. You can use SCP to transfer media to your server from your local computer. Replace your username and 123.456.7.8 with the IP address of your Linode.

        scp example_video.mp4 username@123.456.7.8:/mnt/plex/plex-media/movies
        
      2. Once you’ve transferred files to your Plex media server, you may need to scan for new files before they show up in your Library. Click on the ellipsis next to a Library and select Scan Library Files.

        Scan your Library for new files

      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.

      Find answers, ask questions, and help others.

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



      Source link