4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

インフラストラクチャのコード化(Infrastructure as Code)

Last updated at Posted at 2023-04-29

インフラを構築する事が出来るだけではなく、コード化して管理出来る能力が求められるようになってきました。そこで、AWSインフラをコード化する基本的な操作をまとめてみました。

現代のソフトウェア開発では、インフラストラクチャのコード化がますます重要になっています。インフラストラクチャのコード化とは、物理的なインフラストラクチャのセットアップや構成を、ソフトウェアのコードとして表現し、自動化することを指します。

インフラストラクチャを手動で構成する場合、手作業のエラーが発生する可能性があります。しかし、コードであれば、そのエラーを自動的に検出できます。また、変更管理も容易になります。コードをバージョン管理システムに格納することで、変更履歴を追跡することができ、必要に応じて以前の状態に戻すことができます。

インフラストラクチャのコード化には、次のような利点があります。

🔸スピードと柔軟性の向上
インフラストラクチャのコード化により、インフラストラクチャのセットアップや構成を自動化できます。
☞手動での作業時間を節約し、スピードと柔軟性を向上させることができます。

🔸信頼性の向上
インフラストラクチャのコード化により、繰り返し実行可能なプロセスが確立され、エラーやヒューマンエラーを減らすことができます。
☞変更履歴が完全に記録され、バージョン管理が容易になります。

🔸標準化と統制の強化
インフラストラクチャのコード化により、インフラストラクチャの構成が標準化され、共通のテンプレートが使われるようになります。
☞異なるチームやプロジェクト間での共通の基盤が確立され、統制が強化されます。

インフラストラクチャのコード化により、ソフトウェア開発のプロセスが改善され、信頼性や効率性が向上します。
将来的には、インフラストラクチャのコード化は、ソフトウェア開発において不可欠な要素となるでしょう。

前回のブログ記事 
🔹Pythonの使い方
https://qiita.com/kimuni-i/items/55db95604b094f0c4e74
🔹AWS Lake Formation CDK(Cloud Development Kit)とは?
https://qiita.com/kimuni-i/items/5c3d9a4e4c2db83d9cc5

PythonでLake Formationを使用するための基本的な手順

AWS Lake FormationをPythonで使用するには、boto3パッケージを使用します。
boto3はAWS SDK for Pythonであり、AWSリソースと対話するためのライブラリです。

PythonでLake Formationを使用するための基本的な手順

boto3パッケージをインストールします。

pip install boto3

boto3を使用してAWSクレデンシャルを設定します。
これには、AWSのアクセスキーIDとシークレットアクセスキーが必要です。

import boto3

# AWSのクレデンシャルを設定
session = boto3.Session(
    aws_access_key_id='your-access-key-id',
    aws_secret_access_key='your-secret-access-key',
    region_name='your-region'
)

boto3のLake Formationクライアントを作成します。

# Lake Formationクライアントを作成
lakeformation_client = session.client('lakeformation')

Lake FormationのAPIを使用して操作を実行します。
たとえば、データベースの作成やテーブルへのアクセス許可の設定などの操作を行うことができます。

# データベースの作成
response = lakeformation_client.create_database(
    DatabaseInput={
        'Name': 'my_database',
        'Description': 'My database'
    }
)
# テーブルへのアクセス許可の設定
response = lakeformation_client.grant_permissions(
    CatalogId='your-catalog-id',
    Principal={
        'DataLakePrincipalIdentifier': 'arn:aws:iam::123456789012:user/my_user'
    },
    Resource={
        'Table': {
            'DatabaseName': 'my_database',
            'Name': 'my_table'
        }
    },
    Permissions=['SELECT']
)

上記の例では、データベースの作成とテーブルへのアクセス許可の設定の操作が示されています。

AWS Lake Formation SDKを使用して、データレイクのアクセス許可を設定する例

import boto3

# AWS Lake Formationクライアントを作成する
lf_client = boto3.client('lakeformation')

# データレイクオブジェクトの設定
database_name = 'my_database'
table_name = 'my_table'
resource_arn = f'arn:aws:glue:us-east-1:123456789012:catalog'
database_arn = f'{resource_arn}:database/{database_name}'
table_arn = f'{database_arn}/table/{table_name}'

# テーブルへのSELECTアクセスを付与する
lf_client.grant_permissions(
    Principal={
        'DataLakePrincipalIdentifier': 'arn:aws:iam::123456789012:user/username'
    },
    Resource={
        'Table': {
            'DatabaseName': database_name,
            'Name': table_name,
        },
    },
    Permissions=['SELECT']
)

# データベースからSELECTアクセスを取り消す
lf_client.revoke_permissions(
    Principal={
        'DataLakePrincipalIdentifier': 'arn:aws:iam::123456789012:user/username'
    },
    Resource={
        'Database': {
            'Name': database_name
        },
    },
    Permissions=['SELECT']
)

