亚马逊AWS官方博客

使用 AWS CDK 结合 OPA 实现“策略即代码”

Original URL: https://aws.amazon.com/blogs/opensource/realize-policy-as-code-with-aws-cloud-development-kit-through-open-policy-agent/

 

AWS Cloud Development Kit(AWS CDK)是一个开源软件框架,允许使用熟悉的编程语言来定义和配置AWS上的基础设施。“基础设施即代码”通过使用CDK对基础设施进行版本控制,能够更有效且可靠地管理AWS上的基础设施。

当然,在计划部署新的AWS资源或更新时,我们必须确保这些更改没有引入安全漏洞,势必要建立安全合规基准,辅以流程遵循合规性要求。现在,是时候来设置和定义相应的安全基准,以确保AWS上基础设施的更改不会引起安全问题。开放策略代理(OPA)是一个云原生基金会的孵化项目,旨在针对云上基础设施的安全基准策略自动进行检查。OPA提供了统一的框架和语言,用于声明、实施和控制云上基础设施中各个部件的安全基准策略。

将OPA与AWS CDK集成在一起之后,可获得“策略即代码”的能力,即在AWS CDK对AWS环境进行更改之前,对这些更改进行合规策略的检查。这种新方法带来很多好处,具体包括:

  • 各个团队成员可以轻松在实际更改之前进行策略检查。
  • 通过与CI / CD集成,可以自动执行策略检查。
  • 用户可以对“基础设施即代码”实施强制性检查。
  • 用户可以根据行业最佳实践框架(例如CIS AWS Benchmark)中的安全合规要求,编写自定义的OPA策略。

总而言之,这将极大地缩短基础设施安全合规的事后检查周期。

这篇文章的其余部分将逐步介绍如何将OPA与AWS CDK结合使用,以实现“策略即代码”。这将涉及以下的任务:

  • 创建一个AWS CDK项目以部署AWS资源。
  • 根据REGO策略语言编写简单的OPA策略。
  • 利用OPA策略来检查AWS CDK的基础设施代码。

先决条件

1.1 在AWS Cloud9中创建EC2环境

按照说明创建一个Amazon Linux Cloud9 EC2环境(自建EC2实例亦OK)。

1.2 确保已安装AWS CDK

$ cdk --version

1.3 安装OPA

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

入门

2.1 创建一个AWS CDK项目

AWS CDK项目将创建一个AWS CloudFormation堆栈,其中包括:一个Amazon Elastic Compute Cloud(Amazon EC2)实例,一个AWS Identity and Access Management(IAM)角色,一个附加到EC2的安全组。

2.2 使用Python语言的CDK Demo应用模板

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

2.3 安装virtualenv

$ python3 -m venv .venv

2.4 进入virtualenv

$ source .venv/bin/activate

2.5 安装所有必需的软件包

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

$ pip install -r requirements.txt

2.6 编辑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

2.7 创建AWS CloudFormation模板

$ cdk synth

这将生成cdk.out/cdk-demo.template.json。如果我们现在运动cdk deploy,将启动CloudFormation堆栈,并创建所有声明的资源。但是,在更改发生之前,我们需要使用OPA进行策略检查,以确保更改没有违反安全合规基准。

2.8 使用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

2.9 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"

该命令的输出显示,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与AWS CDK,AWS CloudFormation或Terraform所支撑的“基础设施即代码”流水线集成在一起,并利用OPA的检查结果,自动使部署失败或通过。显然,借助这些工具的功能,极大地扩充了DevSecOps的实践空间。正应了一句话:凡事皆有可能!

 

本篇作者

Xuejiao Zhang

Xuejiao Zhang is a DevOps Consultant at Amazon Web Services. Prior to joining Amazon. Xuejiao worked for a number of e-commerce companies like JD.COM, Rakuten. You can find her on Github.

本篇译者

黄帅

亚马逊 AWS 专业服务团队云架构咨询顾问。负责企业级客户的云架构设计和优化、DevOps 组织咨询和技术实施。在软件研发领域有多年架构设计和运维、团队管理经验,对 DevOps、云原生微服务治理框架、容器化平台运维、混沌工程实践等有深入的研究和热情。