亚马逊AWS官方博客

使用 AWS Cloud Development Kit 通过 Open Policy Agent 实现策略即代码

AWS Cloud Development Kit (AWS CDK) 是一个开源软件开发框架,可使用户通过熟悉的编程语言来定义和预置 AWS 基础设施。使用 CDK,您可以对基础设施进行版本控制,且基础设施即代码的改变可为您更高效可靠地管理 AWS 基础设施提供新机会。

但是,当计划部署新的 AWS 资源或更新它们时,您必须确保这些更改不会造成漏洞,或者您的组织可能设有基线,您必须根据合规性要求遵守。现在,应该设置定义操作准备情况和保持安全基线的标准,以确保基础设施更改不会造成问题。Open Policy Agent (OPA) 是一个孵化项目的原生云计算基础,旨在自动执行策略测试。OPA 提供统一的框架和语言,以声明、实现和控制原生云解决方案中各种组件的策略。

OPA 与 AWS CDK 集成,可以帮助您实现策略即代码功能,从而在 AWS CDK 对 AWS 环境进行更改之前测试更改。这带来了很多不同好处,包括:

  • 个体团队成员可以轻松对更改执行检查。
  • 可以通过与 CI/CD 集成自动执行策略评估。
  • 用于可以对基础设施即代码输入实施预防性控制。
  • 用户可以基于行业最佳实践框架(例如 CIS AWS 基准)的技术控制要求编写自定义 OPA 策略。

总而言之,工程师的反馈回路将会缩短。

本博客文章的剩下部分将逐步介绍如何将 OPA 与 AWS CDK 结合用于策略即代码。下面是将涵盖的高级任务的列表:

  • 创建 AWS CDK 项目以部署 AWS 资源。
  • 基于 REGO 策略语言编写简单的 OPA 策略。
  • 利用 OPA 策略验证 CDK 基础设施代码。

先决条件

在 AWS Cloud9 中创建 EC2 环境

遵照说明创建 Amazon Linux Cloud9 EC2 环境作为工作区,您可以在本博客文章的其余部分使用 Cloud9 环境。

确保已安装 AWS CDK

$ cdk --version     

安装 OPA

$ curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64

$ chmod 755 ./opa

入门

创建 AWS CDK 项目

CDK 项目将创建 Amazon Elastic Compute Cloud (Amazon EC2) 实例、AWS Identity and Access Management (IAM) 角色、附加到 EC2 的安全组等的 AWS CloudFormation 堆栈。

将项目模板应用程序应用于 Python

$ mkdir cdk-demo
$ cd cdk-demo/
$ cdk init  --language python --app cdk-demo

安装 virtualenv

$ python3 -m venv .venv

输入 virtualenv

$ source .venv/bin/activate

安装所有必需的软件包

$ cat >requirements.txt <<EOF
aws-cdk.aws-ec2
aws-cdk.core
-e .
EOF

$ pip install -r requirements.txt

编辑 AWS CDK 项目以创建资源

cat >app.py <<EOF
#!/usr/bin/env python3

import os
from aws_cdk import core
from aws_cdk.core import Environment
from cdk_demo.cdk_demo_stack import CdkDemoStack

app = core.App()

ACCOUNT = app.node.try_get_context('account') or os.environ.get(
    'CDK_DEFAULT_ACCOUNT', 'unknown')
REGION = app.node.try_get_context('region') or os.environ.get(
    'CDK_DEFAULT_REGION', 'unknown')

AWS_ENV = Environment(region=REGION, account=ACCOUNT)

CdkDemoStack(app, "cdk-demo", env=AWS_ENV)

app.synth()
EOF



cat >cdk_demo/cdk_demo_stack.py <<EOF

from aws_cdk import core, aws_ec2


class CdkDemoStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        self.vpc = aws_ec2.Vpc.from_lookup(self, 'default_vpc', is_default=True)
        
        self.sg_ssh = aws_ec2.SecurityGroup(
            self,
            'ssh',
            vpc=self.vpc,
            description="Allow SSH from anywhere",
            security_group_name="SSH from anywhere"
        )
        self.sg_ssh.add_ingress_rule(aws_ec2.Peer.any_ipv4(), aws_ec2.Port.tcp(22))

        self.ami = aws_ec2.LookupMachineImage(
            name="ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*",
            owners=["099720109477"],
        )

        self.ec2 = aws_ec2.Instance(
            self,
            'cdk-demo',
            instance_type=aws_ec2.InstanceType('t2.micro'),
            machine_image=self.ami,
            vpc=self.vpc,
            security_group=self.sg_ssh,
        )
EOF

创建 AWS CloudFormation 模板

$ cdk synth

模板将生成为 cdk.out/cdk-demo.template.json。如果我们现在运行 cdk deploy,CloudFormation 堆栈将启动,并且将创建声明的所有资源。然而,应用更改前,让我们使用 OPA 进行验证,以确保没有违反安全性或操作策略。

在 Rego 中编写 OPA 策略

本示例中的策略将在三个方面检查 AWS CloudFormation 模板:

  • 它是否创建了超过 10 个 EC2 实例
  • EC2 实例上是否启用了 SSH
  • 是否创建了 IAM 角色
cat > opa_cdk.rego <<EOF

package opa_cdk

import input 

# deny if it creates more than 10 EC2 instances
deny_too_many_ec2[deny] {                             
    instances := [res | res:=input.Resources[_]; res.Type == "AWS::EC2::Instance"]   
    count(instances) > 10  
    deny := true
}

# deny if ssh is enabled
deny_ssh_enabled[deny] {                             
    input.Resources[_].Properties.SecurityGroupIngress[_].ToPort == 22
    deny := true
}

# deny if it creates IAM role
deny_role_created[deny] {                             
    input.Resources[_].Type == "AWS::IAM::Role"
    deny := true
}
EOF

评估 OPA 策略

对 AWS CloudFormation 模板运行 OPA 策略:

cd ..
./opa eval --format pretty -i cdk-demo/cdk.out/cdk-demo.template.json -d cdk-demo/opa_cdk.rego  "data"

对 AWS CloudFormation 模板运行 OPA 策略后输出

输出显示,CloudFormation 模板确实通过了要创建的 EC2 实例数量的检查,但违反了不创建 IAM 角色或不在 EC2 实例上启用 SSH 的策略。

在模板通过所有的策略测试前,不应该执行部署。OPA 帮助确保仅将基于策略的基础设施更改投入生产。

清理

从 AWS 控制台中删除 Cloud9 EC2 环境。

总结

上述示例是 hello world 演示,展示了使用 OPA 验证并确定提议的 AWS CDK 更新是否受到授权的方式。我认为此示例也可以应用于其他使用案例,例如确保所有资源在创建之前都有标记,确保遵循资源的命名标准,满足安全性或操作要求等等。

尽早了解应用程序或基础设施部署是否违反了策略定义很有用。因此,此策略评估应该是基础设施生命周期工作流程中的一个步骤,并将导致创建非合规资源的部署失败。

OPA 可以作为守护程序与您的服务并排运行,并通过 HTTP 使用 JSON 提供 RESTful API。对于使用 Go 编写的服务,OPA 可以嵌入并用作库。将 OPA 与 AWS CDK 结合使用可以高度扩展基础设施即代码,从而为基础设施策略测试提供自助服务功能和端到端自动化。

本博客文章提供了一个示例使用案例,您可以在您所在组织的环境中应用该使用案例。出于安全性、成本和可用性原因,您还希望在您的环境中实施很多其他策略。您可以从自己对访问控制及对容器化工作负载施加约束的要求开始,并且您可以将 OPA 与 AWS CDK 结合使用,以构建策略驱动型基础设施、实施约束、提供防护措施并有信心地管理云资源。

现在,您离 DevSecOps 又近了一步,您可以将 OPA 与您的 CDK、AWS CloudFormation 或 Terraform 支持的基础设施即代码管道集成,并利用 OPA 输出来自动使部署失败或通过。有了这些开源工具的强大功能,几乎可以提供无数种可能。

图片精选自 Pixabay