我的雇主需要在 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 提交案例,我获得了足够的指导来解决这个问题。
需要解决的障碍
使用存档文件时,不同平台的食谱目录结构不同。
如果您通过存储在 AWS S3 上的存档文件提供配方,AWS 要求为 Linux 提供一个目录结构,并为另一个不同的目录结构提供目录结构对于 Windows。
Linux 可以将多本食谱放在一个根目录中。这是
$ berks package
默认的做法。Windows 不接受该根目录。该
$ berks package
命令没有以 Windows 接受的方式构建一个包含多个 cookbook 的存档的选项。我不得不手动编辑 tarfile。Windows 上的 Ruby
有一个
"error: Seahorse::Client::NetworkingError: SSL_connect"
漏洞这可能会出现在“aws”说明书中。AWS 希望服务之间使用 https。这需要一个有效的证书颁发机构包。Windows 上的 Ruby 无法访问 OS CA 证书包。如果出现以下情况,可以修复此问题:a) 安装 aws-sdk gem,然后
b)在配方中设置路径
curl-ca-bundle.crt
关于依赖项和社区手册的详细信息。
这Windows 上适用于 Chef 12 的 AWS 文档没有提到 Berksfile 或社区食谱。这些都是在 AWS 上记录适用于 Linux 上的 Chef 11。
指定地区当调用更新时。
奇怪的是,在实例上运行配方时显示实例不存在。
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
配方块中。正确的策略附加到正确的角色
确保“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 中设置的值来更新“团队”标签。
为此,配方使用搜索现有数据包来获取实例详细信息。它还使用搜索第二个现有数据包来获取区域详细信息。
(它对我有用....)
- 在 AWS,构建堆栈
- 在 AWS 上,将自定义 json 分配给堆栈
- { “aws-tag”:{ “标签”:{ “团队”:“teamFooBar” } } }
- 在 AWS 上,使用自定义存储库配置堆栈。此示例使用 s3
- 在 AWS 上构建层
- 简称全部小写
- 安全组 AWS-OpsWorks-Blank-Server
- 配方/配置“配置生命周期事件”例如,如果您的配方名为一度那么“配置生命周期事件”应该包含一次性::默认 食谱
- 本地安装厨师DK(Chef 开发套件)
- 在本地安装适用于 Windows 的 Git
- 我喜欢
git-bash.exe
- 本地使用 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]'
- 例子:
- 在本地,编辑 cookbook_dir\metadata.rb
- 添加
depends 'aws'
- 添加
- 在本地编辑 cookbook_dir\recipes\default.rb
- 在我的示例中,'#{node['aws-tag']['tags']['team']}' 将返回“teamFooBar”
- 编辑配方以调用正确的 ca-bundle.crt
- 编辑后,使用以下方式检查配方 ruby 语法
$ ruby -c /path/to/cookbook_dir/recipes/default.rb
- 本地一次性设置,初始化 berksfile
- 在适用于 Windows MinTTY 的 Git 中,cd 到 cookbook_dir 并使用
$ berks install
它初始化 berksfile 并跟踪依赖项
- 在适用于 Windows MinTTY 的 Git 中,cd 到 cookbook_dir 并使用
- 在本地,编辑 cookbook_dir Berksfile
- 添加
cookbook 'aws'
- 添加
- 在本地,cd 进入 cookbook_dir 并运行
$ berks package
以构建 cookbook_dir.tar.gz - 在本地编辑 MS Windows Server 2012 的存档文件
- 解压 cookbook_dir.tar.gz 。将所有内容移出目录 'cookbooks' 并上移一级。重新打包 cookbook_dir.tar.gz
- 上传 cookbook_dir.tar.gz 到 s3
- 从 s3 中删除先前的副本
- 确保权限正确(必要时“将所有内容公开”)
- 在 AWS 上,一次性设置,编辑分配给 OpsWorks 启动的实例的角色以更新标签
- 'aws-opsworks-ec2-role' “语句”:[{“操作”:[“ec2:CreateTags”,“ec2:DescribeTags”],“资源”:[“*”],“效果”:“允许”}]
- 启动实例
- 添加实例
- 启动实例
- stack > 运行命令 > 更新自定义菜谱
- 使固定Windows 版 aws-sdk gem 未附带正确的 ca-bundle.crt
- 安装 ruby
- 在初始设置中,需要此步骤
- 在后续的测试运行中,不需要此步骤
- 安装 aws-sdk
- 在初始设置中,需要此步骤
- 在后续的测试运行中,不需要此步骤
- 安装 ruby
- 确认其有效
- 检查 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