あのときの、ほら!あれ、あれ!

SIer勤務のAWSなエンジニア(父)が好きなことをアウトプットして人生のなにがしかに役立てたり役立てなかったりするブログ

Lambda関数でAssumeRoleして他のアカウントのNACL設定を取得する

こんばんは!!

複数アカウントをOrganizationで運用していくにあたり
Masterアカウントから配下のアカウントのNACLの設定状態を取得するのを
Lambda関数で実装したいと思い、自宅の疑似環境でお試ししてみました。


やっていること

①Masterアカウント→SlaveアカウントにAssumeロール
②AssumeロールしたロールでSlaveアカウントのNACL設定を取得


実際は取得した内容を成型しないと使い物にならないのですが
とりあえず取得できるというところまでやれたので
忘れないうちに残します。


1. Masterアカウントでロール作成 Lambda関数で使うロールです
ロール名:AWSGetResourceByLambdaReadOnlyRole(なんでもよい)
* 1111111=SlaveアカウントのID

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::1111111:role/AWSGetResourceByLambdaReadOnlyRole",
            "Effect": "Allow"
        }
    ]
}


2. Slaveアカウントでロール作成

NACL情報を取得するためのロールです
MasterアカウントのアカウントIDを信頼エンティティに追加しています
※NACLはVPCではなく'"ec2:Describe*"'で取得するので注意が必要
EC2の読み取りのみの権限を付与しました

3. Lambda関数を作成

import boto3
import json
from boto3.session import Session
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)

# 引数で渡された AWS アカウント/ロールのクレデンシャルを取得
def sts_assume_role(account_id, role_name, region):
    role_arn = "arn:aws:iam::" + account_id + ":role/" + role_name
    session_name = "test"

    client = boto3.client('sts')

    # AssumeRole で一時クレデンシャルを取得
    response = client.assume_role(
        RoleArn=role_arn,
        RoleSessionName=session_name
    )

    session = Session(
        aws_access_key_id=response['Credentials']['AccessKeyId'],
        aws_secret_access_key=response['Credentials']['SecretAccessKey'],
        aws_session_token=response['Credentials']['SessionToken'],
        region_name=region
    )

    return session

def lambda_handler(event,context):
    print("Received event: " + json.dumps(event, indent=2))

    account_id = event['account']
    role_name = event['role']
    region= event['region']

    # account_id = event['account']
    # role_name = event['role']
    # region = event['region']

    # イベントで指定されたAWSアカウント/ロールのクレデンシャルを取得
    session = sts_assume_role(account_id, role_name, region)

    ec2 = session.client('ec2')

    # 取得したクレデンシャルを使ってインスタンスリソースを取得
    instances = ec2.describe_network_acls(MaxResults=123)
    # logger.info(instances)

    return print(instances)


イベント

{
  "account": "1111111",
  "role": "AWSGetResourceByLambdaReadOnlyRole",
  "region": "ap-northeast-1"
}

Roleは2.で作成したロール名を記載します

結果

{'NetworkAcls': [{'Associations': [{'NetworkAclAssociationId': 'aclassoc-4e406234', 'NetworkAclId': 'acl-8e50e1e8', 'SubnetId': 'subnet-f81dc9d3'}, {'NetworkAclAssociationId': 'aclassoc-49406233', 'NetworkAclId': 'acl-8e50e1e8', 'SubnetId': 'subnet-49eed112'}, {'NetworkAclAssociationId': 'aclassoc-4f406235', 'NetworkAclId': 'acl-8e50e1e8', 'SubnetId': 'subnet-b72ce1ff'}], 'Entries': [{'CidrBlock': '0.0.0.0/0', 'Egress': True, 'Protocol': '-1', 'RuleAction': 'allow', 'RuleNumber': 100}, {'CidrBlock': '0.0.0.0/0', 'Egress': True, 'Protocol': '-1', 'RuleAction': 'deny', 'RuleNumber': 32767}, {'CidrBlock': '0.0.0.0/0', 'Egress': False, 'Protocol': '-1', 'RuleAction': 'allow', 'RuleNumber': 100}, {'CidrBlock': '0.0.0.0/0', 'Egress': False, 'Protocol': '-1', 'RuleAction': 'deny', 'RuleNumber': 32767}], 'IsDefault': True, 'NetworkAclId': 'acl-8e50e1e8', 'Tags': [], 'VpcId': 'vpc-ebadad8c', 'OwnerId': '11111111'}, {'Associations': [{'NetworkAclAssociationId': 'aclassoc-0e2844846f5677dd7', 'NetworkAclId': 'acl-034327f98e1edb609', 'SubnetId': 'subnet-0a15d8d5a3c54b67b'}, {'NetworkAclAssociationId': 'aclassoc-0f53fb9a35dc2f745', 'NetworkAclId': 'acl-034327f98e1edb609', 'SubnetId': 'subnet-002cfbbdfa4df0df6'}, {'NetworkAclAssociationId': 'aclassoc-0148161c1f8bea553', 'NetworkAclId': 'acl-034327f98e1edb609', 'SubnetId': 'subnet-05a23ba6e5bd8e188'}, {'NetworkAclAssociationId': 'aclassoc-08cc336738cb46568', 'NetworkAclId': 'acl-034327f98e1edb609', 'SubnetId': 'subnet-0180a727935d772cd'}], 'Entries': [{'CidrBlock': '0.0.0.0/0', 'Egress': True, 'Protocol': '-1', 'RuleAction': 'allow', 'RuleNumber': 100}, {'CidrBlock': '0.0.0.0/0', 'Egress': True, 'Protocol': '-1', 'RuleAction': 'deny', 'RuleNumber': 32767}, {'CidrBlock': '0.0.0.0/0', 'Egress': False, 'Protocol': '-1', 'RuleAction': 'allow', 'RuleNumber': 100}, {'CidrBlock': '0.0.0.0/0', 'Egress': False, 'Protocol': '-1', 'RuleAction': 'deny', 'RuleNumber': 32767}], 'IsDefault': True, 'NetworkAclId': 'acl-034327f98e1edb609', 'Tags': [], 'VpcId': 'vpc-021e22d78fe136fdb', 'OwnerId': '11111111'}]


参考サイト


EC2 — Boto 3 Docs 1.12.4 documentation
Lambda で Switch ロールに対応した複数アカウントのインスタンス一覧の取得 - Qiita