ポイント
🔸boto3モジュールを使用してAWS Lake Formationクライアントを作成します。
🔸database_nameとtable_nameを設定し、リソースARN、データベースARN、テーブルARNを構築します。
🔸lf_client.grant_permissions()メソッドを使用して、指定したユーザーにテーブルへのSELECTアクセスを付与します。
🔸PrincipalパラメータにはIAMユーザーのARNを指定し、Resourceパラメータにはデータベースとテーブルの情報を指定します。
🔸lf_client.revoke_permissions()メソッドを使用して、指定したユーザーからデータベースへのSELECTアクセスを取り消します。同様に、PrincipalパラメータとResourceパラメータを指定します。

AWS Lake Formationを使用してVPC内のデータにアクセスする例

VPCエンドポイントを使用すると、インターネット経由での通信を必要とせず、VPC内部で完結するため、セキュリティが向上します。

VPCエンドポイントを作成するためのサンプルコード

import boto3

# Boto3を使用してLake Formationのクライアントを作成する
lf_client = boto3.client('lakeformation')

# Lake Formationのデータレイク設定を作成する
vpc_endpoint = lf_client.create_data_lake_settings(
    DataLakeSettings={
        # デフォルトのデータベース作成時のアクセス許可を指定する
        'CreateDatabaseDefaultPermissions': [
            {
                'Principal': {
                    'DataLakePrincipalIdentifier': 'IAM_ROLE_ARN'
                },
                'Permissions': [
                    'ALL'
                ]
            },
        ],
        # Lake Formationの管理者を指定する
        'DataLakeAdmins': [
            {
                'DataLakePrincipalIdentifier': 'IAM_USER_ARN'
            },
        ],
        # 信頼されたリソースオーナーを指定する
        'TrustedResourceOwners': [
            'AWS'
        ],
        # VPCエンドポイントを使用するかどうかを指定する
        'UseVirtualPrivateCloud': True,
        # VPCのIDを指定する
        'VirtualPrivateCloudId': 'VPC_ID',
        # エンドポイントへのパブリックアクセスを無効にする
        'EndpointPublicAccess': False,
        # エンドポイントへのプライベートアクセスを有効にする
        'EndpointPrivateAccess': True,
        # VPCエンドポイントのサブネットIDを指定する
        'VpcEndpointSubnetIds': [
            'SUBNET_ID'
        ],
        # リージョンを指定する
        'Region': 'REGION'
    }
)

コード内の各パラメーターの説明

🔸lf_client
Boto3のLake Formationクライアントを初期化します。

🔸DataLakeSettings
Lake Formationの設定オブジェクトを作成します。

🔸CreateDatabaseDefaultPermissions
データベースを作成する場合のデフォルトのアクセス許可を定義します。ここでは、IAMロールのARNを指定して、そのロールに対してALLのアクセス許可を設定しています。

🔸DataLakeAdmins
Lake Formationの管理者のリストを定義します。ここでは、IAMユーザーのARNを指定しています。

🔸TrustedResourceOwners
信頼されたリソースの所有者を定義します。ここでは、AWSを指定しています。

🔸UseVirtualPrivateCloud
VPCを使用するかどうかを定義します。ここでは、Trueを指定しています。

🔸VirtualPrivateCloudId
VPCのIDを指定します。

🔸EndpointPublicAccess
エンドポイントにパブリックアクセスを許可するかどうかを定義します。ここでは、Falseを指定しています。

🔸EndpointPrivateAccess
エンドポイントにプライベートアクセスを許可するかどうかを定義します。ここでは、Trueを指定しています。

🔸VpcEndpointSubnetIds
VPCエンドポイントのサブネットIDを指定します。

🔸Region
リージョンを指定します。

このコードが実行されると、指定されたVPCにLake Formationのエンドポイントが作成されます。

このエンドポイントを使用して、VPC内のリソースからデータレイクにアクセスする事が出来ます。

VPCエンドポイントが作成されたら、VPC内のEC2インスタンスなどからLake Formationにアクセスする場合は、VPCエンドポイントを使用するように設定します。

具体的には、Lake Formation SDKのconfigオブジェクトのendpoint_urlプロパティにVPCエンドポイントのURLを指定します。

VPCエンドポイントを使用してLake Formationクライアントを作成

import boto3
from botocore.config import Config

# リージョンとVPCエンドポイントのURLを指定してConfigオブジェクトを作成する
config = Config(
    region_name='REGION',
    endpoint_url='https://VPC_ENDPOINT_URL'
)

# VPCエンドポイントを使用してLake Formationクライアントを作成する
lf_client = boto3.client('lakeformation', config=config)

このコードは、指定されたVPCエンドポイントを使用してLake Formationのクライアントを作成しています。
botocore.config.Config()を使用してVPCエンドポイントを指定し、boto3.client()を使用してLake Formationのクライアントを作成することができます。

🔸1行目では、boto3モジュールをインポートしています。

🔸2行目では、botocore.configモジュールからConfigクラスをインポートしています。

🔸3行目では、Configクラスを使用して、指定されたリージョンとVPCエンドポイントのURLを含むconfigオブジェクトを作成しています。

🔸4行目では、boto3モジュールからclient()関数を使用してLake Formationのクライアントを作成しています。client()関数のconfig引数に、3行目で作成したconfigオブジェクトを渡しています。これにより、Lake FormationのAPI呼び出しは、指定されたVPCエンドポイントを介して行われるようになります。

ポイント
1️⃣botocore.config.Config()を使用して、Lake Formationのクライアントに設定する構成を定義しています。
この構成には、次の2つのプロパティが含まれています。

🔸region_name
AWSリージョンの名前。この例では、REGIONに設定されています。

🔸endpoint_url
使用するVPCエンドポイントのURL。この例では、https://VPC_ENDPOINT_URLに設定されています。

2️⃣boto3.client()を使用してLake Formationのクライアントを作成しています。このメソッドには、2つの引数があります。

🔸service_name
クライアントを作成するAWSサービスの名前。この例では、lakeformationに設定されています。

🔸config
botocore.config.Config()で定義された構成オブジェクト。
この例では、configに定義されたオブジェクトが使用されています。

このようにして、指定されたVPCエンドポイントを使用して、Lake Formationのクライアントを作成することができます。

Lake FormationとSecrets Managerを組み合わせる

Lake Formationとは、AWSのサービスで、データレイクを構築するためのツールです。Lake Formationには、データカタログ、データアクセス制御、データ加工などの機能があります。

Secrets Managerは、AWSのサービスで、アプリケーションに必要な機密情報(APIキー、パスワード、証明書など)を安全に管理するためのツールです。

Lake FormationとSecrets Managerを組み合わせることで、データレイクにアクセスするための権限を制御しながら、アプリケーションが必要とする機密情報を安全に管理できます。

例えば、AWS Glueを使用してデータレイク内のデータを加工し、S3に保存する場合を考えてみましょう。この場合、Glue JobがSecrets Managerから必要な認証情報を取得し、Lake Formationが設定されたアクセス制御に基づいてデータレイクにアクセスします。このように、Lake FormationとSecrets Managerを組み合わせることで、データレイクのセキュリティを強化し、アプリケーションが必要な情報にアクセスできるようにすることができます。

import boto3

# Secrets Managerから必要な認証情報を取得する
secrets_manager = boto3.client('secretsmanager')
secrets = secrets_manager.get_secret_value(SecretId='<SECRET_ID>')
username = secrets['username']
password = secrets['password']

# Lake Formationから必要な権限を取得する
lakeformation = boto3.client('lakeformation')
permissions = lakeformation.get_permissions(resourceArn='<DATA_LAKE_ARN>', principal={'DataLakePrincipalIdentifier': '<PRINCIPAL_ID>'})

