Infrastructure as code using AWS CloudFormation and Chef : Chef

Install Chef

solo.rb

				
					cookbook_path [
      '/var/chef/cookbooks'
    ]
    environment 'example'
    environment_path '/var/chef/environments'
    file_backup_path '/var/chef/backup'
    file_cache_path '/var/chef/cache'
				
			

Roles

				
					{
      "name": "base_node_mongo_nginx",
      "description": "This role sets up web server with node and mysql",
      "chef_type": "role",
      "MONGO":{
        "URL":"127.0.0.1",
        "PORT":"27017",
        "DBNAME":"testdb_staging"
      },
      "run_list": [
        "recipe[init_config]",
        "recipe[install_node]", //install nodejs and npm rpm
        "recipe[install_mongo]", //install mongo rpm
        "recipe[install_nginx]", //install nginx and copy right config
      ]
    }
				
			
				
					 "run_list": [
      "role[base_node_mongo_nginx]",
      "recipe[install_app]" //install application, run npm install, and start server
    ]
				
			

Cookbooks & Recipes

Chef recipes are ruby files that are a component of cookbooks. There are a lot of details to Cookbooks, but to keep things simple we will discuss writing simple recipes with some resources. A much more detailed documentation can be found here:

template vs cookbook_file

Initially, when you are setting up your chef recipe you might end up just using cookbook_file which simply copies the file over to a location, but as you start parameterizing contents of the file with variables you will need to replace cookbook_file with template. For example, you might want 2 nginx configurations on different virtual hosts. A very common use case. Here, instead of having separate file, you can make one config and customize the contents with variables.

role:
				
					 {
      "name": "staging",
      "description": "This role sets up nginx config",
      "chef_type": "role",
      "ENV":"staging",
      "SERVER":{
        "DOCUMENT_ROOT":"/var/www/public",
        "SERVER_NAME":"vhost.domain.com"
      },
      "run_list": [
        "recipe[install_nginx]"
      ]
    }
    
				
			

recipe – install_nginx:

				
					template "/etc/nginx/conf.d/nginx.#{node['ENV']}.conf" do
      source "nginx.template.conf"
      mode 0755
      variables({
        :DOCUMENT_ROOT => node['SERVER']['DOCUMENT_ROOT'],
        :SERVER_NAME => node['SERVER']['SERVER_NAME'],
      })
      notifies :restart, 'service[nginx]', :immediately
    end
				
			

nginx.template.conf:

				
					server {
    
      listen 80;
      listen [::]:80;
    
      server_name <%= @SERVER_NAME %>;
    
      location / {
        root <%= @DOCUMENT_ROOT %>;
      }
    }
    
				
			

This is a template resource that does the following:

    1. takes nginx.template.conf
    2. replaces variables DOCUMENT_ROOT, SERVER_NAME and SERVER_PORT
    3. creates the file to /etc/nginx/conf.d/nginx.staging.conf
    4. sets the mode to 755
    5. restarts service nginx immediately after doing all the above.

Folder set up

Here is a sample folder set up, keeps the recipe and files/templates associated with it together
				
					chef-solo
    --cookbooks -> folder that contains all the recip[e folders
    --↳---install_nginx -> folder that contains all the files for a recipe
    -------↳--recipes -> folder for recipe
    ----------↳--default.rb -> the recipe with resource blocks
    -------↳--templates -> folder that contains all templates
    ----------↳--nginx.template.conf -> template
    -------↳--metadata.rb -> name and description
				
			

Executing Chef

Using chef-solo, you can pass in the solo.rb and the role json to execute it.

Official chef documentation:

POWER UP YOUR BUSINESS WITH AWS DEVELOPMENT SERVICES

Facebook
Twitter
LinkedIn

Parikshit Agnihotry

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *