How do I share code across Chef cookbooks in a chef-repo? - ruby

I would like to share a small handful of methods across recipes in a chef repo. I know that on a cookbook level I can put code in modules in the libraries directory (see related question). What I'm looking for is something like that but available across all of the cookbooks in my Chef repo.
I can think of a couple solutions:
Create a gem, install the gem as part of the chef run. This seems like overkill.
Put the file in some folder and add that folder to the $LOAD_PATH in the recipe file. I have a feeling that won't work with actual deployment because the chef server doesn't know anything about the repo.
Put the file in some folder and symlink that into the libraries directory of each cookbook.
The last option seems like the most viable. Is there a better/more idiomatic way to do what I want?

You can use a library defined function from another cookbook but you must teach Chef that your cookbook depends on the providing cookbook.
So, for example, if in cookbook A, you have a libraries/default.rb that provides some function f, you can access it from cookbook B so long as B's metadata.rb file includes the line:
depends "A"
See the Chef documentation on metadata and libraries for more details.

There are 3 distinct options allowing for sharing code in form of either chef resource (1. LWRP, 2. HWRP) or methods (3. "libraries"). I'd suggest you consider LWRPs first. I find this answer very good in explaining differences between mentioned techniques.

Related

How to create golang modules for others?

Example Scenario
I have an AWS S3 bucket with lots of object which a couple of my application needs to access. The applications use some info available to them to form the S3 object name, get the object and run a transformation on the object data before using it for further processing specific to the application.
I would like to create a module which will hold the logic for forming the object name, obtain it from S3 and then run the transformation on the object data so that I wont be duplicating these functions in multiple places.
In this scenario should I add AWS SDK as a dependency in the module? Keep in mind that the applications might have to use AWS SDK for something else specific to that application or they might not require it at all.
In general what is the best way to solve problems like this i.e where to add the dependency? And how to manage different versions?
If your code has to access packages from the AWS SDK then yes, you have no choice but to add it as dependency. If it doesn't and the logic is generic, or you can abstract it away from the AWS SDK then you don't need the dependency (and in fact the go tooling like go mod tidy will remove the dependency from go.mod if you add it)
In this scenario should I add AWS SDK as a dependency in the module?
Keep in mind that the applications might have to use AWS SDK for
something else specific to that application or they might not require
it at all.
Yes, if any package from your module depends on AWS SDK, Go Modules system is going to add AWS SDK as a dependency for your module. There is nothing special you are supposed to do with your module.
Try this script with Go 1.11 or higher (and make sure to work out of GOPATH):
Write your module like this:
Tree:
moduledir/packagedir1
moduledir/packagedir2
Initialize the module:
Recipe:
cd moduledir
go mod init moduledir ;# or go mod init github.com/user/moduledir
Build module packages:
Recipe:
go install ./packagedir1
go install ./packagedir2
Module things are supposed to automagically work!
In general what is the best way to solve problems like this i.e where to add the dependency? And how to manage different versions?
The Modules system is going to automatically manage dependencies for your module and record them in the files go.mod and go.sum. If you need to override some dependency, you should use the 'go get' command for that. For instance, see this question: How to point Go module dependency in go.mod to a latest commit in a repo?
You can also find much information on Modules here: https://github.com/golang/go/wiki/Modules

Development environment with vagrant + chef/puppet/salt: how to deal with user specific credentials (e.g. github)?

I want to create a dev environment with vagrant and friends to streamline the onboarding process for new devs. Found some awesome tutorials already.
What I don't understand is how to deal with user specific stuff. For example, within the Chef (or Puppet or Salt) setup I want to checkout repositories (from github). Since they are private, I need to know the users credentials. Same goes for npm login and presumably other stuff.
What kind of approaches are there, to deal with user specific logins?
One of the extensible points in vagrant's puppet implementation is the ability to inject custom facts into the puppet run. See the section "Custom Facts" in the Vagrantfile Puppet Apply docs.
That leaves the question of how to supply those facts to the Vagrantfile. One way is to create a file (yaml, json, etc) in your project directory that includes user specific settings and read it into the Vagrantfile (it's, just ruby, after all). Make sure you add the user specific settings file to your source control's ignore list. I've never tried this plugin, but nugrant looks like it does a lot of this.
The above has the nasty side effect of leaving your passwords stored on your hard drive in a place where anyone on the team knows to look. If that is not acceptable, you can also make Vagrant prompt the user for passwords on the command line and use the entered value. Doesn't require storing passwords on your host machine, but does require re-entering them every time you use vagrant.

Is it ok to use ansible for deployement of apps instead of make files

I have recently started using ansible for configuration management of linux servers.
My habbit is that if I learn one tool then I try to use it as much as possible.
Initially for my php web apps I had a long Makefile which used to download, install packages , make php.ini file chnages , extract zip files , copy files between folders etc to deploy my application in as automated way.
Now, I am thinking of converting that Makefile deployment to Ansible because then I can arrange the separate yml file for separate areas rather than one big makefile for the whole project.
I want to know that is it good idea to use ansible for that or Makefile will be good for that.
Sure, Ansible is great for that. You can separate all your different steps into different playbooks that are identified by yaml files.
You can define common tasks and then include them in your specific playbooks.
You can also make use of Ansible roles to create complete set of playbooks depending on the role of the server. For example, one set servers' role could be webservers and another set of servers' role could be databases.
You can find more info on roles here: http://docs.ansible.com/playbooks_roles.html
There are's also a few modules on the web out there that you can also use to get you started and you can also use Ansible Galaxy to import roles.
Of course, you can accomplish the same by breaking down your Makefile but maybe you want to learn a new tool.
Hope it helps.

What is the correct way to use Chef from Ruby (Rails)?

I'm very new with Chef, maybe I search wrong but Google show a lot of quick starts and deployment options, but mostly on how to deploy an app from dev's console. What I need is to perform recipes from the Rails app.
I have a stack which includes Rails+Resque as a master and Chef as a slave. Chef is added as a gem chef, the chef/shef/ext used inside the app to run queries.
It should do several things, like create ssh users (which works) and deploy new app stacks (which don't).
As the chef gem doesn't have a lot of docs and ext doesn't feel like user (or dev) oriented too, I think there should be some other way to work with Chef server (knife?), or some kind of documentation on gem I definitely miss to work effitiantly with this.
We got stuck on something similar and ended up using the ridley gem:
As per this SO question.

Puppet to chef converter

Is there any convertor which converts Puppet scripts to Chef?
I found ruby script which converts Chef scripts to Puppet https://github.com/relistan/chef2puppet but I need puppet2chef.
UPDATE: So, Blueprint is abandonware (last update in 2013). I think the answer to this question is, sadly, now: No.
So, I do not believe there is a 'simple script' way available yet to do this conversion. What I've done in testing is to use Blueprint to do the following:
Install a fresh node with Puppet for the node type you wish to "convert".
Allow Blueprint to scan the resulting server.
Use Blueprint to export either Chef or Puppet code.
Repeat for each node type you have defined in Puppet (or Chef, if you go the other direction).
From the Blueprint README.md:
Blueprint reverse-engineers servers.
Easy configuration management.
Detect relevant packages, files, and source installs.
Generate reusable server configs.
Convert blueprints to Puppet or Chef or CFEngine 3.
No DSLs, no extra servers, no workflow changes.
I hope I'm proven wrong, and there is a soup-to-nuts script to just "convert" from Puppet to Chef. I'd use it in a heartbeat! :) This method will at least get you started.

Resources