简体   繁体   English

在Ruby for Chef食谱中使用变量

[英]Using variables in Ruby for Chef cookbook

I have my cookbook which I am using to create an RDS instance on AWS. 我有用于在AWS上创建RDS实例的食谱。 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. 我不想将AWS凭证存储在我的代码中,所以我写了一小段Ruby代码来从本地计算机上存储的文件中获取凭证。 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. 我尝试将access_key和secret_access_key变量声明为全局变量。 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. 问题在于变量是在块内声明的,块中声明的变量的作用域是该块,因此当块结束时( end关键字),变量消失。 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. 考虑使用AWS CloudFormation服务创建AWS基础设施,例如RDS。 Chef is better suited at running on a VM (eg EC2 instance) and provisioning your software stack. Chef更适合在VM(例如EC2实例)上运行并配置软件堆栈。

For example, use cloud formation to create your EC2 instance. 例如,使用云形成来创建您的EC2实例。 Use chef to install software components on it, such as the JDK, Tomcat, etc. 使用chef在其上安装软件组件,例如JDK,Tomcat等。

As the comments you've included indicate, an IAM instance profile would be the preferred way to handle authentication/authorization when using this cookbook. 正如您所包含的注释所表明的那样,使用本食谱时,IAM实例配置文件将是处理身份验证/授权的首选方式。 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. 作为故障保险,当您通过json属性执行菜谱时,可以通过刀/厨师独奏将这些信息传入。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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