使用资源目录管理操作旗下账户的概念验证CLI

本文涉及的产品
轻量应用服务器 2vCPU 4GiB,适用于网站搭建
轻量应用服务器 2vCPU 4GiB,适用于搭建Web应用/小程序
轻量应用服务器 2vCPU 4GiB,适用于搭建容器环境
简介: 在多账号云环境中,通过资源目录与角色扮演实现跨账号资源控制是一种常见架构。本文介绍如何使用阿里云CLI通过临时凭证实现主账号、成员账号间的角色切换,并操作目标账号资源。同时提供Python代码示例,演示如何通过STS获取临时凭证并访问ECS资源,适用于企业多账号统一管理和运维场景。

我们一般情况下会把运维账号和业务账号分开,然而又不太可能在每个账号下建立RAM账号管理。而是使用资源目录把各个账号都邀请进来,然后利用角色扮演的方式实现控制对应账号下的资源。作为概念验证,我是直接使用CLI来实现,而不是通过写代码SDK接口实现。下面我先分享3个使用临时凭证的卓越架构:

通过FC函数角色实现临时凭证的获取和使用
通过ECS实例角色实现临时凭证的获取和使用
通过容器服务RRSA实现临时凭证的获取和使用

Landing Zone通常包含资源规划、财务管理、网络规划、安全防护、合规审计、身份权限、运维管理、自动化。而账号的管理在Landing Zone中通常占据非常重要的地位,通过资源目录以及账号中的角色扮演的方式实现跨账号跨BU统一运维控制。

主页:https://www.aliyun.com/landing-zone?spm=a2c4g.29094516.0.0.7a1361df6y7mRA

企业多账号统一架构方案
Light Landing Zone
企业级DMZ上云方案
多账号网络安全统一防护方案
多主体集团账号统一财务管理方案
多账号操作日志统一归集与审计
通过配置审计和函数计算实现云主机风险巡检

通过主账号授权

通过管理账号的RAM用户扮演成员RAM角色的方式登录阿里云控制台

这个文档实际上是直接使用主账号(资源目录的管理账号)AK/SK来实现角色扮演。下面我们多出一步,是先由资源目录下B账号扮演为管理账号,然后再去扮演C账号去操作资源。这其实不是最佳实践,因为在资源目录里面,CloudAdmin(管理账号)是具有最大权限。只不过我们作为概念验证的步骤,先行使用最大权限来验证,需要最佳实践的可以略过本章节。

我们资源目录下账号B,想要获得资源目录下账号C的权限可以通过先角色扮演为主账号A,然后再扮演C。

A账号UID: A0001
B账号UID: B0002
C账号UID: C0003

  1. 首先先在主账号创建角色,角色允许另一云账号(UID:B0002)操作,并授权这个角色以下权限:AliyunSTSAssumeRoleAccess,AliyunResourceDirectoryFullAccess。

  2. 复制好这个角色的ARN路径,例如:acs:ram::A0001:role/rd-allow-assume-root-from-B0002

  3. 在运维部署账号B中创建RAM用户并保存AccessKey ID和AccessKey Secret。

  4. 使用CLI概念验证:

    aliyun configure --mode AK --profile AccountB
    aliyun sts AssumeRole --region cn-beijing --DurationSeconds 3600 --RoleArn acs:ram::A0001:role/rd-allow-assume-root-from-B0002 --RoleSessionName alice
    

RoleSessionName是用于审计,你叫什么都可以。
RoleArn就是填写之前我们在主账号创建角色的ARN。 这个授权是让B账户获取资源目录全部权限,也就是允许资源目录下成员扮演管理账号。 acs:ram::<对应的UID>:role/rd-allow-assume-root-from-B0002
DurationSeconds就说最长有效期多少秒,实际测试最多只能填3600(1小时)。

输出如下:

