# IaRC ## Infrastructure as Ruby Code --- # Outline - Infrastructure as code - Chef / CINC - Practical example - Q & A --- # About me Jochen Lillich monospacementor.com twitch.tv/fullstacklive floss.social/@monospacementor Note: - Immigrant --- ## Infrastructure as code Note: - Central - VCS --- # Chef / CINC - Chef Software (formerly Opscode) - April 2019: introduction of commercial license - 2020: acquired by Progress - OSS fork: CINC -- ## CINC components - CINC server - CINC client - test-kitchen - CINC Auditor - CINC Workstation -- ## Architecture ![](cinc-architecture.png) -- ## Cookbooks - Recipes - Files - Templates - Custom resources - Tests -- ## Data Node-specific: - Attributes - Roles - Policies Node-independent: - Data Bags -- ## Built-in resources - package - file - service - template - execute - bash / ruby - cron - etc. --- ## A simple example Set up backup with Borgmatic -- ## Install a package `borgmatic/recipes/default.rb` ```ruby package "borgmatic" do action :install end ``` -- ## Create a config file `borgmatic/recipes/default.rb` ```ruby template "/etc/borgmatic/config.yaml" do source "config.yaml.erb" owner "root" group "root" mode 0o660 variables( config: node["borgmatic"]["config"] ) end ``` -- ## Node attributes ```json "borgmatic": { "config": { "source_directories": [ "/home/monospace", "/etc" ], ... } } ``` -- ## Template files `borgmatic/templates/default/config.yaml.erb` ```yaml source_directories: <% @config["source_directories"].each do |dir| %> - <%= dir %> <% end %> ... ``` -- ## Multiple configs ```json "borgmatic": { "configs": { "config1": { "source_directories": [ "/etc" ], }, "config2": { "source_directories": [ "/home/monospace" ] } } } ``` -- ## Multiple configs ```ruby node["borgmatic"]["configs"].each_pair do |name, config| template "/etc/borgmatic/#{name}.yaml" do source "config.yaml.erb" ... variables( config: config ) end end ``` -- ## Define a cron job `borgmatic/recipes/default.rb` ```ruby cron "borgmatic" do command "borgmatic -c /etc/borgmatic/config.yaml" hour node["borgmatic"]["cron_hour"] minute node["borgmatic"]["cron_minute"] user "root" end ``` -- ## Default attributes `borgmatic/attributes/default.rb` ```ruby default["borgmatic"]["cron_hour"] = "03" default["borgmatic"]["cron_minute"] = "00" default["borgmatic"]["config"] = { ... } ``` -- ## Roles ```json "default_attributes": { "borgmatic": { "cron_hour": "02" "cron_minute": "00", "config": { ... } } }, "run_list": "recipe[borgmatic::default]" } ``` -- # Testing Note: - test-kitchen - VM or Docker container - Converge - Verify with CINC Auditor (inspired by ServerSpec) - Can audit live servers, too -- `borgmatic/test/integration/default/borg_spec.rb` ```ruby describe package("borgmatic") do it { should be_installed } end ``` -- ```ruby config = "/etc/borgmatic/config.yaml" describe file(config) do its("body") { should include "..." } end ``` -- ```ruby describe crontab do its("commands") do should include "borgmatic -c #{config}" end end ``` --- # Where to go from here - Application cookbooks - Custom resources --- # Thank you!