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

本文涉及的产品
轻量应用服务器 2vCPU 4GiB,适用于网站搭建
轻量应用服务器 2vCPU 4GiB,适用于搭建Web应用/小程序
轻量应用服务器 2vCPU 1GiB,适用于搭建电商独立站
简介: 在多账号云环境中,通过资源目录与角色扮演实现跨账号资源控制是一种常见架构。本文介绍如何使用阿里云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()
相关文章
|
10天前
|
人工智能 运维 NoSQL
机器一宕机就靠“拍脑袋”?试试知识图谱,排故快准狠!
机器一宕机就靠“拍脑袋”?试试知识图谱,排故快准狠!
62 8
|
14天前
|
开发工具 Python
使用Python和OpenAPI将云上的安全组规则填写入Excel
本文介绍如何通过Python脚本自动化获取阿里云安全组及其规则信息,并将结果导出为Excel表格。相比CLI命令行方式,Python实现更高效、便捷,适用于需要批量处理和交付的场景。
使用Python和OpenAPI将云上的安全组规则填写入Excel
|
13天前
|
网络协议 Ubuntu Linux
Wireguard in Linux的安装方法
本文介绍了如何在Ubuntu和Rocky Linux中安装配置WireGuard,并探讨了配置过程中可能出现的DNS泄露问题及解决方法,包括通过nmtui设置DNS及调整DNS优先级参数。
|
安全 API 开发工具
阿里云如何开通子账号
阿里云如何开通子账号
6966 1
|
6天前
|
开发工具 Docker Windows
OpenWrt 通过Docker单独打包passwall ipk
OpenWrt 通过Docker单独打包passwall ipk
|
6天前
|
Prometheus 监控 Cloud Native
Grafana完整教程
本文介绍了Grafana与Prometheus的安装与配置流程,涵盖源配置、端口设置、服务端与客户端安装、Node Exporter部署及自启动设置,同时提供多服务器监控方案与推荐Dashboard。
Grafana完整教程
|
7天前
|
应用服务中间件 Linux 网络安全
使用Nginx免费版与Keepalived实现高可用性High Availablity方案
本文介绍了如何使用Nginx免费版与Keepalived实现高可用性(HA)方案,涵盖环境搭建、Keepalived安装配置、版本升级及主从模式设置。通过虚拟机测试,结合CentOS与宝塔,详细说明VIP配置与服务启动流程,助你构建稳定可靠的Web高可用架构。
|
6天前
|
Ubuntu Docker 容器
Ubuntu国内镜像Docker安装详细教程
Ubuntu国内镜像Docker安装详细教程
|
6天前
|
Kubernetes 负载均衡 Ubuntu
Kubernetes安装详细教程 Ubuntu版
本教程基于Ubuntu 22.04配置Kubernetes环境,涵盖依赖安装、swap关闭、内核参数调整、containerd与Kubernetes组件安装、集群初始化及CNI网络插件部署等内容,并提供常见问题处理方法和相关工具推荐。
|
6天前
|
Ubuntu 数据安全/隐私保护 Docker