1 Chef InSpec介绍
任何业务都依赖于基础设施环境。近年来,基础设施领域已发生了巨大的变化。从最初的传统数据中心到数据中心托管服务,而如今,基础设施即服务和云平台在企业中更受欢迎。因此,大多数企业正在将其工作负载从本地数据中心迁移到云平台。
为了部署和管理这些复杂的基础设施配置,很多企业使用代码即基础设施(IaC)。当您使用IaC在AWS云平台上创建成百上千个资源时,如何知道代码按预期方式部署了这些资源?这些资源是否遵守合规性和安全性措施?我们并不确定,因此需要基础设施测试程序。
Chef InSpec是一个用于测试和审核应用程序和基础设施的开源代码框架。
Chef InSpec的工作原理是将系统的实际状态与您编写的Chef InSpec代码表达的期望状态进行比较。Chef InSpec可以检测违规并以报告的形式显示。
2 Chef InSpec入门
下面将主要介绍Chef InSpec的安装及环境配置。
2.1 Chef InSpec安装
Chef InSpec提供了适配多种操作系统环境的安装包,支持的操作系统类型如下:
- Amazon Linux
- Debian GNU/Linux
- Red Hat Enterprise Linux/CentOS
- macOS
- SUSE Linux Enterprise Server
- Ubuntu Linux
- Windows
软件包的下载地址如下:
https://downloads.chef.io/products/inspec
本文以Amazon Linux环境为例进行说明,下载当前最新的Chef InSpec软件包,使用下面的命令进行Chef InSpec安装:
rpm -ivh inspec-<version>.x86_64.rpm
安装完成后可以看到inspec命令可以正常运行,并提示inspec命令可以使用的参数帮助信息
2.2 Chef InSpec配置介绍
使用Chef InSpec时主要需要弄清楚下面的三部分:
- Command-line interface
- Profile
- Resource
InSpec CLI使用local,SSH,WinRM,Docker或AWS等连接方式,可针对不同基础设施目标运行测试和审核。常用命令说明如下:
命令 |
说明 |
archive |
将配置文件压缩成tar.gz(默认)或zip文件 |
check |
验证指定路径上的所有测试 |
exec |
针对指定目标运行所有测试文件。 加载给定的配置文件,并在需要时获取其依赖项。然后连接到目标并执行配置文件中包含的所有控件。输出测试结果。 |
help |
查看特定命令的帮助信息 |
shell |
打开一个交互式的调试终端 |
version |
打印此工具的版本 |
Chef InSpec支持创建复杂的测试和合规性配置文件,每个profile文件都是独立的结构,具有自己的执行流程。用户可以自己编写profile文件,还可以在社区支持的Chef Supermarket和GitHub上找到别人写的profile。
Profile文件通常具有下面的目录结构:
examples/profile
├── README.md
├── controls
│ ├── example.rb
├── libraries
│ └── extension.rb
└── inspec.yml
其中各个文件和目录的说明如下:
- md是用于解释profile的适用范围和用法
- controls是所有测试用例所在的目录
- libraries是用于存放扩展Chef InSpec资源代码的目录
- yml包含配置文件的描述
Chef InSpec拥有80多种可供使用的资源。如果您需要的资源尚未提供,也可以编写自己的自定义资源。Chef InSpec支持的资源列表如下:
https://docs.chef.io/inspec/resources/
2.3 使用Chef InSpec测试AWS资源
典型的使用环境如下图所示,在数据中心内使用Chef InSpec对AWS进行基础设施资源测试。
从本地数据中心连接AWS环境需要使用Access Key和Secret Access Key(AKSK)。在企业环境中,通常会将IAM User集中在一个Master账号中进行管理,用户使用IAM User登陆AWS环境,然后再用Assume Role的方式操作其它AWS账户。
使用Chef InSpec连接AWS前,首先需要创建IAM用户,并生成AKSK。另外在UseCase账号中,需要创建Assume Role,给予适当的权限并允许Master账号中的IAM User切换到Use Case账号。
在本地数据中心连接AWS环境的配置示例如下:
# cat .aws/credentials
[default]
aws_access_key_id = <Access Key>
aws_secret_access_key = <Secret Access Key>
# cat ~/.aws/config
[default]
region = cn-north-1
output = json
[profile usecase]
role_arn = <UseCase Account IAM Role Arn>
使用如下命令创建示例profile,该命令会自动生成profile目录结构。
# inspec init profile --platform aws example
─────────────────────────── InSpec Code Generator ───────────────────────────
Creating new profile at /root/example
• Creating file README.md
• Creating file attributes.yml
• Creating directory controls
• Creating file controls/example.rb
• Creating file inspec.yml
示例代码的测试内容在controls/example.rb文件中
# copyright: 2018, The Authors
title "Sample Section"
aws_vpc_id = attribute("aws_vpc_id", value: "", description: "Optional AWS VPC identifier.")
# You add controls here
control "aws-single-vpc-exists-check" do # A unique ID for this control.
only_if { aws_vpc_id != "" } # Only run this control if the `aws_vpc_id` attribute is provided.
impact 1.0 # The criticality, if this control fails.
title "Check to see if custom VPC exists." # A human-readable title.
describe aws_vpc(aws_vpc_id) do # The test itself.
it { should exist }
end
end
# Plural resources can be inspected to check for specific resource details.
control "aws-vpcs-check" do
impact 1.0
title "Check in all the VPCs for default sg not allowing 22 inwards"
aws_vpcs.vpc_ids.each do |vpc_id|
describe aws_security_group(vpc_id: vpc_id, group_name: "default") do
it { should allow_in(port: 22) }
end
end
end
control "aws-vpcs-multi-region-status-check" do # A unique ID for this control.
impact 1.0 # The criticality, if this control fails.
title 'Check AWS VPCs in all regions have status "available"' # A human-readable title.
aws_regions.region_names.each do |region| # Loop over all available AWS regions
aws_vpcs(aws_region: region).vpc_ids.each do |vpc| # Find all VPCs in a single AWS region
describe aws_vpc(aws_region: region, vpc_id: vpc) do # The test itself.
it { should exist } # Confirms AWS VPC exists
it { should be_available } # Confirms AWS VPC has status "available"
end
end
end
end
该测试的主要内容包含:
- 如果传入指定的VPC ID,则检查指定的VPC是否存在
- 检查所有VPC的安全组内是否包含允许22端口访问的策略
- 检查所有区域内的状态为available的VPC
执行如下命令运行该profile对AWS环境进行测试:
# inspec exec example -t aws://cn-north-1/usecase
Profile: AWS InSpec Profile (example)
Version: 0.1.0
Target: aws://cn-north-1
↺ aws-single-vpc-exists-check: Check to see if custom VPC exists.
↺ Skipped control due to only_if condition.
✔ aws-vpcs-check: Check in all the VPCs for default sg not allowing 22 inwards
✔ EC2 Security Group ID: sg-01d67dds39bcffe17 Name: default VPC ID: vpc-032cdd155d561c7bf is expected to allow in {:port=>22}
✔ aws-vpcs-multi-region-status-check: Check AWS VPCs in all regions have status "available"
✔ VPC vpc-032cdd155d561c7bf in cn-north-1 is expected to exist
✔ VPC vpc-032cdd155d561c7bf in cn-north-1 is expected to be available
Profile: Amazon Web Services Resource Pack (inspec-aws)
Version: 1.31.0
Target: aws://cn-north-1
No tests executed.
Profile Summary: 2 successful controls, 0 control failures, 1 control skipped
Test Summary: 3 successful, 0 failures, 1 skipped
3 总结
在实际的应用场景中,可以将Chef InSpec用于Terraform等IaC工具进行环境部署之后的测试与审核,另外,还可以将Chef InSpec与Jenkins等CI/CD工具集合使用,以持续测试您部署的基础架构,以确保其符合合规性策略。
本篇作者
卢冲 – 亚马逊 AWS 专业服务团队云架构咨询顾问。负责企业级客户的云架构设计和优化、云上运维咨询和技术实施。曾就职于Novell、RedHat等企业,具有多年企业级客户项目实施经验。