企业多账号场景下订阅特定资源配置变更
方案概述
当企业有多个云账号,不同账号内会有许多不同的云资源。企业内部安全合规团队如果想重点关注某些特定规则的资源变更情况。比如只关注特定全名规则的RAM角色是否发生了修改,并且希望把这份修改事件投递到企业内部的管理系统用于后续审计分析。
本文档介绍了一种通过配置审计(Config)结合事件总线(EventBridge)和函数计算为企业提供一种实现方案,文中会以特定的一个场景来演示操作步骤。客户可以参考相关配置来适配自身的业务需求。
方案优势
集中式配置
通过资源目录和配置审计集成的能力,可以完成多账号资源的集中配置。
灵活配置过滤规则
基于云原生产品能力,客户无需额外做过多的代码开发,即可实现对不同账号内资源的灵活过滤。相比于自定义处理配置审计投递到消息系统程序来讲,这种方式维护成本更低。
可扩展处理变更事件
使用函数计算处理事件总线中的变更事件,客户可以自行修改函数计算中的程序逻辑,实现可扩展。
客户场景
订阅特定资源变更事件
场景描述
企业内部的安全合规要求,对特定资源变更需要重点关注,将事件投递到内部系统,并形成事件审计分析。
适用客户
使用资源目录管理云上多个账号的企业客户。
对资源变更比较关注的企业客户。
存在中心运维团队、审计团队的企业客户。
方案架构
架构说明
通过资源目录将企业多个云账号统一纳管,建立账号树。
通过Config委派管理员的方式,开通多账号的配置审计。
在单个成员账号中配置事件总线,选择事件投递目标为“日志账号”,事件模式选择特定的过滤规则。
在“日志账号”内配置事件总线,将对应的事件投递到函数计算;函数计算解析相应的事件对象,并保存入库。
在本方案中提供函数计算里面的代码为Python3.X。
产品费用及名词
产品费用
产品名称 | 产品说明 | 产品费用 |
资源目录RD | 资源目录RD(Resource Directory)是阿里云面向企业客户提供的一套多级账号和资源关系管理服务。 | 免费,详情参见产品定价。 |
配置审计Config | 配置审计(CloudConfig)是阿里云上的配置管理和IT治理服务。将您分散在各地域的资源整合为全局资源列表,您可以便捷地搜索全局资源。同时帮助您记录云上IT资源的配置变更历史,允许您将全量资源配置和配置历史文件持续收集到指定的存储空间。同时持续自动地评估云上资源配置的合规性,实现云上IT合规治理。 | 配置审计公测期间所有阿里云有效账号均可免费使用。但具体涉及到其他服务,详情计费参考链接 |
事件总线 EventBridge | 事件总线EventBridge是阿里云提供的一款无服务器事件总线服务,能够以标准化的CloudEvents 1.0协议在应用之间路由事件,帮助您轻松构建松耦合、分布式的事件驱动架构。 | 公测期间产品免费。 |
函数计算 | 阿里云函数计算是事件驱动的全托管计算服务。通过函数计算,您无需管理服务器等基础设施,只需编写代码并上传。函数计算会为您准备好计算资源,以弹性、可靠的方式运行您的代码,并提供日志查询、性能监控、报警等功能。 | 收费,详情参见计费概述。 |
名词解释
名称 | 说明 |
企业管理主账号 | 在企业拥有多个阿里云账号时,特指拥有管理其他账号资源权限的管理员账号。用于管理多账号,统一配置多账号身份权限,统一查看各云账号账单,统一配置审计规则并下发到各成员账号。 |
CloudEvents 1.0 | 用标准方式描述事件数据的开源规范,旨在简化事件声明以及跨服务、跨平台的消息投递。 |
事件模式 | 对事件进行过滤的模块。事件模式支持对CloudEvents包含data在内的所有字段进行过滤。 |
事件目标 | 事件的处理终端,负责消费事件。 |
安全性
跨账号路由事件
同组织或关联组织下不同的阿里云账号通常需要进行事件互通,事件总线EventBridge提供跨账号路由事件的能力,您可以将多个账号的事件路由到一个账号中统一处理。授权说明及操作详情参见跨账号路由事件。
成员账号配置事件总线权限
事件总线EventBridge的权限管理是通过阿里云的访问控制RAM(Resource Access Management)产品实现的。使用RAM可以让您避免与其他用户共享云账号密钥,即AccessKey(包含AccessKey ID和AccessKey Secret),按需为用户分配最小权限。此方案中授权配置如下:
权限策略名称 | 说明 |
AliyunEventBridgeFullAccess | 事件总线EventBridge的管理权限,等同于阿里云账号的权限,被授予该权限的RAM用户可执行发布事件和控制台所有操作。 |
日志账号操作权限
日志账号里面需要配置事件总线、函数计算。参照按需为用户分配最小权限。此方案中授权配置如下:
权限策略名称 | 说明 |
AliyunEventBridgeFullAccess | 事件总线EventBridge的管理权限,等同于阿里云账号的权限,被授予该权限的RAM用户可执行发布事件和控制台所有操作。 |
AliyunFcDefaultRole | 用于FC服务角色的授权策略。 |
代码中的敏感数据
本方案中用到了RDS数据库,对于数据库连接所需要用到的账号、密码等敏感数据建议不要硬编码在代码中。而是推荐放在函数计算的环境变量里面。
注意事项
支持配置审计的云服务
阿里云配置审计服务已支持一系列核心基础设施,例如:云服务器ECS、 云数据库RDS、对象存储OSS、专有网络VPC、负载均衡和容器服务Kubernetes版等。在此基础上,配置审计也在不断扩展对其他云服务的支持。更多信息,请参见支持配置审计的云服务。
变更事件时延
用户修改特定的云资源,到事件触发到函数计算进行处理。这个过程时延大概在5~8分钟。
实施步骤
实施准备
确保已在「企业管理账号」中开通资源目录,并且将其他账号邀请到资源目录中。具体操作,请参见Landing Zone搭建概述。
确保已在「企业管理账号」中开启多账号的配置审计功能。具体操作,请参见云治理中心-统一配置防护规则。
确保在各个成员账号中开通事件总线。具体操作,请参见开通事件总线。
确保在「日志账号」中开通事件总线及函数计算、开通日志服务、配置相应的VPC网络及安全组用于配置数据库及函数计算资源。创建相应的数据库,相应的数据表及授权。具体操作,请参见开通事件总线。
实施场景
某客户多账号架构如下:
在业务账号B里面有如下几个Ram角色:
客户只关注以sg前缀的Ram角色对应的变更(包括修改、创建、删除),其他角色的变更不需要订阅。相关角色修改触发的变更事件在数据库中记录,如下图所示:
数据规划
本文以订阅特定规则RAM角色变更事件,为您介绍通过配置审计结合事件总线,函数计算实现过滤特定规则的变更事件。相关数据规划如下表:
云服务 | 参数 | 示例 |
配置审计 | 账号组 | configgroup |
事件总线 | 规则名称 | eb-filter-ram-role |
函数计算 | 服务 | eb_event_action |
服务的系统模板权限 | AliyunFCDefaultRolePolicy | |
函数 | eb_event_trigger | |
触发器 | ConfigurationItemChangeTrigger |
注意:由于配置审计部署在华东2(上海),为了减少网络损耗,建议事件总线及函数计算选择华东2(上海)。
操作流程
通过配置审计将账号内资源变更事件投递到事件总线,触发函数计算完成对事件内容处理过滤,并完成数据入库完整的操作流程如下图所示:
操作步骤
本操作步骤中提到的账号均以上面「某客户多账号架构」为指引。
登录日志账号A,新建一个RAM角色支持事件总线跨账号路由。角色名称:b-account-eb-role
具体操作,请参见 跨云账号路由事件。
登录业务账号B,配置事件总线:
登录事件总线控制台。
在左侧导航栏,单击事件总线。
在顶部菜单栏,选择地域,例如:华东2(上海)。
选择 default 进入这个默认事件配置页。
在 事件规则 页面,单击 创建规则。
在创建规则页面,完成以下操作。
在配置基本信息配置向导,在名称文本框输入规则名称(eb-filter-ram-role),在描述文本框输入规则的描述,然后单击下一步。
在配置事件模式配置向导,事件源类型选择阿里云官方事件源,事件源选择acs.ram 访问控制,事件类型选择ram:Config:ConfigurationItemChangeNotification 访问控制配置变更通知,在事件模式内容代码框输入事件模式如下,然后点下一步。
{ "source": [ "acs.ram" ], "data": { "resourceName": [ { "prefix": "sg-" } ] }, "type": [ "ram:Config:ConfigurationItemChangeNotification" ] }
在配置事件目标配置向导,配置以下参数,然后单击创建。
服务类型:单击事件总线。
目标账户类型:默认选择其他阿里云账号。
账号ID:输入接收账号的ID。在本场景中配置「日志账号UID」。
总线名称:输入default。
角色名称:输入 「b-account-eb-role」。
事件:默认选择完整事件,不做转换,直接投递原生CloudEvents 1.0协议中的完整结构。
登录日志账号A,配置函数计算:
新建服务。
登录函数计算控制台。
在左侧导航栏,单击服务及函数。
在顶部菜单栏,选择地域,例如:华东2(上海)。
在服务列表页面,单击创建服务。
在创建服务面板,名称输入eb_event_action。
单击确定。
新建函数。
在服务eb_event_action的左侧导航栏,单击函数管理。
单击创建函数。
在创建函数页面,名称输入eb_event_trigger,运行环境选择Python 3,配置函数触发器选择EventBridge触发器->访问控制,其中触发器名称ConfigurationItemChangeTrigger,事件类型选择「选中全部事件类型」,其他参数保持默认值。
单击创建。
配置函数的环境变量。
在函数eb_event_trigger的函数代码页签,单击函数配置页签。
在环境变量区域,单击编辑。
单击添加变量,输入该环境变量的变量名称和变量值。
变量MYSQL_ENDPOING,值为RDS内网地址。
变量MYSQL_PORT,值为RDS数据库端口。
变量MYSQL_USER,值为数据库用户名称。
变量MYSQL_PASSWORD,值为数据库用户密码。
变量MYSQL_DBNAME,值为数据库名称。
单击保存。
配置函数实例生命周期回调方法
在函数管理页面,单击目标函数操作列的配置。
在编辑函数配置页面的实例生命周期回调区域,设置回调程序与超时时间,然后单击保存。
本示例中的配置如下截图:
函数代码
在函数eb_event_trigger的触发器管理页签,单击函数代码页签。
单击文件index.py。
拷贝并粘贴如下代码至文件index.py。
import pymysql import json,logging import os connection = None logger = logging.getLogger() def initialize(context): global connection try: connection = pymysql.connect( host=os.environ['MYSQL_ENDPOING'], # 替换为您的HOST名称。 port=int(os.environ['MYSQL_PORT']), # 替换为您的端口号。 user=os.environ['MYSQL_USER'], # 替换为您的用户名。 passwd=os.environ['MYSQL_PASSWORD'], # 替换为您的用户名对应的密码。 db=os.environ['MYSQL_DBNAME'], # 替换为您的数据库名称。 connect_timeout=5) logger.info('eb job connect mysql success!!!') except Exception as e: logger.error( "ERROR: Unexpected error: Could not connect to MySql instance.") raise Exception(str(e)) def pre_stop(context): if connection != None: connection.close() def save_transactional(sql, params): try: cursor=connection.cursor() cursor.execute(sql , params) connection.commit() except Exception as e: logger.error(e) def handler(event, context): eb = json.loads(event).get("data") eb_action,eb_time,resource_name,req_id = eb.get("resourceEventType"),eb.get("captureTime"),eb.get("resourceName"),eb.get("requestId") account_id, region, config_diff, resourse_type = eb.get("accountId"),eb.get("regionId"),eb.get("configurationDiff"),eb.get("resourceType") logger.info(eb_action+eb_time+resource_name+req_id+account_id+region+config_diff+resourse_type) change_sql = "insert into event_list(req_id,type,time,resource,account,region,configdiff,resourcetype) values(%s,%s,%s,%s,%s,%s,%s,%s)" params = (req_id,eb_action,eb_time,resource_name,account_id, region, config_diff, resourse_type) save_transactional(change_sql, params) return 'success'
说明:本段代码是以处理RAM Role资源变更为例,为您介绍对于此类资源变更如何保存到数据库。对于其他资源类型的变更可以在这个方案基础上稍作修改。
以上代码示例中提到的表「event_list」结构如下:
CREATE TABLE `event_list` ( `req_id` varchar(255) NOT NULL, `type` varchar(255) DEFAULT NULL, `time` varchar(255) DEFAULT NULL, `resource` varchar(255) DEFAULT NULL, `account` varchar(255) DEFAULT NULL, `region` varchar(255) DEFAULT NULL, `configdiff` text, `resourcetype` varchar(255) DEFAULT NULL, PRIMARY KEY (`req_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
登录业务账号B,对Ram角色进行变更。
增加一个新的Role角色。名称:sg-100。
修改一个现有的Role角色,名称:sg-001。
删除一个现有的Role角色,名称:sg-001。
登录日志账号A,查看事件追踪
通过事件总线控制台查看事件追踪
通过函数计算控制台查看调用日志
故障排除
为什么业务账号内的资源变更了但事件追踪查不到?
从业务账号内资源变更到配置审计,再投递到事件总线,这个过程大概会有5~8分钟的时延。可以稍微等几分钟再去查询事件追踪。
函数计算中的程序无法访问后端数据库?
确认当前函数计算是否有配置网络选项,需要确保函数计算所在的网络环境跟RDS在同一个VPC内。