sous-chefs / redisio

Development repository for the redisio cookbook
https://supermarket.chef.io/cookbooks/redisio
Apache License 2.0
297 stars 300 forks source link
chef chef-cookbook chef-resource hacktoberfest managed-by-terraform redisio

Redisio Cookbook

Cookbook Version Build Status OpenCollective OpenCollective License

Please read the changelog when upgrading from the 1.x series to the 2.x series

Description

Website:: https://github.com/sous-chefs/redisio

Installs and configures Redis server instances

Maintainers

This cookbook is maintained by the Sous Chefs. The Sous Chefs are a community of Chef cookbook maintainers working together to maintain important cookbooks. If you’d like to know more please visit sous-chefs.org or come chat with us on the Chef Community Slack in #sous-chefs.

Requirements

This cookbook builds redis from source or install it from packages, so it should work on any architecture for the supported distributions. Init scripts are installed into /etc/init.d/

It depends on the ulimit cookbook: https://github.com/bmhatfield/chef-ulimit and the build-essentials cookbook: https://github.com/chef-cookbooks/build-essential

Platforms

Testing

This cookbook is tested with Delivery's local mode run under Chef-DK and Test Kitchen

Tested on:

Usage

The redisio cookbook contains LWRP for installing, configuring and managing redis and redis_sentinel.

The install recipe can build, compile and install redis from sources or install from packages. The configure recipe will configure redis and set up service resources. These resources will be named for the port of the redis server, unless a "name" attribute was specified. Example names would be: service["redis6379"] or service["redismaster"] if the name attribute was "master". NOTE: currently installation from source is not supported for FreeBSD

The most common use case for the redisio cookbook is to use the default recipe, followed by the enable recipe.

Another common use case is to use the default, and then call the service resources created by it from another cookbook.

It is important to note that changing the configuration options of redis does not make them take effect on the next chef run. Due to how redis works, you cannot reload a configuration without restarting the redis service. Redis does not offer a reload option, in order to have new options be used redis must be stopped and started.

You should make sure to set the ulimit for the user you want to run redis as to be higher than the max connections you allow. NOTE: setting ulimit is not supported on FreeBSD since the ulimit cookbook doesn't support FreeBSD

The disable recipe just stops redis and removes it from run levels.

The cookbook also contains a recipe to allow for the installation of the redis ruby gem.

Redis-sentinel will write configuration and state data back into its configuration file. This creates obvious problems when that config is managed by chef. By default, this cookbook will create the config file once, and then leave a breadcrumb that will guard against the file from being updated again.

Recipes

Role File Examples

Install redis and set up an instance with default settings on default port, and start the service through a role file

run_list *%w[
  recipe[redisio]
  recipe[redisio::enable]
]

default_attributes({})
Install redis with packages and set up an instance with default settings on default port, and start the service through a role file
run_list *%w[
  recipe[redisio]
  recipe[redisio::enable]
]

default_attributes({
  'redisio' => {
    package_install: true
    version:
  }
})
Install redis, give the instance a name, and use a unix socket
run_list *%w[
  recipe[redisio]
  recipe[redisio::enable]
]

default_attributes({
  'redisio' => {
    'servers' => [
      {'name' => 'master', 'port' => '6379', 'unixsocket' => '/tmp/redis.sock', 'unixsocketperm' => '755'},
    ]
  }
})
Install redis and pull the password from an encrypted data bag
run_list *%w[
  recipe[redisio]
  recipe[redisio::enable]
]

default_attributes({
  'redisio' => {
    'servers' => [
      {'data_bag_name' => 'redis', 'data_bag_item' => 'auth', 'data_bag_key' => 'password'},
    ]
  }
})
Data Bag
{
    "id": "auth",
    "password": "abcdefghijklmnopqrstuvwxyz"
}
Install redis and set up two instances on the same server, on different ports, with one slaved to the other through a role file
run_list *%w[
  recipe[redisio]
  recipe[redisio::enable]
]

default_attributes({
  'redisio' => {
    'servers' => [
      {'port' => '6379'},
      {'port' => '6380', 'replicaof' => { 'address' => '127.0.0.1', 'port' => '6379' }}
    ]
  }
})
Install redis and set up two instances, on the same server, on different ports, with the default data directory changed to /mnt/redis, and the second instance named
run_list *%w[
  recipe[redisio]
  recipe[redisio::enable]
]

default_attributes({
  'redisio' => {
    'default_settings' => {'datadir' => '/mnt/redis'},
    'servers' => [{'port' => '6379'}, {'port' => '6380', 'name' => "MyInstance"}]
  }
})
Install redis and set up three instances on the same server, changing the default data directory to /mnt/redis, each instance will use a different backup type, and one instance will use a different data dir
run_list *%w[
  recipe[redisio]
  recipe[redisio::enable]
]

default_attributes({
  'redisio' => {
    'default_settings' => { 'datadir' => '/mnt/redis/'},
    'servers' => [
      {'port' => '6379','backuptype' => 'aof'},
      {'port' => '6380','backuptype' => 'both'},
      {'port' => '6381','backuptype' => 'rdb', 'datadir' => '/mnt/redis6381'}
    ]
  }
})
Install redis 2.4.11 (lower than the default version) and turn safe install off, for the event where redis is already installed This will use the default settings. Keep in mind the redis version will not actually be updated until you restart the service (either through the LWRP or manually)
run_list *%w[
  recipe[redisio]
  recipe[redisio::enable]
]

default_attributes({
  'redisio' => {
    'safe_install' => false,
    'version'      => '2.4.11'
  }
})
Install a single redis-sentinel to listen for a master on localhost and default port number
run_list *%w[
  recipe[redisio::sentinel]
  recipe[redisio::sentinel_enable]
]

Install redis and set up two instances, on the same server, on different ports, the second instance configuration file will be overwriten by chef

run_list *%w[
  recipe[redisio]
  recipe[redisio::enable]
]

default_attributes({
  'redisio' => {
    'servers' => [{'port' => '6379'}, {'port' => '6380', 'breadcrumb' => false}]
  }
})

LWRP Examples

Instead of using my provided recipes, you can simply depend on the redisio cookbook in your metadata and use the LWRP's yourself. I will show a few examples of ways to use the LWRPS, detailed breakdown of options are below in the resources/providers section

Install Resource

It is important to note that this call has certain expectations for example, it expects the redis package to be in the format `redis-VERSION.tar.gz'.

redisio_install "redis-installation" do
  version '2.6.9'
  download_url 'http://redis.googlecode.com/files/redis-2.6.9.tar.gz'
  safe_install false
  install_dir '/usr/local/'
end

Configure Resource

The servers resource expects an array of hashes where each hash is required to contain at a key-value pair of 'port' => 'port numbers'.

redisio_configure "redis-servers" do
  version '2.6.9'
  default_settings node['redisio']['default_settings']
  servers node['redisio']['servers']
  base_piddir node['redisio']['base_piddir']
end

Sentinel Resource

The sentinel resource installs and configures all of your redis_sentinels defined in sentinel_instances

Using the sentinel resources:

redisio_sentinel "redis-sentinels" do
  version '2.6.9'
  sentinel_defaults node['redisio']['sentinel_defaults']
  sentinels sentinel_instances
  base_piddir node['redisio']['base_piddir']
end

Attributes

Configuration options, each option corresponds to the same-named configuration option in the redis configuration file; default values listed

Default settings is a hash of default settings to be applied to to ALL instances. These can be overridden for each individual server in the servers attribute. If you are going to set logfile to a specific file, make sure to set syslog-enabled to no.

Available options and their defaults

'user'                    => 'redis' - the user to own the redis datadir, redis will also run under this user
'group'                   => 'redis' - the group to own the redis datadir
'permissions'             => '0644' - the unix permissions applied to the server config file
'homedir'                 => Home directory of the user. Varies on distribution, check attributes file
'shell'                   => Users shell. Varies on distribution, check attributes file
'systemuser'              => true - Sets up the instances user as a system user
'ulimit'                  => 0 - 0 is a special value causing the ulimit to be maxconnections +32.  Set to nil or false to disable setting ulimits
'configdir'               => '/etc/redis' - configuration directory
'name'                    => nil, Allows you to name the server with something other than port.  Useful if you want to use unix sockets
'tcpbacklog'              => '511',
'address'                 => nil, Can accept a single string or an array. When using an array, the FIRST value will be used by the init script for connecting to redis
'databases'               => '16',
'backuptype'              => 'rdb',
'datadir'                 => '/var/lib/redis',
'unixsocket'              => nil - The location of the unix socket to use,
'unixsocketperm'          => nil - The permissions of the unix socket,
'timeout'                 => '0',
'keepalive'               => '0',
'loglevel'                => 'notice',
'logfile'                 => nil,
'syslogenabled'           => 'yes',
'syslogfacility'          => 'local0',
'shutdown_save'           => false,
'save'                    => nil, # Defaults to ['900 1','300 10','60 10000'] inside of template.  Needed due to lack of hash subtraction
'stopwritesonbgsaveerror' => 'yes',
'rdbcompression'          => 'yes',
'rdbchecksum'             => 'yes',
'dbfilename'              => nil,
'replicaof'               => nil,
'masterauth'              => nil,
'replicaservestaledata'   => 'yes',
'replicareadonly'         => 'yes',
'repldisklesssync'        => 'no', # Requires redis 2.8.18+
'repldisklesssyncdelay'   => '5', # Requires redis 2.8.18+
'replpingreplicaperiod'   => '10',
'repltimeout'             => '60',
'repldisabletcpnodelay    => 'no',
'replicapriority'         => '100',
'requirepass'             => nil,
'rename_commands'         => nil, or a hash where each key is a redis command and the value is the command's new name.
'maxclients'              => 10000,
'maxmemory'               => nil,
'maxmemorypolicy'         => nil,
'maxmemorysamples'        => nil,
'appendfilename'          => nil,
'appendfsync'             => 'everysec',
'noappendfsynconrewrite'  => 'no',
'aofrewritepercentage'    => '100',
'aofrewriteminsize'       => '64mb',
'luatimelimit'            => '5000',
'slowloglogslowerthan'    => '10000',
'slowlogmaxlen'           => '1024',
'notifykeyspaceevents'    => '',
'hashmaxziplistentries'   => '512',
'hashmaxziplistvalue'     => '64',
'listmaxziplistentries'   => '512',
'listmaxziplistvalue'     => '64',
'setmaxintsetentries'     => '512',
'zsetmaxziplistentries'   => '128',
'zsetmaxziplistvalue'     => '64',
'hllsparsemaxbytes'       => '3000',
'activerehasing'          => 'yes',
'clientoutputbufferlimit' => [
  %w(normal 0 0 0),
  %w(replica 256mb 64mb 60),
  %w(pubsub 32mb 8mb 60)
],
'hz'                         => '10',
'aofrewriteincrementalfsync' => 'yes',
'clusterenabled'             => 'no',
'clusterconfigfile'          => nil, # Defaults to redis instance name inside of template if cluster is enabled.
'clusternodetimeout'         => 5000,
'clusterport'                => nil,
'includes'                   => nil,
'aclfile'                    => nil, # Requires redis 6+
'breadcrumb'                 => true # Defaults to create breadcrumb lock-file.
'tlsport'                    => nil,
'tlscertfile'                => nil,
'tlskeyfile'                 => nil,
'tlskeyfilepass'             => nil,
'tlsclientcertfile'          => nil,
'tlsclientkeyfile'           => nil,
'tlsclientkeyfilepass'       => nil,
'tlsdhparamsfile'            => nil,
'tlscacertfile'              => nil,
'tlscacertdir'               => nil,
'tlsauthclients'             => nil,
'tlsreplication'             => nil,
'tlscluster'                 => nil,
'tlsprotocols'               => nil,
'tlsciphers'                 => nil,
'tlsciphersuites'            => nil,
'tlspreferserverciphers'     => nil,
'tlssessioncaching'          => nil,
'tlssessioncachesize'        => nil,
'tlssessioncachetimeout'     => nil,

The redis_gem recipe will also allow you to install the redis ruby gem, these are attributes related to that, and are in the redis_gem attributes file.

The sentinel recipe's use their own attribute file.

'user'                    => 'redis',
'configdir'               => '/etc/redis',
'sentinel_bind'           => nil,
'sentinel_port'           => 26379,
'monitor'                 => nil,
'down-after-milliseconds' => 30000,
'can-failover'            => 'yes',
'parallel-syncs'          => 1,
'failover-timeout'        => 900000,
'loglevel'                => 'notice',
'logfile'                 => nil,
'syslogenabled'           => 'yes',
'syslogfacility'          => 'local0',
'quorum_count'            => 2,
'protected-mode'          => nil,
'maxclients'              => 10000,
'aclfile'                 => nil, # Requires redis 6+
'includes'                => nil,

You may also pass an array of masters to monitor like so:

[{
  'sentinel_port' => '26379',
  'name' => 'mycluster_sentinel',
  'masters' => [
    { 'master_name' => 'master6379', 'master_ip' => '127.0.0.1', 'master_port' => 6379 },
    { 'master_name' => 'master6380', 'master_ip' => '127.0.0.1', 'master_port' => 6380 }
  ]

}]

Resources/Providers

install

Actions:

Attribute Parameters

This resource expects the following naming conventions:

package file should be in the format base_nameVersion_number.artifact_type

package file after extraction should be inside of the directory base_nameVersion_number

install "redis" do
  action [:run,:nothing]
end

configure

Actions:

Attribute Parameters

configure "redis" do
  action [:run,:nothing]
end

Contributors

This project exists thanks to all the people who contribute.

Backers

Thank you to all our backers!

https://opencollective.com/sous-chefs#backers

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website.

https://opencollective.com/sous-chefs/sponsor/0/website https://opencollective.com/sous-chefs/sponsor/1/website https://opencollective.com/sous-chefs/sponsor/2/website https://opencollective.com/sous-chefs/sponsor/3/website https://opencollective.com/sous-chefs/sponsor/4/website https://opencollective.com/sous-chefs/sponsor/5/website https://opencollective.com/sous-chefs/sponsor/6/website https://opencollective.com/sous-chefs/sponsor/7/website https://opencollective.com/sous-chefs/sponsor/8/website https://opencollective.com/sous-chefs/sponsor/9/website