需要解决的障碍

需要解决的障碍

我的雇主需要在 OpsWorks 中启动的 AWS ec2 实例上线后为其添加标签。

此堆栈中的实例均为 MS Windows Server 2012 R2 Base。目标是向堆栈 Foo 中启动的实例添加自定义标签,向堆栈 Bar 中启动的实例添加自定义标签,如“application”:“foo”。

我找到了github repo chef-aws-tag我相信如果我在 Linux 上运行 Chef 11,它就能满足我的需求。OpsWorks 仅适用于 Windows Server 2012,并且仅适用于 Chef 12.2。

当我将 github repo 中的 chef-aws-tag 配方添加到安装生命周期事件时,实例在“running_setup”处失败,并出现“setup_failed”。

然后,Chef 故障日志在 running_setup 阶段报告此故障:

INFO: HTTP Request Returned 412 Precondition Failed : No such cookbook: aws 
ERROR: Running exception handlers
FATAL: Net::HTTPServerException: 412 "Precondition Failed "

这与 metadata.rb 中的依赖项匹配,行:depends 'aws', '>= 0.2.4'
我知道缺少依赖项。我不清楚如何满足此依赖项。配方在 S3 中,存储库 URL 为https://s3-us-west-2.amazonaws.com/employer/ec2instance-tagging.zip

当我将配方添加到配置生命周期事件时,机器上线且没有错误,但标签未添加。ec2 实例显示“stock”标签;键“opsworks:instance”、“opsworks:layer:foo_layer”、“opsworks:stack”和“Name”均具有我期望的值。我想要通过配方添加的标签(“application”、“team”、“environment”)不存在。

自定义 JSON 添加到 Stack 级别:

{ "aws-tag": {
        "tags": {
            "team": "specialteam",
            "application": "foo",
            "environment": "development"
        }
    }
}

是否有一个特定于 OpsWorks AWS 的配方或 Cookbook 我应该调用它来在启动后为实例设置标签?我该如何调用该配方?

我读过这个关于使用 OpsWorks 自定义应用程序部署的 AWS 博客文章。我是否遗漏了相同的“通过 chef 在实例上设置 aws 标签”配方或烹饪书,该配方或烹饪书位于 亚马逊网络服务 - 实验室GitHub 上的存储库?

aws opsworks-cookbooks在 github 上说“对于 Chef 12.2 Windows 和 Chef 12 Linux,没有内置食谱”,但我希望这是错误的 :-) 并且已经添加了我尚未找到的食谱。或者,希望有人已经这样做了,并在某处记录了它。

我正在按照这篇 AWS 博客文章排除故障快速探索 AWS OpsWorks 中的 Chef 环境(同样是为 Linux 编写的)还有这个关于在 Opsworks 上调试 Chef 的 SF 问题


答案1

我自己能够解决其中的一些问题。通过向 AWS Support 提交案例,我获得了足够的指导来解决这个问题。

需要解决的障碍

  1. 使用存档文件时,不同平台的食谱目录结构不同。

    如果您通过存储在 AWS S3 上的存档文件提供配方,AWS 要求为 Linux 提供一个目录结构,并为另一个不同的目录结构提供目录结构对于 Windows。

    Linux 可以将多本食谱放在一个根目录中。这是$ berks package默认的做法。

    Windows 不接受该根目录。该$ berks package命令没有以 Windows 接受的方式构建一个包含多个 cookbook 的存档的选项。我不得不手动编辑 tarfile。

  2. Windows 上的 Ruby

    有一个"error: Seahorse::Client::NetworkingError: SSL_connect" 漏洞这可能会出现在“aws”说明书中。AWS 希望服务之间使用 https。这需要一个有效的证书颁发机构包。Windows 上的 Ruby 无法访问 OS CA 证书包。如果出现以下情况,可以修复此问题:

    a) 安装 aws-sdk gem,然后

    b)在配方中设置路径curl-ca-bundle.crt

  3. 关于依赖项和社区手册的详细信息。

    Windows 上适用于 Chef 12 的 AWS 文档没有提到 Berksfile 或社区食谱。这些都是在 AWS 上记录适用于 Linux 上的 Chef 11。

  4. 指定地区当调用更新时。

    奇怪的是,在实例上运行配方时显示实例不存在。

    FATAL: Aws::EC2::Errors::InvalidInstanceIDNotFound: aws_resource_tag[i-5ccd24d4] (stemsoft::default line 27) had an error: Aws::EC2::Errors::InvalidInstanceIDNotFound: The instance ID 'i-5ccd24d4' does not exist

    AWS 错误代码表示 InvalidInstanceID.NotFound 可能由以下原因造成:a) 超出区域范围,或 b) 最近创建的实例的 ID 尚未在系统中传播。

    解决方法是将其包含region stack['region']aws_resource_tag配方块中。

  5. 正确的策略附加到正确的角色

    确保“aws-opsworks-ec2-role”和“aws-opsworks-service-role”都设置了正确的策略。“aws-opsworks-service-role”可以保持原样,这样 OpsWorks 服务就可以对其他 AWS 服务进行 API 调用。默认 IAM 实例配置文件“aws-opsworks-ec2-role”需要在 ec2 上具有创建和描述标签的权限。

程序

