Puppet: You cannot specify more than one of content, source, target -- I did not!

Question: Guess how to the error below related to the problem.

err: Failed to apply catalog: You cannot specify more than one of content, source, target at ...

      file { "/etc/rsyslog.d/forward_tcp_${audit_forwarding_dest}.conf":
        ensure  => exist,
        owner   => root,
        group   => root,
        mode    => 644,
        require => Package['rsyslog'],
        content => template('rsyslog/forward.conf.erb'),

Collapse )
Answer: All I needed was to have ensure => present.

Chef data bags hate minute. A few reads to work around the thing

Thanks to my coworker, Greg for those.

Then, take a look at Citadel and Barbican:
- Specifically designed to use S3 (and compatible with O3)
- Significant limitations (systems can have only one IAM role)
- Comes with an Angular-based webapp
- RESTful API designed specifically to solve encrypted data bag problems
- No Ruby API

Dropwizard: producing HTML and JSON from the same class does not work

In my case the problem is caused by the two things:
1. JacksonMessageBodyProvider is annotated with a too generic of a media mapping (*/*)
2. Dropwizards io.dropwizard.views.ViewMessageBodyWriter is annotated of same mapping and is getting a higher priority

The workaround is simple:

1. Define a dummy provider inheriting from the Jackson's one

public class Jackson extends JacksonMessageBodyProvider {
   public Jackson(ObjectMapper mapper, Validator validator) {
      super(mapper, validator);

2. Register it with your dropwizard

environment.jersey().register(new Jackson(environment.getObjectMapper(), environment.getValidator()));

Happy coding!

Fixtures in chef test kitchen

I love test kitchen it makes infrastructure as a code even more testable and reproducible, yet some things are not that smooth yet, still after some googling they're possible. Let me save you some time then :)

At the time of writing latest test kitchen is v1.1.1 and it includes no preinstall/postinstall commands(although, I've seen some PR's on github making that happen). Until then you'll need to do the following:

1) Create a cookbook in your test folder
2) Add a recipe setting up environment for you, e.g.:
   new file: test/cookbooks/fake/
   new file: test/cookbooks/fake/metadata.rb
   new file: test/cookbooks/fake/recipes/fixture_mysql_and_a_user.rb

3) Reference that on your .kitchen.yml run_list
  - name: existing_mysql
    - recipe[fake::fixture_mysql_and_a_user]
    - recipe[platform_db]

4) Don't forget to verify the outcome
new file:   test/integration/existing_mysql/bats/mysql.bats

5) The magic! Add the following to your Berksfile, otherwise nothing will work
cookbook "fake", path: "./test/cookbooks/fake", group: :integration

Debugging rspec_puppet tests

Debugging rspec_puppet tests can be somewhat painful, so you can use the following:

  it "should do stuff" do
    Puppet::Util::Log.level = :debug

    # dump compiled catalog
    it { p subject.resources }

It has two effects:

  1. You see more of the files resolution process(plus missing vars)

  2. It shows you all the resources compiled puppet catalog will have just before the test assertions run

Yay Chef!

On natural keys vs surrogate keys

pk  Recently, I've spent quite a while working around a DB schema where a primary key was natural one(a carefully chosen field from the domain). And still we'll need a migration to make the thing look good. Let me summarize the aspects:

  • Changing PK is painful

    • Foreign keys from other tables

    • Following the above chaning PK requires some cascading either when data changed, or when a schema is redesigned(In the example, after introducing surrogate key to Person table we'd need to drop FK constraints from PersonData and PersonDataChangeNotification)

  • You're expected to know it at insert time

We hit both points from the above because PK was a key supplied by an external system. Please don't.