在Ruby for Chef cookbook中使用变量

在Ruby for Chef cookbook中使用变量,ruby,amazon-web-services,chef-infra,chef-recipe,Ruby,Amazon Web Services,Chef Infra,Chef Recipe,我有我的食谱,我正在使用它在AWS上创建RDS实例。我不想在代码中存储AWS凭据,所以我编写了一小段Ruby代码,以从本地计算机上存储的文件中获取凭据。代码如下: 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] #

我有我的食谱,我正在使用它在AWS上创建RDS实例。我不想在代码中存储AWS凭据,所以我编写了一小段Ruby代码,以从本地计算机上存储的文件中获取凭据。代码如下:

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
当我运行我的烹饪书时,我不断得到这样一个错误:

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

我对ruby是新手。我已经尝试将access\u key和secret\u access\u key变量声明为全局变量。这并没有解决问题。我不知道如何解决这个问题。非常感谢您的帮助。

我认为您在这里的做法有点不妥

考虑使用AWS CloudFormation服务创建AWS基础设施,如RDS。Chef更适合在VM(例如EC2实例)上运行和配置软件堆栈

例如,使用云形成来创建EC2实例。使用chef在其上安装软件组件,如JDK、Tomcat等

正如您所包含的注释所示,IAM实例概要文件将是使用本手册处理身份验证/授权的首选方法。使用当前的解决方案,可以考虑将这些变量存储在加密的数据包中。 我怀疑您的错误与chef的收敛/执行阶段有关。作为一个故障保护,当您通过json属性执行cookbook时,您可以通过刀子/chef solo将它们传递进来

knife .... --json-attributes '{"myCompany":{"aws":{"access_key":"...", "secret_key":"..."}}}'
你的食谱就会变成

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

我认为你在这里的做法有点不对劲

考虑使用AWS CloudFormation服务创建AWS基础设施,如RDS。Chef更适合在VM(例如EC2实例)上运行和配置软件堆栈

例如,使用云形成来创建EC2实例。使用chef在其上安装软件组件,如JDK、Tomcat等

正如您所包含的注释所示,IAM实例概要文件将是使用本手册处理身份验证/授权的首选方法。使用当前的解决方案,可以考虑将这些变量存储在加密的数据包中。 我怀疑您的错误与chef的收敛/执行阶段有关。作为一个故障保护,当您通过json属性执行cookbook时,您可以通过刀子/chef solo将它们传递进来

knife .... --json-attributes '{"myCompany":{"aws":{"access_key":"...", "secret_key":"..."}}}'
你的食谱就会变成

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

问题在于变量是在块内声明的,在块中声明的变量的作用域是该块,因此当块结束时(关键字
end
),变量消失。如果要在资源中使用变量,应执行以下操作:

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
要记住的一点是,这不是存储秘密的“厨师方式”。源代码管理中不需要的项通常存储在中


对于诸如访问密钥之类的机密,“厨师方法”是要么使用,要么如果您需要更具企业性。

问题是变量在块内声明,块中声明的变量的作用域是该块,因此当块结束时(关键字
end
),变量消失。如果要在资源中使用变量,应执行以下操作:

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
要记住的一点是,这不是存储秘密的“厨师方式”。源代码管理中不需要的项通常存储在中


对于像访问密钥这样的秘密,“厨师方法”是要么使用,要么如果你需要更具进取心。

@arthur在下面是正确的。这不是一个收敛/执行阶段的问题,而是变量作用域。有趣的观点。我将尝试云形成服务。好吧,我的同事们想成为“平台不可知论者”。我猜使用云形成是被抛到了窗外。不过谢谢你的帮助。啊,真可惜他们给了你这样的借口。一天结束时,您仍然在使用rds。谁在乎你是否为它配备了云阵形vs厨师。如果您安装并维护自己的postgres安装,那么我同意,但这将使用chef,因为它擅长提供vm。Scubadev,有没有办法直接与您联系以了解任何问题?我现在正试图从快照创建一个RDS实例,我正在使用超市上提供的食谱。它不具备从快照创建RDS的功能。我不确定如何才能使该功能正常工作。如果你愿意,我可以就stackoverflow提出一个新问题。我使用的食谱如下:@arthur在下面是正确的。这不是一个收敛/执行阶段的问题,而是变量作用域。有趣的观点。我将尝试云形成服务。好吧,我的同事们想成为“平台不可知论者”。我猜使用云形成是被抛到了窗外。不过谢谢你的帮助。啊,真可惜他们给了你这样的借口。一天结束时,您仍然在使用rds。谁在乎你是否为它配备了云阵形vs厨师。如果您安装并维护自己的postgres安装,那么我同意,但这将使用chef,因为它擅长提供vm。Scubadev,有没有办法直接与您联系以了解任何问题?我现在正试图从快照创建一个RDS实例,我正在使用超市上提供的食谱。它不具备从快照创建RDS的功能。我不确定如何才能使该功能正常工作。如果你愿意,我可以就stackoverflow提出一个新问题。我使用的食谱如下:我认为这也是问题所在。我确实尝试过在块外声明变量,就像在代码中一样。现在我得到了一个新的错误,类似于:在资源“aws rds[AQAAD]aws::rds::Errors::IncompletSignature------------------授权标头需要“Signature”参数上执行操作时出错。授权标头需要“SignedHeaders”参数。当我使用我的证件时