简体   繁体   中英

Using variables in Ruby for Chef cookbook

I have my cookbook which I am using to create an RDS instance on AWS. I did not want to store the AWS credentials in my code so I wrote a small snippet of Ruby code to get the credentials from a file stored on my local machine. Here's the code:

Dir.glob("#{Dir.home}/.aws/config1") do |my_config_file|
   access_key = File.readlines(my_config_file)[0]
   secret_access_key = File.readlines(my_config_file)[1]
   #puts access_key
   #puts "\n"
   #puts secret_access_key
end

    include_recipe "aws-rds"

    aws_rds db_info[:name] do
      # will use the iam role if available
      # optionally place the keys
      # see http://docs.aws.amazon.com/AWSSdkDocsRuby/latest/DeveloperGuide/ruby-dg-roles.html

      aws_access_key        access_key
      aws_secret_access_key secret_access_key
      engine                'postgres'
      db_instance_class     'db.t1.micro'
      region                'us-east-1'
      allocated_storage     5
      master_username       db_info[:username]
      master_user_password  db_info[:password]
    end

When I run my cookbook, I keep getting an error like this:

Recipe Compile Error in C:/Users/amohamme1/.chef/local-mode-cache/cache/cookbooks/amir_rds_test-machines/recipes/up-machines.rb
================================================================================

NoMethodError
-------------
undefined method `access_key' for Chef::Resource::AwsRds

I am new to ruby. I have tried declaring the access_key and secret_access_key variables as global. That did not solve the problem. I'm not sure how I can fix this problem. Any help is appreciated.

The issue is the variables are declared inside a block, variables declared in a block are scoped to that block so when the block ends (the end keyword) the variable disappears. If you want to use the variable inside your resource you should do:

access_key = nil
secret_access_key = nil

Dir.glob("#{Dir.home}/.aws/config1") do |my_config_file|
   access_key = File.readlines(my_config_file)[0]
   secret_access_key = File.readlines(my_config_file)[1]
end

aws_rds db_info[:name] do
  aws_access_key        access_key
  aws_secret_access_key secret_access_key
  engine                'postgres'
  db_instance_class     'db.t1.micro'
  region                'us-east-1'
  allocated_storage     5
  master_username       db_info[:username]
  master_user_password  db_info[:password]
end

One thing to keep in mind is that this isn't the "Chef way" of storing secrets. Items that we don't want in source control are normally stored in data bags .

In the case of secrets like access keys, the "Chef way" is to either use encrypted data bags or if you need to be more enterprise then chef vault .

I think you're a bit off in the weeds with your approach here.

Consider creating AWS infrastructure pieces such as RDS using the AWS CloudFormation service. Chef is better suited at running on a VM (eg EC2 instance) and provisioning your software stack.

For example, use cloud formation to create your EC2 instance. Use chef to install software components on it, such as the JDK, Tomcat, etc.

As the comments you've included indicate, an IAM instance profile would be the preferred way to handle authentication/authorization when using this cookbook. With your current solution, you could consider storing these variables in an encrypted data bag.

I suspect your error has to do with the convergence/execution phases of chef. As a fail safe, you could pass these in via knife/chef-solo when you execute the cookbook via json attributes.

knife .... --json-attributes '{"myCompany":{"aws":{"access_key":"...", "secret_key":"..."}}}'

Your recipe would then become

include_recipe "aws-rds"

aws_rds db_info[:name] do
  aws_access_key        node[:myCompany][:aws][:access_key]
  aws_secret_access_key node[:myCompany][:aws][:secret_key]
  engine                'postgres'
  db_instance_class     'db.t1.micro'
  region                'us-east-1'
  allocated_storage     5
  master_username       db_info[:username]
  master_user_password  db_info[:password]
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM