写点什么

使用 AWS Systems Manager 和 AWS Lambda 实现跨账户的共享服务调用

  • 2019-10-23
  • 本文字数:5858 字

    阅读完需:约 19 分钟

使用 AWS Systems Manager 和 AWS Lambda 实现跨账户的共享服务调用

多账号架构下的共享服务

在大型企业的云环境中,为了满足 IT 系统的合规性要求和安全性要求,通常需要采用多账户的架构以实现不同业务部门之间的资源隔离和权限控制。下图是一个常见的企业多账户架构,通常包含两类账户群:一类是中央共享服务账户群(桔色背景框),包含 AD 服务、日志服务、VPN 服务、跳板机等共享服务;另一类是业务应用账户群(蓝色背景框),通常情况下生产和非生产的资源会分别放置到不同的账户中。



图一 企业多账户架构示例


业务应用和共享服务的通信,通常可以通过以下两种方式实现:


(1)通过 VPC Peering 的方式打通共享服务所在的 VPC 和业务应用所在的 VPC 的网络连接,同时配合安全组进行网络流量的控制。目前 AWS 的中国区域可以支持这个方式,但需要注意 VPC Peering 会有连接数量的限制


(2)业务应用可以通过 Interface VPC Endpoint(基于 AWS PrivateLink 技术)访问到共享服务的 VPC,同时配合安全组进行网络流量的控制。目前(2018 年 5 月)AWS 中国区域尚不支持 Interface VPC Endpoints。


除了以上两种基于私有网络打通的方案之外,本文描述了某 AWS 客户在项目实施中设计的第三种跨账户共享服务访问方式:基于 API 的跨账户共享服务访问方式。

基于 API 的跨账户共享服务访问方式概述

在项目实施中,为了避免共享服务和业务应用的直接网络连通,实施团队设计了使用业务应用账户下的 Lambda 程序调用共享服务账户下 AWS Systems Manager 服务 API 的方式来完成共享服务的调用。


本文将以 EC2 服务器的 DNS 自动注册为例,展示跨账户共享服务调用的实现机理。如图二所示,当 Auto Scaling 组发生水平扩展时,新增的 EC2 实例经常需要执行一些定制的初始化工作,DNS 域名的注册就是其中的一个环节。Auto Scaling 的水平扩展由 CloudWatch Event 的规则捕捉后,会触发 Lambda 程序通过跨账户的 API 调用完成 DNS 的域名注册。



图二 方案架构


下面将为您介绍方案的实现细节。

共享服务的 API 化

本方案通过 AWS Systems Manager 实现了共享服务的 API 化,从而把基于私有网络的服务调用转变为基于公有网络的 AWS API 调用。


例如,为了实现在 AD 中执行 DNS 域名的注册,可以采用 AWS Manager 预设的 AWS-RunPowerShellScript Document,通过在 AD 所在的 Windows 操作系统中执行 PowerShell 的脚本的方式完成 DNS 域名的注册。



图三 Documents in AWS Systems Manager


以下 Python 代码片段通过调用 AWS Manager 的 SendCommand API,实现了 DNS 域名注册共享服务的调用:


Python


ssmCommand = client.send_command(    InstanceIds = [      '<instance-id>'    ],    DocumentName = 'AWS-RunPowerShellScript',    Parameters = {    'commands': [      'Add-DnsServerResourceRecordA -Name "<host-name>" -ZoneName "<zone-name>" -AllowUpdateAny -IPv4Address "<ip-address>" -TimeToLive 01:00:00'    ]    },  )
复制代码


具体 Python SDK 函数的参数可以参见文档

共享服务调用的触发

共享服务调用通常由 AWS 资源的状态变更触发。本项目的需求为,当 Auto Scaling 组根据 Scaling Policy 启动 EC2 实例时,需要完成一些运维的自动化操作,而这些操作可以通过 Lambda 程序调用相应的 AWS API 来完成。例如:


  • 通过 AWS Manager 实现的共享服务 API:参见上文描述。

  • 通过 EC2 API 实现 AWS 平台层面的操作:例如,修改 AWS EC2 实例的属性 。


这些自动化操作由 CloudWatch Event 的规则(rule)来触发。Rule Pattern 如下文所示:


Python


{  "source": [    "aws.autoscaling"  ],  "detail-type": [    "EC2 Instance Launch Successful"  ],  "detail": {    "AutoScalingGroupName": [      "my-asg-name"    ]  }}
复制代码


这个 CloudWatch Event 规则的设立可以通过 AWS 控制台的向导来完成。



图四 CloudWatch Event Rule 的设立


为实现配置过程的自动化,上述 CloudWatch Event 规则的设立也可以通过以下 CloudFormation 模板完成。

(1)设置触发条件和触发对象

Python


EventRule:   Type: "AWS::Events::Rule"  Properties:     Description: "EventRule"    EventPattern:       source:         - "aws.autoscaling"      detail-type:         - "EC2 Instance Launch Successful"      detail:         AutoScalingGroupName:           - "<asg-name>"    State: "ENABLED"    Targets:       -         Arn: <lambda-arn>        Id: "TargetFunction01"
复制代码


其中:


  • 是 Auto Scaling Group 的名字。

  • 是需要触发的 Lambda 程序的 ARN。

(2)设置调用权限,即赋予 CloudWatch Event 调用 Lambda 程序的权限

Python


PermissionForEventsToInvokeLambda:   Type: "AWS::Lambda::Permission"  Properties:     FunctionName: <lambda-arn>      Ref: "LambdaFunction"    Action: "lambda:InvokeFunction"    Principal: "events.amazonaws.com"    SourceArn: <event-rule-arn>
复制代码


其中,


  • 是 Lambda 程序的 ARN。

  • 是 CloudWatch Event 规则的 ARN

共享服务调用的权限配置

所有 AWS 的操作都需要授权才可以完成。跨账号的 API 调用的授权需要以下几个步骤。


(1)在共享服务账户下,创建角色(role),命名为 ssm-role-for-lambda。这个角色将被 Lambda 程序继承,用来获取执行 AWS Systems Manager 所需的权限。这个角色绑定的权限可采用以下 AWS Managed Policy。


Python


arn:aws-cn:iam::aws:policy/AmazonSSMFullAccess
复制代码


(2)在共享服务账户下,为第一步创建的 ssm-role-for-lambda 角色添加 Trusted Entity,从而允许业务账户中的 Lambda 程序继承这个角色。


Python


{  "Version": "2012-10-17",  "Statement": [   {     "Effect": "Allow",     "Principal": {       "AWS": "arn:aws-cn:iam::<app-account-id>:root"     },     "Action": "sts:AssumeRole"   }  ]}
复制代码


其中,是业务应用账户的 ID。


(3)在业务应用账户下,设置 Lambda 的执行权限,需包括以下权限,从而允许 Lambda 程序来继承 ssm-role-for-lambda 角色:


Python


{   "Sid": "VisualEditor0",   "Effect": "Allow",   "Action": "sts:AssumeRole",   "Resource": "arn:aws-cn:iam::<shared-service-account-id>:role/ssm-role-for-lambda"}
复制代码


其中,是共享服务账户的 ID。


(4)在业务应用账户下,Lambda 程序中通过 STS 服务的 AssumeRole API 继承这个角色。此 API 调用可以通过以下 Python 代码片段实现:


Python


lambda_sts_client = boto3.client('sts',    region_name="cn-north-1"    )response = lambda_sts_client.assume_role(    RoleArn="arn:aws-cn:iam::<share-service-account-id>:role/ssm-role-for-lambda",    RoleSessionName="remotessm"    )
复制代码


其中,是共享服务账户的 ID。


以上代码片段中的 response 变量将返回已继承 ssm-role-for-lambda 角色一套动态授权信息,具体包括:


  • AWS_ACCESS_KEY_ID

  • AWS_SECRET_ACCESS_KEY

  • AWS_SESSION_TOKEN


(5)在业务应用账户下,基于第四步获取的动态授权,Lambda 程序即可调用 AWS Systems Manager 的 API 完成共享服务的调用。例如,以下 Python 代码片段实现了调用 AWS Systems Manager 的 API 的 ssm_client 句柄的获取。


Python


ssm_session = boto3.Session(    aws_access_key_id=response['Credentials']['AccessKeyId'],aws_secret_access_key=response['Credentials']['SecretAccessKey'],    aws_session_token=response['Credentials']['SessionToken'],    region_name="cn-north-1"    )ssm_client = ssm_session.client('ssm')
复制代码

基于 API 的跨账户共享服务访问方式的优势

本文介绍了基于 AWS Systems Manager 和 Lambda 的跨账户共享服务访问方式。相比前文中提到的另外两种方式,本方案有以下优势:


  • 无需配置共享服务 VPC 和业务应用 VPC 的私有网络连接。对于没有 Private Link 功能的中国区域,避免了触及 VPC Peering 数量上限的风险。

  • 把需要客户自行实现的私有网络接口暴露、操作系统内程序执行权限管控等高风险功能,转化为 AWS 平台基于 IAM 服务的 API 访问控制,从而提高了系统的安全性。

  • 实现了共享服务的 API 化,为下一步的共享服务的标准化和自动化奠定基础。


作者介绍:


寇欣


亚马逊 AWS 中国区专业服务部咨询顾问。加入 AWS 之前,在 IT 和云计算行业积累了丰富的云服务架构和应用软件架构的经验。历任 Oracle 电信事业部专业服务部门资深顾问、中国移动研究院云计算研究员、Lucent Tech 研发中心系统架构师。


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/using-aws-systems-manager-and-aws-lambda-for-cross-account-shared-service-calls/


2019-10-23 08:00743

评论

发布
暂无评论
发现更多内容

Go- 方法-2

HelloBug

方法 Go 语言

美团面试:请手写一个快排,被我怼了

程序员 面试 算法

阿里P8终于总结出这份SpringBoot分布式架构精髓笔记

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

微信朋友圈架构设计

小智

架构实战营

不愧是阿里内部“SpringCloudAlibaba学习笔记”从头到尾,都是精华

Java 架构 面试 微服务

【LeetCode】二叉搜索树的最近公共祖先Java题解

Albert

算法 LeetCode 9月日更

🚄【Redis干货领域】从底层彻底吃透AOF原理(基础篇)

洛神灬殇

redis aof Redis 协议 9月日更

发布半小时登上GitHub首页的Spring Boot实战笔记,竟是京东T8编写

Java~~~

Java spring 架构 面试 Spring Boot

华为顶级网络工程师分享出这份TCP/IP网络编程笔记!已封神

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

逆袭!裸辞26天,历经4面,60w“跳”进鹅厂(附面试流程和真题)

Java~~~

Java 架构 面试 微服务 JVM

膜拜!清华大佬手撸多线程并发源码笔记Github上线3天星标35k+

Java~~~

Java 架构 面试 JVM 多线程

单链路性能测试实践

FunTester

性能测试 接口测试 测试框架 压力测试 全链路测试

Go- 方法-1

HelloBug

方法 Go 语言

GraphQl Calculator计算指令@distinct:使用表达式对列表进行去重

杜艮魁

数据中台 graphql

世界顶级安全专家整理出的这份笔记告诉你Linux应该怎么学

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

大厂慌了!由国外技术工程师亲自操刀的微服务实战手册限时分享

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

阿里P8纯手写SQL文档:收获不止SQL优化抓住SQL的本质

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

不愧是华为内部的“操作系统学习笔记”,一篇说细节,一篇讲哲学

Java~~~

Java 架构 面试 操作系统 网络

头一次见,阿里大牛把计算机网络协议讲得这么有趣,已火爆Github

Java~~~

Java 架构 面试 网络协议 计算机

Go- 结构体

HelloBug

Go 语言 结构体

微信朋友圈高性能架构设计

毛先生

世界顶级安全专家耗时三年写出了这份4308页的Linux笔记

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

仅靠七个步骤,4面通过拿offer,终“跳进”字节跳动

Java 程序员 架构 面试 计算机

Ubuntu Server 20.04 搭建安装Harbor

玏佾

Docker k8s Harbor

GitHub破百万访问的阿里神作:并发实现原理JDK源码笔记

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

大牛分享,献出这份年薪68W的蚂蚁金服Java高级开发封神宝典!

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

美团面试:说说MySQL存储引擎原理,幸好我准备过!

Java MySQL 程序员 面试 计算机

GitHub阅读量最高的文章竟是图解Java,不愧是Alibaba内部资料

Java~~~

Java 架构 面试 JVM 基础

软件工程师必备沟通技巧

俞凡

沟通 认知

链路性能测试中参数多样性方法分享

FunTester

性能测试 测试框架 全链路测试 FunTester 链路测试

GitHub标星翻倍!阿里大牛呕心沥血终成39w字Java面试笔记

Java~~~

Java 架构 面试 微服务 多线程

使用 AWS Systems Manager 和 AWS Lambda 实现跨账户的共享服务调用_语言 & 开发_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章