以下步骤的目标是构建一个在 Microsoft Windows Server 2012 上运行 Chef 12 的 OpsWorks 堆栈,其中包含一个 (自定义) 食谱,其中包含一个设置自定义标签的配方。在我的示例中,标签从堆栈中的自定义 json 集中获取其信息。

我还没有找到可以做到这一点的现有食谱。我宁愿使用现有食谱,也不愿创建自定义食谱。

在此过程结束时,该配方使用厨师社区“aws”食谱 使用堆栈设置中定义的自定义 json 中设置的值来更新“团队”标签。

为此,配方使用搜索现有数据包来获取实例详细信息。它还使用搜索第二个现有数据包来获取区域详细信息。

(它对我有用....)

  1. 在 AWS,构建堆栈
  2. 在 AWS 上,将自定义 json 分配给堆栈
    • { “aws-tag”:{ “标签”:{ “团队”:“teamFooBar” } } }
  3. 在 AWS 上,使用自定义存储库配置堆栈。此示例使用 s3
  4. 在 AWS 上构建层
    • 简称全部小写
    • 安全组 AWS-OpsWorks-Blank-Server
    • 配方/配置“配置生命周期事件”例如,如果您的配方名为一度那么“配置生命周期事件”应该包含一次性::默认 食谱
  5. 本地安装厨师DK(Chef 开发套件)
    • 在本地安装适用于 Windows 的 Git
    • 我喜欢git-bash.exe
  6. 本地使用 Chef 初始化 cookbook 目录 cookbook_dir
    • 转到 build_root
    • 在 build_root 中创建目录 cookbook_dir
    • 在 build_root 中chef generate cookbook cookbook_dir
      • 例子:$ chef generate cookbook cookbook_dir --berks --copyright 'EMPLOYER' --email '[email protected]'
  7. 在本地,编辑 cookbook_dir\metadata.rb
    • 添加depends 'aws'
  8. 在本地编辑 cookbook_dir\recipes\default.rb
    • 在我的示例中,'#{node['aws-tag']['tags']['team']}' 将返回“teamFooBar”
    • 编辑配方以调用正确的 ca-bundle.crt
    • 编辑后,使用以下方式检查配方 ruby​​ 语法$ ruby -c /path/to/cookbook_dir/recipes/default.rb
  9. 本地一次性设置,初始化 berksfile
    • 在适用于 Windows MinTTY 的 Git 中,cd 到 cookbook_dir 并使用$ berks install它初始化 berksfile 并跟踪依赖项
  10. 在本地,编辑 cookbook_dir Berksfile
    • 添加cookbook 'aws'
  11. 在本地,cd 进入 cookbook_dir 并运行$ berks package以构建 cookbook_dir.tar.gz
  12. 在本地编辑 MS Windows Server 2012 的存档文件
    • 解压 cookbook_dir.tar.gz 。将所有内容移出目录 'cookbooks' 并上移一级。重新打包 cookbook_dir.tar.gz
  13. 上传 cookbook_dir.tar.gz 到 s3
    • 从 s3 中删除先前的副本
    • 确保权限正确(必要时“将所有内容公开”)
  14. 在 AWS 上,一次性设置,编辑分配给 OpsWorks 启动的实例的角色以更新标签
    • 'aws-opsworks-ec2-role' “语句”:[{“操作”:[“ec2:CreateTags”,“ec2:DescribeTags”],“资源”:[“*”],“效果”:“允许”}]
  15. 启动实例
    • 添加实例
    • 启动实例
    • stack > 运行命令 > 更新自定义菜谱
  16. 使固定Windows 版 aws-sdk gem 未附带正确的 ca-bundle.crt
    • 安装 ruby
      • 在初始设置中,需要此步骤
      • 在后续的测试运行中,不需要此步骤
    • 安装 aws-sdk
      • 在初始设置中,需要此步骤
      • 在后续的测试运行中,不需要此步骤
  17. 确认其有效
    • 检查 ec2 实例是否存在正确的标签
    • 检查 OpsWorks 实例日志(配置命令)
    • 成功示例:INFO: AWS: Updating the following tags for resource i-12345678 (skipping AWS tags): { .... "team"=>"teamFooBar"}

示例菜谱

示例菜谱 example::default.rb

Chef::Log.info("********** from custom json, Team  is  '#{node['aws-tag']['tags']['team']}' **********")

instance = search("aws_opsworks_instance", "self:true").first
Chef::Log.info("Instance id from data bag: #{instance['ec2_instance_id']}" )

stack = search("aws_opsworks_stack").first
Chef::Log.info("**********  stack['region'] from data bag:  '#{stack['region']}' **********")

include_recipe 'aws'
chef_gem "aws-sdk" do
    compile_time false
    action :install
    version node[:aws][:aws_sdk_version]
end

ruby_block "Set the AWS Bundle" do
   block do
      require 'aws-sdk'
      Aws.config[:ssl_ca_bundle] = 'C:\ProgramData\Git\bin\curl-ca-bundle.crt'
   end
   action :run
end

aws_resource_tag instance['ec2_instance_id'] do
    tags('team' => node['aws-tag']['tags']['team']   )
    region stack['region']
    action :update
    Chef::Log.info("********** updated tags('team') **********")
end

相关内容