Environment-specific Data bag?

Is it possible to have different values in a data bag per environment?

I find it tricky to change something in the structure of a data bag: I can
test the cookbook changes in my dev environment, but pushing the databag to
my chef-server makes it available to the production nodes, which don’t know
about the change.

This could also be a way to have different values for the respective
environments (like say, a different path, IP address, etc.).

Or am I using the data bag incorrectly?

Benoit

You can do this just by changing the structure of the items to include the environment as a top level key:

{
"id": "paths"
"production": { "path": "/usr/local" },
"dev": { "path": "/usr/local"}
}

So when you de-reference it:

i = Chef::DataBagItem('bagname', 'paths')
i[node.chef_environment]["path"]

Best,
Adam

On Oct 19, 2011, at 8:40 AM, Benoit Caron wrote:

Is it possible to have different values in a data bag per environment?

I find it tricky to change something in the structure of a data bag: I can test the cookbook changes in my dev environment, but pushing the databag to my chef-server makes it available to the production nodes, which don't know about the change.

This could also be a way to have different values for the respective environments (like say, a different path, IP address, etc.).

Or am I using the data bag incorrectly?

Benoit

Yes, its exactly what I'm doing.

I'm using the node.chef_environment to get the correct version of my
applications to release.

But when retrofitting one of my first cookbooks where I had:

{
"id": "appname",
"releases": { "releasename": "git-tag", "releasename2": "another-git-tag"}
}
to
{
"id": "appname",
"releases": {
"production": { "releasename": "git-tag", "releasename2":
"another-git-tag"},
"dev": { "releasename": "git-tag", "releasename2": "master"},
}

I had to break the structure; I could have just add another entry (say
"releasesversion"), but I would not have had to do this if databag could be
sticked to an environment.

But then, I'm not sure if having attributes defined in a roles would not be
better. Of course, with data bag it's easier to build tools to allow
non-technical people be able to push releases.

Anyway, thanks for the clarification!

On Wed, Oct 19, 2011 at 12:13 PM, Adam Jacob adam@opscode.com wrote:

You can do this just by changing the structure of the items to include the
environment as a top level key:

{
"id": "paths"
"production": { "path": "/usr/local" },
"dev": { "path": "/usr/local"}
}

So when you de-reference it:

i = Chef::DataBagItem('bagname', 'paths')
i[node.chef_environment]["path"]

Best,
Adam

On Oct 19, 2011, at 8:40 AM, Benoit Caron wrote:

Is it possible to have different values in a data bag per environment?

I find it tricky to change something in the structure of a data bag: I
can test the cookbook changes in my dev environment, but pushing the databag
to my chef-server makes it available to the production nodes, which don't
know about the change.

This could also be a way to have different values for the respective
environments (like say, a different path, IP address, etc.).

Or am I using the data bag incorrectly?

Benoit

Might be overkill for you, but instead of repeating the 'environments' inside each key I'd suggest putting the environment as the top level key and 'mirror' all your keys inside that:

{
"production": {
....
},
"staging": {
....
}
}

or if you need to iterate the environments you can add yet another key above that

{
"enviroments": {
"production": {
....
},
"staging": {
....
}
}
}

On Oct 19, 2011, at 10:00 AM, Benoit Caron wrote:

Yes, its exactly what I'm doing.

I'm using the node.chef_environment to get the correct version of my applications to release.

But when retrofitting one of my first cookbooks where I had:

{
"id": "appname",
"releases": { "releasename": "git-tag", "releasename2": "another-git-tag"}
}
to
{
"id": "appname",
"releases": {
"production": { "releasename": "git-tag", "releasename2": "another-git-tag"},
"dev": { "releasename": "git-tag", "releasename2": "master"},
}

I had to break the structure; I could have just add another entry (say "releasesversion"), but I would not have had to do this if databag could be sticked to an environment.

But then, I'm not sure if having attributes defined in a roles would not be better. Of course, with data bag it's easier to build tools to allow non-technical people be able to push releases.

Anyway, thanks for the clarification!

On Wed, Oct 19, 2011 at 12:13 PM, Adam Jacob adam@opscode.com wrote:
You can do this just by changing the structure of the items to include the environment as a top level key:

{
"id": "paths"
"production": { "path": "/usr/local" },
"dev": { "path": "/usr/local"}
}

So when you de-reference it:

i = Chef::DataBagItem('bagname', 'paths')
i[node.chef_environment]["path"]

Best,
Adam

On Oct 19, 2011, at 8:40 AM, Benoit Caron wrote:

Is it possible to have different values in a data bag per environment?

I find it tricky to change something in the structure of a data bag: I can test the cookbook changes in my dev environment, but pushing the databag to my chef-server makes it available to the production nodes, which don't know about the change.

This could also be a way to have different values for the respective environments (like say, a different path, IP address, etc.).

Or am I using the data bag incorrectly?

Benoit

I'm currently doing just like your first exemple, with a few other keys for
apps/cookbooks that needs it.

The thing is that I need to support many branch of our app at the same time:
I'm actually deploying different versions of the app in different
directories, that will be loaded by different vhosts.

So my databag looks like:

{ "id": "mysuperapp",
"path": "/path/the/same/in/every/environments",
"releases": {
"dev": { "releasename": "master", "oldrelease": "1.0.1"},
"production": { "releasename": "1.2.3", "oldrelease": "1.0.1"}
}
}

Where the value of the releases[node.chef_environment] is the name of a git
tag/branch. I then use the git resources to deploy to the correct version.

On Wed, Oct 19, 2011 at 1:48 PM, Alex Soto apsoto@gmail.com wrote:

Might be overkill for you, but instead of repeating the 'environments'
inside each key I'd suggest putting the environment as the top level key and
'mirror' all your keys inside that:

{
"production": {
....
},
"staging": {
....
}
}

or if you need to iterate the environments you can add yet another key
above that

{
"enviroments": {
"production": {
....
},
"staging": {
....
}
}
}

On Oct 19, 2011, at 10:00 AM, Benoit Caron wrote:

Yes, its exactly what I'm doing.

I'm using the node.chef_environment to get the correct version of my
applications to release.

But when retrofitting one of my first cookbooks where I had:

{
"id": "appname",
"releases": { "releasename": "git-tag", "releasename2": "another-git-tag"}
}
to
{
"id": "appname",
"releases": {
"production": { "releasename": "git-tag", "releasename2":
"another-git-tag"},
"dev": { "releasename": "git-tag", "releasename2": "master"},
}

I had to break the structure; I could have just add another entry (say
"releasesversion"), but I would not have had to do this if databag could be
sticked to an environment.

But then, I'm not sure if having attributes defined in a roles would not be
better. Of course, with data bag it's easier to build tools to allow
non-technical people be able to push releases.

Anyway, thanks for the clarification!

On Wed, Oct 19, 2011 at 12:13 PM, Adam Jacob adam@opscode.com wrote:

You can do this just by changing the structure of the items to include the
environment as a top level key:

{
"id": "paths"
"production": { "path": "/usr/local" },
"dev": { "path": "/usr/local"}
}

So when you de-reference it:

i = Chef::DataBagItem('bagname', 'paths')
i[node.chef_environment]["path"]

Best,
Adam

On Oct 19, 2011, at 8:40 AM, Benoit Caron wrote:

Is it possible to have different values in a data bag per environment?

I find it tricky to change something in the structure of a data bag: I
can test the cookbook changes in my dev environment, but pushing the databag
to my chef-server makes it available to the production nodes, which don't
know about the change.

This could also be a way to have different values for the respective
environments (like say, a different path, IP address, etc.).

Or am I using the data bag incorrectly?

Benoit