Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we run any cookbooks using terraform provisioner? #413

Open
only4pri opened this issue Aug 12, 2020 · 6 comments
Open

Can we run any cookbooks using terraform provisioner? #413

only4pri opened this issue Aug 12, 2020 · 6 comments

Comments

@only4pri
Copy link

Can we run any cookbooks using terraform provisioner?

I want to run a cookbook once a server is built. How can i achieve it ?

@edwardbartholomew
Copy link
Collaborator

edwardbartholomew commented Aug 12, 2020

Greetings @only4pri and thank you for your interest in kitchen-terraform!
Bootstrapping a server with Chef is something that can happen naturally with Terraform (without need for kitchen-terraform) as I'll describe below. The great thing about using kitchen-terraform though is that you can easily run Inspec tests to verify everything together - that changes made in either Terraform or your cookbook, didn't break your overall module deployment.

My typical workflow would have the Terraform module bundle the cookbook and upload to a s3 bucket with a null_resource. Then create a template that can be called during server bootstrapping. In this example, I've named it mycookbook and it exists in a different repo than the Terraform module) . If this cookbook uses other cookbooks, then you'll need to use berks package in this below step rather than just zip it up.

Use AWS CLI to upload mycookbook cookbook:

resource "null_resource" "upload_cookbook" {
  depends_on = ["aws_s3_bucket.mycookbook_bootstrapping"]
  provisioner "local-exec" {
    command = <<EOF
cd /tmp;
rm -rf mycookbook mycookbook.zip;
git clone git@github.com:newcontext/mycookbook.git;
zip -X -r mycookbook.zip mycookbook -x \*.git\*
aws s3 cp mycookbook.zip s3://${aws_s3_bucket.mycookbook_bootstrapping.id}
EOF
  }
}

Create a bootstrapping script to run when server starts:

#!/usr/bin/env bash

# install prereqs
apt-get update
apt-get install -y awscli unzip

# install chefdk (use a more current version)
wget https://packages.chef.io/files/current/chefdk/3.0.29/ubuntu/16.04/chefdk_3.0.29-1_amd64.deb
dpkg -i chefdk_3.0.29-1_amd64.deb
# from /tmp, download wrapper cookbook and unzip it
cd /tmp
aws s3 cp --region ${aws_region} s3://${s3_bucket_name}/mycookbook.zip .
unzip mycookbook.zip
# need to have HOME set to avoid something like: https://github.com/ConnorAtherton/rb-readline/issues/8
export HOME=/tmp
# download dep cookbooks and run chef-zero to configure
berks vendor --berksfile mycookbook/Berksfile /tmp/cookbooks
echo '${chef_attributes}' > attributes.json
chef-client -j attributes.json -z --override-runlist recipe['mycookbook']

Create template for above script (create another one if you want attributes like in this example):

data "template_file" "script" {
  template = "${file("${path.module}/templates/userdata.sh.tpl")}"

  vars = {
    aws_region      = "${data.aws_region.current.name}"
    s3_bucket_name  = "${aws_s3_bucket.mycookbook.id}"
    chef_attributes = "${data.template_file.chef_attributes.rendered}"
  }
}

When creating the instance, set this template to run via user_data:

resource "aws_instance" "repo" {
  depends_on = ["null_resource.upload_keys"]

  ami                  = "${var.image_id}"
  instance_type        = "${var.instance_type}"
  user_data            = "${data.template_cloudinit_config.config.rendered}"

There's multiple ways but that's one pattern I've used. The great thing about using this module with Terraform is being able to run your tests

@elijah
Copy link
Member

elijah commented Aug 12, 2020 via email

@edwardbartholomew
Copy link
Collaborator

Thanks for the encouragement @elijah , that's a great idea! Any suggestions - like do you think would cloudinit be preferable to userdata?

@elijah
Copy link
Member

elijah commented Aug 12, 2020 via email

@only4pri
Copy link
Author

Thanks for your reply. I Created New "null_resource" to run a simple command on remote machine.

resource "null_resource" "example1" {
provisioner "remote-exec" {
connection {
host = "${optumvm_rhel7fsvm.rhel7ServerA.servername}"
bastion_host = "apsr*****"
bastion_host_key = "pathofthefil"
bastion_port = "22"
bastion_user = "root"
bastion_private_key = "pathofthefil"
private_key = "pathofthefile"
}
inline = [
"mkdir -p /tmp/iamonetest",
]
}
}

Can Anyone Explain? what private key is needed here ? and from where to fetch it ?

@KevinBuchs
Copy link
Contributor

Hi @only4pri - I think, but am not sure, that you need to supply your Chef private key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants