1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Glue Python ShellでAWS Secrets Manager+キーペア認証を使い、Snowflakeに接続する方法

Last updated at Posted at 2025-06-24

はじめに

Snowflakeはセキュリティ強化の一環として多要素認証(MFA)の強制導入が進められており、2025年11月までに全ユーザーへのMFAが義務化される予定です。
これにより、従来のパスワード認証だけでは不十分となり、より安全性の高い認証方式への移行が急務となっています。

この記事では、AWS Glue Python Shell ジョブからSnowflakeに対して、パスワードではなくキーペア認証を用い、さらに接続情報そのものはAWS Secrets Managerによって秘匿化する方法をステップごとに解説します。

注意事項

  • 2025年6月時点の情報で記載しております。

この記事で書くこと

・WSLでキーペアを作成する方法
・Snowsightで公開鍵をユーザーに紐づける方法
・AWS Glue Python ShellでSnowflakeに接続する方法
・セキュリティ強化のためにやっておきたいこと(推奨)
・AWSからPrivateLink経由でSnowflakeに接続する(補足)

前提条件
・WSL2インストール済みでLinux環境が動かせる
・Glueの実行ロールに十分な権限が付与されている
・インターネット経由での接続である

WSLでのキーペア作成方法

  1. 以下のOpenSSLコマンドを使い、キーペアを生成し、パスフレーズをメモします。
    # 秘密鍵
    openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 des3 -inform PEM -out rsa_key.p8
    ※パスフレーズ作成がある
    
    # 公開鍵
    openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
    ※上記で作成したパスフレーズを入力する
    
     
  2. 以下のOpenSSLコマンドを使い、公開鍵のフィンガープリントを出力&メモします。
    # 公開鍵のフィンガープリント確認
    openssl rsa -pubin -in rsa_key.pub -outform DER | openssl dgst -sha256 -binary | openssl enc -base64
    
    # 出力例(Base64表記)
    mF1y8G7+3pV9u3Pc6hXn8T1Yj7G+QH8Sq9Pp0h3l9j47
    
     
  3. 上記で作成した公開鍵「rsa_key.pub」の、以下のxxxxxxxxx部分をメモします。
    -----BEGIN PUBLIC KEY-----
    xxxxxxxxx
    xxxxxxxxx
    -----END PUBLIC KEY-----
    
     
  4. 上記で作成した秘密鍵「rsa_key.p8」の、以下のxxxxxxxxx部分をメモします。
    -----BEGIN ENCRYPTED PRIVATE KEY-----
    xxxxxxxxx
    xxxxxxxxx
    -----END ENCRYPTED PRIVATE-----
    

Snowsightで公開鍵をユーザーに紐づける方法

  1. 以下のSQLで、公開鍵をSnowflakeの新規ユーザーか既存ユーザーに紐づける

    -- 新規ユーザーに紐づける
    CREATE USER NEW_USER
      TYPE = SERVICE
      RSA_PUBLIC_KEY = 'WSLでのキーペア作成方法の3.でメモしたxxxxxxxxx部分'
    
    -- 既存ユーザーに紐づける
    ALTER USER EXISTING_USER
      SET RSA_PUBLIC_KEY = 'WSLでのキーペア作成方法の3.でメモしたxxxxxxxxx部分'
    

     

  2. 以下のSQLで、紐づけた公開鍵のフィンガープリントを抜き出す

    -- 新規 or 既存ユーザーのプロパティ一覧を取得
    DESC USER '<NEW_USER か EXISTING_USER>';
    
    -- プロパティ一覧を取得したクエリから、フィンガープリントを抜き出す
    SELECT
      TRIM(
        (SELECT "value"
          FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
          WHERE "property" = 'RSA_PUBLIC_KEY_FP'),
           'SHA256:'
          );
    

     

  3. WSLでのキーペア作成方法の2.でメモしたフィンガープリントと一致しているか確認する
    フィンガープリントが一致しない場合、上記の作業を見直してください。