{
   
        "AssumedRoleUser": {
   
                "Arn": "acs:ram::A0001:role/rd-allow-assume-root-from-B0002",
                "AssumedRoleId": "1111111111111111:alice"
        },
        "Credentials": {
   
                "AccessKeyId": "STS.f1Aap4ykmxWkQLt7rsb6kZId3",
                "AccessKeySecret": "lyQBUVVwySDFxd6eUAYF66GGlC1QWpvvlXpl8zfXgJi",
                "Expiration": "2025-03-12T07:32:26Z",
                "SecurityToken": "YE1pddbiSFxk436EEgW5lv0rXpUefySwpyiy0HgpJsCcW1bw41JaVFWxFo1EPILJEb6VvbTcd7auetIKho1piiFVJrqDLc24Cwez16I387VW8WeSe7FUocMGvTC32Sjwa3hQ4zDM4hMad4I6pzRiwKaED9llQqK9slrbc9BBU3JirRj0ykvZp9A5XewKAYqXplY7piYGEHKkI5VXQpaDZU1ohGcRYyYSzWCxDZGbHsGaZIE5y5wDDrBz8AJ5uWFLoprVYAWW2bpaEOzEEhG1yYzBBH4zyhA346fgJ3d1fERiwKkDLaxvgFUoumuHdVzvJhhKE9PfsLZoPQdUBuiVfXwxhyzgjbBoucrYdeLhZTURk75xtaaZmsAU0qAyyMuQiDEyt9DRmJqaOKKvDuZRYyOfD6D3fpYomlgxPWXZ15sHpuiEwpYmxiifZs0rPeFpampl1tbui6XVMvh733gWLEutHAZ4Tpz70zxsSewyZfYRMiwoIWV82kbSyrpPdmOoS7oO8eOSzSZYbMF4WvsrvA15PFRDbFhHd3vBSS6Pjzkd63hKZAmc4Z5IWTFTxrxp9ipQSLqbilTfIhkCX7MTHpCoLi0d8rYwDDVzx21t0RlVzAjBs3pKK2hd51qz"
        },
        "RequestId": "5aa57662-4faa-4d9e-ba32-e9726c715660"
}
  1. 然后我们使用aliyun configure --mode StsToken --profile assume-root-from-B0002将AK/SK和Token保存。

  2. 这时候我们已经在主账号下了,但是我们只有角色扮演和查看资源目录权限,其实是看不到主账号下的内容的。我们接着扮演角色到子账号C上。
    因为是主账号,本身加入资源目录的时候已经自动加了角色(resourcedirectoryaccountaccessrole),允许主账号操作。所以接下来我们:

    aliyun sts AssumeRole --region cn-beijing --DurationSeconds 3600 --RoleSessionName alice --RoleArn acs:ram::C0003:role/resourcedirectoryaccountaccessrole
    

    然后再继续记录AK/SK和Token,并使用这STS AK密钥方式来登录CLI(也就是实现了扮演角色)。这个时候,你就已经可以DescribeInstances来操作账号C的资源了。
    使用主账号授权的好处是,只要你知道资源目录下UID,就能直接控制。

授权资源目录下B账号操作C或D账号

但是有没有可能我完全不希望主账号创建角色,而是在C账号,D账号等其他资源目录账号创建角色并授权B账号查看或者操作呢?

我们先忽略掉如何批量给资源目录下的账号创建角色问题,直接B-->C同样也是可行的。不过授权角色上,不同于管理账号授权,我们只需要授权想让B账号看到什么或者操作什么即可,比如ECS Full Access。
我们只需要在对应账号创建角色,并授权允许对应的权限即可。

acs:ram::UIDC0003:role/allow-access-from-B0002

aliyun sts AssumeRole --region cn-beijing --DurationSeconds 3600 --RoleArn acs:ram::UIDC0003:role/allow-access-from-B0002 --RoleSessionName alice

获得AK/SK和STS Token后,我们就能扮演C账号来管理了。

Python 角色扮演概念验证

将从B账号扮演C账号,然后列出C账号ECS资源。

# -*- coding: utf-8 -*-
# This file is auto-generated, don't edit it. Thanks.
import os
import sys

from typing import List

from alibabacloud_sts20150401.client import Client as Sts20150401Client
from alibabacloud_ecs20140526.client import Client as Ecs20140526Client

from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_sts20150401 import models as sts_20150401_models
from alibabacloud_ecs20140526 import models as ecs_20140526_models
from alibabacloud_tea_util import models as util_models
from alibabacloud_tea_util.client import Client as UtilClient
from alibabacloud_credentials.client import Client as CredClient
from alibabacloud_tea_rpc.models import Config


class Sample:
    def __init__(self):
        pass

    @staticmethod
    def create_sts_client() -> Sts20150401Client:
        """
        使用AK&SK初始化STS Client
        @return: Sts20150401Client
        """
        config = open_api_models.Config(
            access_key_id='AAAAAAAAA',
            access_key_secret='BBBBBBBBBBBBB'
        )
        # STS Endpoint 请参考 https://api.aliyun.com/product/Sts
        config.endpoint = f'sts.cn-beijing.aliyuncs.com'
        return Sts20150401Client(config)

    @staticmethod
    def create_ecs_client(access_key_id: str, access_key_secret: str, security_token: str) -> Ecs20140526Client:
        """
        使用临时凭证初始化ECS Client
        @param access_key_id: 临时 AccessKey ID
        @param access_key_secret: 临时 AccessKey Secret
        @param security_token: STS Token
        @return: Ecs20140526Client
        """
        config = open_api_models.Config(
            access_key_id=access_key_id,
            access_key_secret=access_key_secret,
            security_token=security_token
        )
        # ECS Endpoint 请参考 https://api.aliyun.com/product/Ecs
        config.endpoint = f'ecs.cn-beijing.aliyuncs.com'
        return Ecs20140526Client(config)

    @staticmethod
    def assume_role(client: Sts20150401Client) -> dict:
        """
        调用 AssumeRole 获取临时凭证
        @param client: Sts20150401Client
        @return: 包含临时凭证的字典
        """
        request = sts_20150401_models.AssumeRoleRequest(
            role_arn='acs:ram::UIDC0003:role/allow-from-B0002',  # 替换为你的角色 ARN
            role_session_name='alice'  # 替换为你的会话名称
        )
        runtime = util_models.RuntimeOptions()
        response = client.assume_role_with_options(request, runtime)
        credentials = response.body.credentials

        sts_result = {
   
            'AccessKeyId': credentials.access_key_id,
            'AccessKeySecret': credentials.access_key_secret,
            'SecurityToken': credentials.security_token
        }

        print("Temporary Credentials:", sts_result)  # 添加的调试打印语句

        return sts_result

    @staticmethod
    def describe_ecs_instances(client: Ecs20140526Client) -> List[dict]:
        """
        查询 ECS 实例信息
        @param client: Ecs20140526Client
        @return: ECS 实例列表
        """
        request = ecs_20140526_models.DescribeInstancesRequest(
            region_id='cn-beijing'
        )
        runtime = util_models.RuntimeOptions()
        response = client.describe_instances_with_options(request, runtime)
        instances = []
        for instance in response.body.instances.instance:
            private_ip = instance.vpc_attributes.private_ip_address.ip_address[
                0] if instance.vpc_attributes and instance.vpc_attributes.private_ip_address.ip_address else "N/A"
            instances.append({
   
                'InstanceId': instance.instance_id,
                'InstanceName': instance.instance_name,
                'PrivateIP': private_ip,
                'Status': instance.status
            })
        return instances

def main():
    try:
        # 初始化 STS 客户端
        sts_client = Sample.create_sts_client()

        # 获取临时凭证
        credentials = Sample.assume_role(sts_client)

        # 使用临时凭证初始化 ECS 客户端
        ecs_client = Sample.create_ecs_client(
            access_key_id=credentials['AccessKeyId'],
            access_key_secret=credentials['AccessKeySecret'],
            security_token=credentials['SecurityToken']
        )

        # 查询 ECS 实例信息
        instances = Sample.describe_ecs_instances(ecs_client)

        # 打印 ECS 实例信息
        print("ECS Instances:")
        for instance in instances:
            print(f"Instance ID: {instance['InstanceId']}")
            print(f"Instance Name: {instance['InstanceName']}")
            print(f"Private IP: {instance['PrivateIP']}")
            print(f"Status: {instance['Status']}")
            print("-" * 40)

    except Exception as e:
        print(f"Error: {e}")


if __name__ == '__main__':
    main()
相关文章
|
3月前
|
人工智能 运维 NoSQL
机器一宕机就靠“拍脑袋”?试试知识图谱,排故快准狠!
机器一宕机就靠“拍脑袋”?试试知识图谱,排故快准狠!
232 8
|
4月前
|
存储 监控 NoSQL
在阿里云上构建高性能PHP应用:最佳实践指南
本文档从四个核心方面阐述了系统设计与优化的全面方案:**架构设计原则**包括分层架构(Web/逻辑/数据分离)与无状态设计(Redis会话存储、OSS文件管理);**核心服务选型**推荐高性价比的ECS、高性能Redis企业版及PolarDB数据库等;**性能优化技巧**涵盖代码层面(OPcache、Swoole框架)、数据库优化(复合索引、分库分表)以及进阶容器化和函数计算策略;**监控体系搭建**则通过云监控、ARMS应用监控、日志服务SLS等工具,确保系统稳定高效运行。
136 10
|
4月前
|
人工智能 运维 网络协议
别只盯着ChatGPT!大模型也能帮你抓网络“鬼”
别只盯着ChatGPT!大模型也能帮你抓网络“鬼”
174 4
|
3月前
|
网络安全 API CDN
如何将Cloudflare HTTPS的SSL证书更换为Google签发的
将Cloudflare HTTPS的SSL证书更换为Google签发的
|
3月前
|
开发工具 Python
使用Python和OpenAPI将云上的安全组规则填写入Excel
本文介绍如何通过Python脚本自动化获取阿里云安全组及其规则信息,并将结果导出为Excel表格。相比CLI命令行方式,Python实现更高效、便捷,适用于需要批量处理和交付的场景。
使用Python和OpenAPI将云上的安全组规则填写入Excel
|
3月前
|
虚拟化 数据安全/隐私保护
VMware ESXi 密码复杂度修改
VMware ESXi 密码复杂度修改
|
11月前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js:从零开始构建后端服务
【10月更文挑战第42天】在数字时代的浪潮中,掌握一门后端技术对于开发者来说至关重要。Node.js,作为一种基于Chrome V8引擎的JavaScript运行环境,允许开发者使用JavaScript编写服务器端代码,极大地拓宽了前端开发者的技能边界。本文将从Node.js的基础概念讲起,逐步引导读者理解其事件驱动、非阻塞I/O模型的核心原理,并指导如何在实战中应用这些知识构建高效、可扩展的后端服务。通过深入浅出的方式,我们将一起探索Node.js的魅力和潜力,解锁更多可能。
|
4月前
|
存储 安全 Java
Java 基础篇必背综合知识点全面总结
本文总结了Java基础篇的核心知识点,涵盖Java特性、JDK与JRE、数据类型与运算符、流程控制语句、面向对象编程(类与对象、封装、继承、多态)、常用类库(java.lang、java.util、java.io)等内容。同时,还介绍了字符串处理、Servlet隐式对象及请求转发与重定向等重要概念。通过学习这些基础知识,可为深入掌握Java高级特性和实际开发打下坚实基础。代码资源可从[链接](https://pan.quark.cn/s/14fcf913bae6)获取。
190 0
|
12月前
|
云安全 监控 安全
出海合规云安全,AWS Landing Zone解决方案建立安全着陆区
出海合规云安全,AWS Landing Zone解决方案建立安全着陆区
|
8月前
|
人工智能 自然语言处理 Java
Spring 集成 DeepSeek 的 3大方法(史上最全)
DeepSeek 的 API 接口和 OpenAI 是兼容的。我们可以自定义 http client,按照 OpenAI 的rest 接口格式,去访问 DeepSeek。自定义 Client 集成DeepSeek ,可以通过以下步骤实现。步骤 1:准备工作访问 DeepSeek 的开发者平台,注册并获取 API 密钥。DeepSeek 提供了与 OpenAI 兼容的 API 端点(例如),确保你已获取正确的 API 地址。
Spring 集成 DeepSeek 的 3大方法(史上最全)