You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用AWS Go SDK列出关联AWS账户的资源

解决AWS Organizations子账户资源列表获取问题

你当前的代码始终使用默认认证的账户身份调用Route53接口,所以只能获取当前账户的资源。AWS没有直接通过传递账户ID切换身份的方式,必须通过**IAM角色扮演(AssumeRole)**来获取子账户的临时凭证,再用该凭证创建对应服务的客户端。

另外,你的代码混合使用了AWS SDK v1和v2,这会增加复杂度,建议统一使用v2版本(你已经导入了v2的包)。

解决步骤

  1. 前提准备:在每个子账户中创建一个IAM角色(比如OrganizationReadOnlyAccess),信任关系设置为允许管理账户(或运行代码的账户)扮演该角色,并且角色权限包含route53:ListHostedZones、route53domains:ListDomains等必要读取权限。
  2. 代码修改:遍历子账户时,调用STS服务的AssumeRole接口获取临时凭证,用该凭证创建子账户的服务客户端,再调用资源列表接口。

修改后的完整代码

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/organizations"
    "github.com/aws/aws-sdk-go-v2/service/route53"
    "github.com/aws/aws-sdk-go-v2/service/route53domains"
    "github.com/aws/aws-sdk-go-v2/service/sts"
    "github.com/aws/aws-sdk-go-v2/service/sts/types"
)

// 扮演子账户角色,获取临时凭证配置
func assumeRole(ctx context.Context, accountID string, roleName string) (aws.Config, error) {
    // 加载默认配置(管理账户的身份)
    cfg, err := config.LoadDefaultConfig(ctx, config.WithDefaultRegion("us-east-1"))
    if err != nil {
        return aws.Config{}, err
    }

    stsClient := sts.NewFromConfig(cfg)
    resp, err := stsClient.AssumeRole(ctx, &sts.AssumeRoleInput{
        RoleArn:         aws.String(fmt.Sprintf("arn:aws:iam::%s:role/%s", accountID, roleName)),
        RoleSessionName: aws.String("org-resource-list-session"),
    })
    if err != nil {
        return aws.Config{}, err
    }

    // 用临时凭证创建新的配置
    return aws.Config{
        Credentials: aws.NewCredentialsCache(aws.NewStaticCredentialsProvider(
            *resp.Credentials.AccessKeyId,
            *resp.Credentials.SecretAccessKey,
            *resp.Credentials.SessionToken,
        )),
        Region: "us-east-1", // 根据需要调整区域
    }, nil
}

func main() {
    ctx := context.TODO()

    // 加载管理账户配置
    cfg, err := config.LoadDefaultConfig(ctx, config.WithDefaultRegion("us-east-1"))
    if err != nil {
        log.Fatal(err)
    }

    // 创建Organizations客户端
    orgClient := organizations.NewFromConfig(cfg)
    resp, err := orgClient.ListAccounts(ctx, &organizations.ListAccountsInput{})
    if err != nil {
        log.Fatalf("获取账户列表失败: %v", err)
    }

    // 替换为你在子账户中创建的角色名称
    targetRoleName := "OrganizationReadOnlyAccess"

    fmt.Println("账户列表:")
    for _, account := range resp.Accounts {
        accountID := *account.Id
        accountName := *account.Name
        fmt.Printf("\n=== 账户: %s (%s) ===\n", accountName, accountID)

        // 扮演子账户角色
        subAccountCfg, err := assumeRole(ctx, accountID, targetRoleName)
        if err != nil {
            fmt.Printf("切换到账户%s失败: %v\n", accountName, err)
            continue
        }

        // 创建子账户的Route53Domains客户端并列出域名
        r53DomainsClient := route53domains.NewFromConfig(subAccountCfg)
        domainsResp, err := r53DomainsClient.ListDomains(ctx, &route53domains.ListDomainsInput{})
        if err != nil {
            fmt.Printf("获取账户%s域名失败: %v\n", accountName, err)
        } else {
            fmt.Println("域名列表:")
            for _, domain := range domainsResp.Domains {
                fmt.Println("-", *domain.DomainName)
            }
        }

        // 创建子账户的Route53客户端并列出托管区域
        r53Client := route53.NewFromConfig(subAccountCfg)
        zonesResp, err := r53Client.ListHostedZones(ctx, &route53.ListHostedZonesInput{})
        if err != nil {
            fmt.Printf("获取账户%s托管区域失败: %v\n", accountName, err)
        } else {
            fmt.Println("托管区域列表:")
            for _, zone := range zonesResp.HostedZones {
                fmt.Println("-", *zone.Name)
            }
        }
    }
}

关键说明

  • 角色扮演逻辑:assumeRole函数负责调用STS服务获取子账户的临时凭证,生成子账户专属的配置。
  • 统一SDK版本:移除了v1的session和route53包,全部使用v2的API,避免版本冲突。
  • 错误处理优化:切换账户或获取资源失败时,不再直接终止程序,而是打印错误后继续处理下一个账户。
  • 角色权限:确保子账户的角色拥有足够的权限来读取Route53和Route53Domains资源,必要时可以自定义权限策略。

内容的提问来源于stack exchange,提问作者Arvind Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 04:15:18