AWS Glue Python ShellでSnowflakeに接続する方法

  1. Secrets ManagerでSnowflakeのユーザー情報と秘密鍵を秘匿化する

Secrets Managerの作成画面
上の画像のように、「その他のシークレットのタイプ」を選び、以下のキー/値を入力する

user='<ユーザー名>'
account='<アカウント識別子>'
warehouse='<ウェアハウス名>'
database='<データベース名>'
schema='<スキーマ名>'
role='<ロール名(省略可)>'
private_key='<WSLでのキーペア作成方法の4.でメモしたxxxxxxxxx部分>'
private_key_passphrase='<WSLでのキーペア作成方法の1.でメモしたパスフレーズ>'

 
2. Additional Python modules pathにスクリプトで使うモジュールを記載

glueのjob details
上の画像のように、Additional Python modules pathに以下のモジュールを入力する

snowflake-connector-python==3.13.2,cryptography==40.0.2

※バージョンは現時点で動作確認ができているものである点に注意
 
3. AWS Glue Python Shell スクリプトを作成する

以下はサンプルスクリプトです。

import json
import sys
import base64
import boto3
import snowflake.connector
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
from botocore.exceptions import ClientError

# Secrets Manager から取得
def get_secret():
   secret_name = "キーペアの作成方法の4.でメモしたxxxxxxxxx部分"
   region_name = "Secrets Managerを作成したリージョン名"
    
   session = boto3.session.Session()
   client = session.client(servicename='secretsmanager', region_name=region_name)

   try:
      response = client.get_secret_value(SecretId=secret_name)
   except ClientError as e:
      raise Exception(f"シークレットの取得に失敗しました: {e}")

   secret = response['SecretString']
   return json.loads(secret)
   
try:
creds = get_secret()
encrypted_der_key = base64.b64decode(creds["private_key"])

private_key = serialization.load_der_private_key(
   data=encrypted_der_key,
   password=creds["private_key_passphrase"].encode(),
   backend=default_backend()
)

private_key_bytes = private_key.private_bytes(
   encoding=serialization.Encoding.DER,
   format=serialization.PrivateFormat.PKCS8,
   encryption_algorithm=serialization.NoEncryption()
)

conn = snowflake.connector.connect(
    user=creds['user'],
    account=creds['account'],
    warehouse=creds['warehouse'],
    database=creds['database'],
    schema=creds['schema'],
    role=creds['role'],
    private_key=private_key_bytes
)

cs = conn.cursor()
cs.execute("SELECT CURRENT_VERSION()")

for row in cs:
   print(row)

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

finally:
try:
   cs.close()
   conn.close()
except:
   pass

※上記で上手くいかない場合、Glueを実行するIAMロールに適切な権限が設定されているか確認してみてください。

セキュリティ強化のためにやっておきたいこと(推奨)

本記事の手順に加えて、以下の内容を実行するとよりセキュアです。

・Glueの実行ロールにだけ、対象のSecretに限定して権限を付与する
private_key_passphraseを、別のSecrets Managerに分離する
・キーペアのローテーションを定期的に行う

AWSからPrivateLink経由でSnowflakeに接続する(補足)

本記事のようにAWS GlueからSnowflakeに接続する際、上記のようなインターネット経由ではなく、AWS内のプライベートネットワークで完結するPrivateLink接続を使用することで、さらなるセキュリティ強化が可能です。

PrivateLink
AWS PrivateLinkは、VPC内からAWSサービスや他のAWSアカウントのサービスに対して インターネットを介さずプライベートに接続する仕組みです。
SnowflakeはPrivateLinkに対応しており、厳しいセキュリティ要件を満たす必要がある場合に有効です。

AWSからPrivateLink経由でSnowflakeに接続する方法については、以下の記事が参考になります。

参照記事

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?