# AWS Glueを使用してデータレイク内のデータを加工する
glue = boto3.client('glue')
job_args = {
    '--username': username,
    '--password': password

この例では、
< SECRET_ID>にはSecrets Managerに保存された認証情報のID、
< DATA_LAKE_ARN>にはデータレイクのARN、
< PRINCIPAL_ID>にはアクセス権を持つIAMユーザーまたはロールのID、
< GLUE_JOB_NAME>には実行するAWS Glueジョブの名前を指定します。
また、--usernameと--passwordはAWS Glueジョブの引数として使用され、
Secrets Managerから取得した認証情報が渡されます。

AWS Secrets ManagerとLake Formationを組み合わせてデータレイクの操作を行う

このサンプルコードは、AWS Secrets Managerを使用して認証情報を取得し、Lake Formationを使用してデータレイクにアクセス制御を設定し、S3を使用してデータの読み書きを行っています。

import boto3

# AWS Secrets Managerから認証情報を取得
def get_secrets():
    # Secrets Managerクライアントの作成
    secrets_manager_client = boto3.client('secretsmanager')
    # Secretの値の取得
    secret_value = secrets_manager_client.get_secret_value(SecretId='my-lake-secret')
    # Secretの値をデコード
    secrets = eval(secret_value['SecretString'])
    return secrets

# Lake Formationによるアクセス制御の設定
def access_lake_formation():
    # boto3セッションの取得
    session = boto3.session.Session()
    # LakeFormationクライアントの作成
    lakeformation_client = session.client('lakeformation')
    # データベース、テーブルのアクセス許可を設定
    lakeformation_client.grant_permissions(
        Principal={
            'DataLakePrincipalIdentifier': 'arn:aws:iam::123456789012:role/my-role'
        },
        Resource={
            'Database': {
                'Name': 'my-database'
            },
            'Table': {
                'DatabaseName': 'my-database',
                'Name': 'my-table'
            }
        },
        Permissions=['SELECT', 'WRITE']
    )

# データレイクからのデータの取得
def get_data_from_lake():
    # boto3セッションの取得
    session = boto3.session.Session()
    # S3クライアントの作成
    s3_client = session.client('s3')
    # ファイルのダウンロード
    s3_client.download_file(
        Bucket='my-lake-bucket',
        Key='my-data-file',
        Filename='my-local-file'
    )

# データレイクにデータの書き込み
def write_data_to_lake():
    # boto3セッションの取得
    session = boto3.session.Session()
    # S3クライアントの作成
    s3_client = session.client('s3')
    # ファイルのアップロード
    s3_client.upload_file(
        Filename='my-local-file',
        Bucket='my-lake-bucket',
        Key='my-data-file'
    )

# メイン処理
def main():
    # Secrets Managerから認証情報の取得
    secrets = get_secrets()
    # 認証情報を使用してAWSに接続
    session = boto3.session.Session(
        aws_access_key_id=secrets['access_key'],
        aws_secret_access_key=secrets['secret_key'],
        aws_session_token=secrets['session_token'],
        region_name='us-west-2'
    )
    # Lake Formationによるアクセス制御
    access_lake_formation()
    # データの取得
    get_data_from_lake()
    # データの書き込み
    write_data_to_lake()

if __name__ == '__main__':
    main()

各部分の解説

🔸import boto3
boto3モジュールをインポートしてAWSの各種サービスにアクセスします。

🔸get_secrets()
AWS Secrets Managerから認証情報を取得する関数です。boto3.client('secretsmanager')でSecrets Managerクライアントを作成し、get_secret_value()で指定したSecretの値を取得します。取得したSecretの値はデコードして返します。

🔸access_lake_formation()
Lake Formationによるアクセス制御を設定する関数です。boto3.session.Session()でセッションを作成し、LakeFormationクライアントを作成します。grant_permissions()でデータベースやテーブルへのアクセス許可を設定します。

🔸get_data_from_lake()
データレイクからデータを取得する関数です。boto3.session.Session()でセッションを作成し、S3クライアントを作成します。download_file()で指定したバケットとキーのファイルをダウンロードします。

🔸write_data_to_lake()
データレイクにデータを書き込む関数です。boto3.session.Session()でセッションを作成し、S3クライアントを作成します。upload_file()で指定したファイルを指定したバケットとキーにアップロードします。

🔸main()
メインの処理を行う関数です。get_secrets()を使用して認証情報を取得し、boto3.session.Session()でセッションを作成します。そして、access_lake_formation()でLake Formationによるアクセス制御を設定し、get_data_from_lake()でデータを取得し、write_data_to_lake()でデータを書き込みます。

🔸if name == 'main'
main(): スクリプトが直接実行された場合にmain()関数を実行します。

🔹AWS Glueを使用してデータレイク内のデータを加工し、S3に保存する際に、
Lake FormationとSecrets Managerを使用するサンプルコード

import boto3
import json
import awswrangler as wr

# AWSリソースの作成
session = boto3.Session()
secrets_manager_client = session.client('secretsmanager')
lakeformation_client = session.client('lakeformation')

# Secrets Managerから認証情報を取得
# Secrets Managerから、設定されたシークレットを取得しています。
# シークレットには、アクセスキーとシークレットアクセスキーなどの機密情報が含まれています。
# JSON形式に変換して、secrets_dictに格納しています。

secrets = secrets_manager_client.get_secret_value(SecretId='my_secret')
secrets_dict = json.loads(secrets['SecretString'])

# Lake Formationのデータベースとテーブルを作成
database_name = 'my_database'
table_name = 'my_table'

response = lakeformation_client.create_database(
    DatabaseInput={
        'Name': database_name
    }
)

response = lakeformation_client.create_table(
    DatabaseName=database_name,
    TableInput={
        'Name': table_name,

#StorageDescriptorパラメータには、テーブルのストレージ情報を指定します。
        'StorageDescriptor': {
#Columnsパラメータには、テーブルの列の情報を指定します。
#ここでは、col1とcol2という2つの列を指定しています。
            'Columns': [
                {
                    'Name': 'col1',
                    'Type': 'string'
                },
                {
                    'Name': 'col2',
                    'Type': 'int'
                }
            ],

#Locationパラメータには、データが保存されるS3バケットとパスを指定します。
#InputFormatパラメータには、入力形式を指定します。ここでは、TextInputFormatを使用しています。
#OutputFormatパラメータには、出力形式を指定します。ここでは、HiveIgnoreKeyTextOutputFormatを使用しています。
#SerdeInfoパラメータには、SerDe (Serialization/Deserialization) の情報を指定します。ここでは、LazySimpleSerDeを使用しています。
#また、SerDeのパラメータとして、フィールドの区切り文字を指定するためのfield.delimを指定しています。

            'Location': 's3://my_bucket/my_path',
            'InputFormat': 'org.apache.hadoop.mapred.TextInputFormat',
            'OutputFormat': 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat',
            'SerdeInfo': {
                'SerializationLibrary': 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe',
                'Parameters': {
                    'field.delim': ','
                }
            },
        },
#PartitionKeysパラメータには、パーティショニングキーの情報を指定します。
#この例では、パーティショニングを使用しないため、空のリストを指定しています。
        'PartitionKeys': []
    }
)

# Glue Jobでデータを加工し、S3に保存
glue = boto3.client('glue')

glue_job_response = glue.start_job_run(
    JobName='my_glue_job',
    Arguments={
        '--database_name': database_name,
        '--table_name': table_name,
        '--output_path': 's3://my_bucket/output/',
        '--access_key_id': secrets_dict['access_key_id'],
        '--secret_access_key': secrets_dict['secret_access_key']
    }
)

# Wranglerを使用してデータを読み込み
df = wr.s3.read_csv('s3://my_bucket/output/part-*', delimiter=',', header=None, names=['col1', 'col2'])

# Wranglerを使用してデータを書き込み
wr.s3.to_csv(df, 's3://my_bucket/processed_data/', index=False)

このコードでは、最初にSecrets Managerから必要な認証情報を取得し、Lake Formationのデータベースとテーブルを作成します。次に、Glue Jobでデータを加工し、S3に保存します。最後に、Wranglerを使用してS3からデータを読み込み、加工後のデータを別のS3バケットに保存します。このように、Lake FormationとSecrets Managerを使用することで、データレイクのセキュリティを強化しながら、安全にデータを加工することができます。

Lake FormationとSecrets Managerを組み合わせてAWS Glue Jobを実行する

import boto3
import os

# Secrets Managerから認証情報を取得
client = boto3.client('secretsmanager')
response = client.get_secret_value(SecretId='my/secret')
secrets = response['SecretString']
auth_info = json.loads(secrets)

# Lake FormationでデータレイクにアクセスするためのIAMロールを取得
client = boto3.client('lakeformation')
response = client.get_data_lake_settings()
lake_arn = response['DataLakeSettings']['DataLakeAdminArn']
role_name = 'glue-role'
role_arn = f"arn:aws:iam::{os.environ['AWS_ACCOUNT_ID']}:role/{role_name}"

# IAMロールにLake Formationのアクセス権限を付与
client.grant_permissions(
    Principal={
        'DataLakePrincipalIdentifier': lake_arn
    },
    Resource={
        'Type': 'IAM_ROLE',
        'Partition': 'aws',
        'Account': os.environ['AWS_ACCOUNT_ID'],
        'Arn': role_arn
    },
    Permissions=['ALL']
)

# Glue Jobを実行するためのパラメータを設定
job_params = {
    'glue_db': 'my_database',
    'glue_table': 'my_table',
    'access_key': auth_info['access_key'],
    'secret_key': auth_info['secret_key']
}

# Glue Jobを開始
glue = boto3.client('glue')
glue.start_job_run(
    JobName='my_job',
    Arguments=job_params,
    WorkerType='Standard',
    NumberOfWorkers=10
)

このサンプルコードでは、まずSecrets Managerから認証情報を取得し、Lake FormationでデータレイクにアクセスするためのIAMロールを取得しています。次に、IAMロールにLake Formationのアクセス権限を付与し、Glue Jobを実行するためのパラメータを設定しています。最後に、Glue Jobを開始しています。これにより、Lake FormationとSecrets Managerを組み合わせてデータレイクにアクセスするためのセキュアな方法が実現されます。

Lake FormationとSecrets Managerを組み合わせてデータレイクにアクセスする

AWS SDK for Python(Boto3)を使用して、Secrets Managerから必要な認証情報を取得します。

import boto3

session = boto3.session.Session()
client = session.client(
    service_name='secretsmanager',
    region_name='us-west-2'
)

secret_name = "my_database_credentials"
get_secret_value_response = client.get_secret_value(SecretId=secret_name)

if "SecretString" in get_secret_value_response:
    secret = get_secret_value_response["SecretString"]
else:
    secret = get_secret_value_response["SecretBinary"]

次に、Lake Formationを使用してデータレイクにアクセスします。

import boto3
from boto3.session import Session

# Create a session using Lake Formation's current region
session = Session(region_name="us-west-2")

# Create a client to interact with Lake Formation
lf = session.client("lakeformation")

# Grant SELECT permission on the table to the IAM user or role
response = lf.grant_permissions(
    Principal={
        'DataLakePrincipalIdentifier': 'arn:aws:iam::012345678901:user/my-user'
    },
    Resource={
        'Table': {
            'DatabaseName': 'my-database',
            'Name': 'my-table'
        }
    },
    Permissions=[
        'SELECT'
    ]
)

この例では、データベースの資格情報をSecrets Managerから取得し、Lake Formationを使用して、特定のIAMユーザーまたはロールに対して、指定されたテーブルに対するSELECTアクセスを許可するように指示しています。

Lake FormationとSecrets Managerを組み合わせたデータ処理

import boto3

# AWSサービスのクライアントを作成
lf_client = boto3.client('lakeformation')
sm_client = boto3.client('secretsmanager')

# データレイクにアクセスするためのIAMロールを作成
response = lf_client.create_resource(
    ResourceArn='arn:aws:s3:::my-datalake',
    RoleArn='arn:aws:iam::123456789012:role/my-lake-role'
)

# アプリケーションが必要とする機密情報を取得
secret_value = sm_client.get_secret_value(
    SecretId='my-app-secrets'
)['SecretString']

# Glue Jobを実行
glue_client = boto3.client('glue')
response = glue_client.start_job_run(
    JobName='my-glue-job',
    Arguments={
        '--my-secret': secret_value
    }
)

上記の例では、まず、Lake FormationでデータレイクにアクセスするためのIAMロールを作成します。
次に、Secrets Managerからアプリケーションが必要とする機密情報を取得し、Glue Jobを開始します。
Glue Jobは、--my-secretという引数に機密情報を渡します。
このように、Glue JobはSecrets Managerから機密情報を直接取得することなく、安全に機密情報を取得することができます。
また、Lake Formationは、このIAMロールが許可されたデータレイクのみにアクセスできるように制御します。

AWS Glueを使用してS3に保存されたデータを加工する際に、Lake FormationとSecrets Managerを使用する

import boto3
import json
import os

# Secrets Managerから必要な機密情報を取得する
session = boto3.session.Session()
secrets_client = session.client(service_name='secretsmanager')
secrets = json.loads(secrets_client.get_secret_value(SecretId=os.environ['MY_SECRET_NAME'])['SecretString'])
api_key = secrets['API_KEY']

# Lake Formationから必要なデータレイクのアクセス権限を取得する
lakeformation_client = boto3.client('lakeformation')
permissions = lakeformation_client.get_permissions(resourceArn=os.environ['MY_DATA_LAKE_ARN'])

# AWS Glueでデータを加工する
glue_client = boto3.client('glue')
response = glue_client.start_job_run(
    JobName='my-glue-job',
    Arguments={
        '--api-key': api_key,
        '--data-lake-arn': os.environ['MY_DATA_LAKE_ARN']
    }
)
print(response)

このサンプルコードでは、Secrets Managerから必要な機密情報を取得し、Lake Formationからデータレイクのアクセス権限を取得しています。そして、AWS Glueを使用してジョブを実行する際に、取得した機密情報とアクセス権限を引数として渡しています。

ただし、このサンプルコードでは環境変数を使用しているため、実際に使用する際には適切な値をセットする必要があります。また、APIキーやデータレイクのARNはサンプルコードの仮の値であり、実際に使用する場合は適切な値に置き換える必要があります。

Lake FormationとSecrets Managerを組み合わせてデータレイクにアクセスする

まず、必要なモジュールをインポートします。

import boto3
import json

次に、Secrets Managerから必要な機密情報を取得します。

client = boto3.client('secretsmanager')
response = client.get_secret_value(SecretId='<your-secret-id>')
secret = json.loads(response['SecretString'])

ここで、には、アプリケーションが必要とする機密情報のSecret IDを指定します。

次に、Lake Formationを使用してS3上のデータにアクセスします。

client = boto3.client('lakeformation')

# アクセス許可を取得
response = client.get_data_lake_settings()
settings = response['DataLakeSettings']
permissions = settings['DataLakeAdmins']

# アクセス許可を設定
permissions.append({'DataLakePrincipalIdentifier': '<your-principal-identifier>'})
client.put_data_lake_settings(DataLakeSettings={'DataLakeAdmins': permissions})

# データにアクセス
response = client.get_data_lake_settings()
settings = response['DataLakeSettings']
print(settings)

ここで、< your-principal-identifier >には、アプリケーションにアクセスを許可するIAMユーザー、IAMロール、またはAWSアカウントのARNを指定します。

この例では、get_secret_value()メソッドを使用してSecrets Managerから機密情報を取得し、get_data_lake_settings()メソッドを使用してLake Formationのアクセス許可を取得し、put_data_lake_settings()メソッドを使用してアクセス許可を設定し、最後にget_data_lake_settings()メソッドを使用して設定を確認します。

AWS Glue Jobを実行するためにLake FormationとSecrets Managerを組み合わせる

import boto3
import json

secrets_client = boto3.client('secretsmanager')
lakeformation_client = boto3.client('lakeformation')

# Secrets Managerから必要な機密情報を取得
secrets_response = secrets_client.get_secret_value(SecretId='my-glue-job-secrets')

# Lake Formationのデータベースとテーブルへのアクセス権を設定
permissions = {
    'DataLakePrincipal': {
        'DataLakePrincipalIdentifier': 'arn:aws:iam::123456789012:user/my-glue-job-user'
    },
    'Permissions': ['SELECT']
}
lakeformation_client.grant_permissions(
    Principal=permissions['DataLakePrincipal'],
    Resource={
        'Database': {
            'Name': 'my-database'
        },
        'Table': {
            'DatabaseName': 'my-database',
            'Name': 'my-table'
        }
    },
    Permissions=permissions['Permissions']
)

# Glue Jobを実行
glue_client = boto3.client('glue')
response = glue_client.start_job_run(
    JobName='my-glue-job',
    Arguments={
        '--input_path': 's3://my-bucket/my-input-data',
        '--output_path': 's3://my-bucket/my-output-data',
        '--secrets': secrets_response['SecretString']
    }
)

print(response)

この例では、Secrets Managerからmy-glue-job-secretsという名前のシークレットを取得し、Lake Formationを使用して、my-databaseデータベース内のmy-tableテーブルに対するmy-glue-job-userユーザーのSELECT権限を付与しています。そして、Glue Jobを実行する際に、--secrets引数に取得した機密情報を渡しています。

Lake FormationとSecrets Managerを組み合わせてGlue Jobを実行する

import boto3
import json

# Secrets Managerから認証情報を取得する
secrets_manager_client = boto3.client('secretsmanager')
secrets = json.loads(secrets_manager_client.get_secret_value(SecretId='my-database-credentials')['SecretString'])

# Lake Formationによるアクセス制御を設定する
lakeformation_client = boto3.client('lakeformation')
response = lakeformation_client.grant_permissions(
    Principal={
        'DataLakePrincipalIdentifier': 'arn:aws:iam::123456789012:user/myuser'
    },
    Resource={
        'Table': {
            'DatabaseName': 'my_database',
            'Name': 'my_table'
        }
    },
    Permissions=['SELECT', 'INSERT']
)

# Glue Jobを実行する
glue_client = boto3.client('glue')
response = glue_client.start_job_run(
    JobName='my_glue_job',
    Arguments={
        '--username': secrets['username'],
        '--password': secrets['password']
    }
)

この例では、まずSecrets Managerから必要な認証情報を取得し、次にLake Formationを使用してデータレイクのアクセス制御を設定します。最後に、Glue Jobを開始するときに、取得した認証情報を引数として渡します。これにより、Glue Jobは必要な情報にアクセスできるようになりますが、データレイクのアクセス制御により、不正なアクセスを防止することができます。

AWS Lake FormationとSecrets Managerを組み合わせる
その他参考例1

Lake Formationを使用してデータカタログを構築し、Secrets Managerを使用して認証情報を管理します。

まず、必要なモジュールをインポートします。

import boto3
from botocore.exceptions import ClientError

次に、AWSクライアントを初期化します。

lakeformation = boto3.client('lakeformation')
secretsmanager = boto3.client('secretsmanager')

データカタログの作成には、以下のようにcreate_data_catalog()を使用します。

def create_data_catalog(database_name, s3_location):
    try:
        response = lakeformation.create_data_catalog(
            Name=database_name,
            Description='My data catalog',
            Parameters={
                'Location': {
                    'S3': {
                        'Bucket': s3_location,
                        'Prefix': database_name
                    }
                }
            },
            Type='LAMBDA',
            Tags={
                'Project': 'My Project',
                'Environment': 'Production'
            }
        )
        print(f"Data catalog '{database_name}' created successfully.")
    except ClientError as e:
        print(f"Error creating data catalog: {e}")

次に、Secrets Managerに認証情報を保存するために、以下のようにcreate_secret()を使用します。

def create_secret(secret_name, username, password):
    try:
        response = secretsmanager.create_secret(
            Name=secret_name,
            SecretString=json.dumps({'username': username, 'password': password}),
            Tags=[
                {
                    'Key': 'Project',
                    'Value': 'My Project'
                },
                {
                    'Key': 'Environment',
                    'Value': 'Production'
                }
            ]
        )
        print(f"Secret '{secret_name}' created successfully.")
    except ClientError as e:
        print(f"Error creating secret: {e}")

最後に、Glue Jobがデータレイクにアクセスするために必要な認証情報を取得するために、以下のようにget_secret_value()を使用します。

def get_secret_value(secret_name):
    try:
        response = secretsmanager.get_secret_value(
            SecretId=secret_name
        )
        return json.loads(response['SecretString'])
    except ClientError as e:
        print(f"Error getting secret value: {e}")

これらの関数を使って、Glue Jobが認証情報を取得しながらデータレイクにアクセスできます。

AWS Lake FormationとSecrets Managerを組み合わせる
その他参考例2

import boto3

# Secrets Managerから認証情報を取得する
secrets_manager = boto3.client('secretsmanager')
secret = secrets_manager.get_secret_value(SecretId='my_database_creds')
creds = json.loads(secret['SecretString'])

# Lake Formationからデータレイクにアクセスする権限を付与する
lake_formation = boto3.client('lakeformation')
response = lake_formation.grant_permissions(
    Principal={
        'DataLakePrincipalIdentifier': 'arn:aws:iam::123456789012:user/my_user'
    },
    Resource={
        'Table': {
            'DatabaseName': 'my_database',
            'Name': 'my_table'
        }
    },
    Permissions=['SELECT']
)

# AWS Glueを使用してデータを加工する
glue = boto3.client('glue')
response = glue.start_job_run(
    JobName='my_job',
    Arguments={
        '--username': creds['username'],
        '--password': creds['password'],
        '--database': 'my_database',
        '--table': 'my_table'
    }
)

この例では、Secrets Managerからデータベースの認証情報を取得し、Lake Formationでデータレイクにアクセスする権限を付与しています。そして、AWS Glueを使用してデータを加工しています。加工に必要な認証情報は、Secrets Managerから取得したものを使用しています。

AWS Lake FormationとSecrets Managerを組み合わせる
その他参考例3

import boto3

# Secrets Managerから必要な機密情報を取得する
secretsmanager = boto3.client('secretsmanager')
secrets = secretsmanager.get_secret_value(SecretId='myapp/secrets')

# Lake Formationによるアクセス制御を設定する
lakeformation = boto3.client('lakeformation')
response = lakeformation.grant_permissions(
    Principal={
        'DataLakePrincipalIdentifier': 'arn:aws:iam::123456789012:user/myuser'
    },
    Resource={
        'Table': {
            'DatabaseName': 'mydb',
            'Name': 'mytable'
        }
    },
    Permissions=['SELECT']
)

# Glue Jobを実行する
glue = boto3.client('glue')
job_name = 'myjob'
response = glue.start_job_run(
    JobName=job_name,
    Arguments={
        '--secrets': secrets['SecretString']
    }
)

このコードでは、Secrets Managerからmyapp/secretsという名前のシークレットを取得し、Lake Formationでmydb.mytableテーブルに対するSELECT権限をユーザーmyuserに与えます。そして、Glue Jobを実行する際に、取得したシークレットを引数として渡します。これにより、Glue Jobは必要な機密情報を取得し、Lake Formationによって設定されたアクセス制御に基づいてデータレイクにアクセスします。

AWS Lake FormationとSecrets Managerを組み合わせる
その他参考例4

import boto3

# Secrets Managerから認証情報を取得
secrets_manager = boto3.client('secretsmanager')
secrets = secrets_manager.get_secret_value(SecretId='my-datalake-auth')

# Lake FormationでデータレイクにアクセスするためのIAMロールを作成
lakeformation = boto3.client('lakeformation')
role_name = 'my-datalake-role'
assume_role_policy = {
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "glue.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
response = lakeformation.create_role(RoleName=role_name, AssumeRolePolicyDocument=json.dumps(assume_role_policy))

# データレイクにアクセスするIAMロールに権限を付与
resource_arn = 'arn:aws:s3:::my-datalake/*'
database_name = 'my_database'
table_name = 'my_table'
table_arn = f'arn:aws:glue:us-west-2:123456789012:table/{database_name}/{table_name}'
permissions = {
  "DataLocation": {
    "ResourceArn": resource_arn
  },
  "Table": {
    "DatabaseName": database_name,
    "TableWildcard": {}
  }
}
response = lakeformation.grant_permissions(
  Principal={
    "DataLakePrincipalIdentifier": f"arn:aws:iam::{response['RoleId']}:role/{role_name}"
  },
  Resource={
    "Table": {
      "TableArn": table_arn
    }
  },
  Permissions=list(permissions.keys())
)

# Glue Jobを実行し、データを処理する
glue = boto3.client('glue')
job_name = 'my-glue-job'
job_args = {
  '--input': f's3://my-datalake/input',
  '--output': f's3://my-datalake/output'
}
response = glue.start_job_run(JobName=job_name, Arguments=job_args, Role=response['Role']['Arn'])

上記の例では、Secrets Managerから取得した認証情報を使用して、Lake FormationでデータレイクにアクセスするためのIAMロールを作成し、IAMロールに権限を付与しています。そして、Glue Jobを実行して、データレイク内のデータを加工しています。このように、Lake FormationとSecrets Managerを組み合わせることで、データレイクのセキュリティを強化しながら、アプリケーションが必要な情報にアクセスできるようにすることができます。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?