ablog

不器用で落着きのない技術者のメモ

Google Chromeで複数AWSアカウントに同時にサインインして操作を行う方法

Google Chrome の右上のユーザーを選択し、追加をクリックする。
f:id:yohei-a:20210115091933p:plain
ユーザー名を入力、アイコンを選択してユーザーを追加する。
f:id:yohei-a:20210115091948p:plain
それぞれのユーザーでログインしておけば、AWSアカウントでサインイン/サインインアウトしなくても同時に複数アカウントにサインインしたままでマネジメントコンソールの操作が可能。
f:id:yohei-a:20210115092003p:plain
ユーザーごとにテーマを変えておくと操作ミス防止に良さそう。
f:id:yohei-a:20210115092613p:plain

AWS Glue の glueContext で spark.conf.set() する方法

Glue Spark ジョブや Jupyter Notebook の glueContext で spark.conf.set() する方法

import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext, SparkConf ★
from awsglue.context import GlueContext
from awsglue.job import Job

conf = SparkConf().set("spark.sql.parquet.enableVectorizedReader", "false") ★
sc = SparkContext.getOrCreate(conf=conf) ★
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init('job01')

Amazon Redshift から Amazon S3 へ UNLOAD 時に s3:ListBucket 権限が必要

Amazon Redshift から Amazon S3 へ UNLOAD 時には s3:PutObject 権限だけでよさそうだが、s3:ListBucket 権限も必要。allowoverwrite オプションをつけている場合は s3:PutObject 権限のみで UNLAOD できるが、allowoverwrite オプションをつけていない場合は s3:ListBucket を実行している模様。

s3:PutObject 権限のみの場合

  • allowoverwrite オプションありは成功
dev=# unload ('select * from customer')
dev-# to 's3://redshift-unload-copy/'
dev-# allowoverwrite
dev-# iam_role 'arn:aws:iam::234567890123:role/RedshiftUnloadCopy';

INFO:  UNLOAD completed, 210000000 record(s) unloaded successfully.
UNLOAD
  • allowoverwrite オプションなしはエラー
dev=# unload ('select * from customer')
dev-# to 's3://redshift-unload-copy/'
dev-# iam_role 'arn:aws:iam::234567890123:role/RedshiftUnloadCopy';
ERROR:  S3ServiceException:Access Denied,Status 403,Error AccessDenied,Rid ...,ExtRid ...,CanRetry 1
DETAIL:
  -----------------------------------------------
  error:  S3ServiceException:Access Denied,Status 403,Error AccessDenied,Rid ...,ExtRid ...,CanRetry 1
  code:      8001
  context:   Listing bucket=redshift-unload-copy prefix= ★ Listing bucket でエラー
  query:     0
  location:  s3_utility.cpp:839
  process:   padbmaster [pid=20827]
  -----------------------------------------------

s3:ListBucket 権限を付与

  • s3:ListBucket 権限を付与すると、allowoverwrite オプションなしでも成功
dev=# unload ('select * from customer')
dev-# to 's3://redshift-unload-copy/'
dev-# iam_role 'arn:aws:iam::234567890123:role/RedshiftUnloadCopy';
INFO:  UNLOAD completed, 210000000 record(s) unloaded successfully.
UNLOAD

参考

3. IAM ロールを作成したら、バケットへのアクセス許可を付与するポリシーをアタッチします。次の例のように、ポリシーを使用できます。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1234537676482",
      "Action": [
        "s3:ListBucket",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::awsexamplebucket/*",
        "arn:aws:s3:::awsexamplebucket"
      ]
    }
  ]
}
クロスアカウント Amazon Redshift データファイルからの S3 Access Denied エラーを回避する

GitHub で2要素認証を有効化したら、git コマンドで push できない

事象

  • GitHub で2要素認証を有効化したら、git コマンドで push できない。

原因

  • 2要素認証を有効化すると、git コマンドではパスワードではなく Personal access tokens で認証を行うため。

解決策

Personal access tokens を生成
  • ブラウザで GitHub にログインする。
  • [右上のアイコン]-[Settings] をクリック。
  • [左ペイン]-[Developer Settings] をクリック。
  • [左ペイン]-[Personal access tokens] をクリック。
  • [Generate new token] をクリック、生成されたトークン文字列を保存する。

Personal access tokens を使って認証

$ git clone https://github.com/yoheia/myrepository.git      
Cloning into 'myrepository'...
Username for 'https://github.com': yoheia
Password for 'https://yoheia@github.com': <Personal access tokens を入力>

GitHub に push すると "error: src refspec master does not match any."、"error: failed to push some refs to" と怒られる

事象

  • GitHub に push すると "error: src refspec master does not match any."、"error: failed to push some refs to" と怒られる。
$ git push origin master 
error: src refspec master does not match any.
error: failed to push some refs to 'git@github.com:yoheia/myrepository.git'

解決策

$ git push origin main

AWS Glue で Amazon S3 にある Parquet を Amazon DynamoDB にロードする

AWS Glue で Amazon S3 にある Parquet を Amazon DynamoDB にロードしてみた。

  • DynamoDB にテーブルを作成する。
    • プライマリキーの項目名と型を設定する。
  • Parquet ファイルを S3 バケットにアップロードする。
  • AWS Glue でクロールしてテーブルを作成する。
  • Glue Spark ジョブを作成する。
import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job

## @params: [JOB_NAME]
args = getResolvedOptions(sys.argv, ['JOB_NAME'])

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)
## @type: DataSource
## @args: [database = "default", table_name = "timeseries", transformation_ctx = "datasource0"]
## @return: datasource0
## @inputs: []
datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "default", table_name = "timeseries", transformation_ctx = "datasource0")
## @type: ApplyMapping
## @args: [mapping = [("ts", "long", "ts", "long"), ("col1", "double", "col1", "double"), ("col2", "double", "col2", "double"), ("col3", "double", "col3", "double")], transformation_ctx = "applymapping1"]
## @return: applymapping1
## @inputs: [frame = datasource0]
applymapping1 = ApplyMapping.apply(frame = datasource0, mappings = [(ts", "long", "ts", "long"), ("col1", "double", "col1", "double"), ("col2", "double", "col2", "double"), ("col3", "double", "col3", "double")], transformation_ctx = "applymapping1")

datasink2 = glueContext.write_dynamic_frame_from_options(
    frame=applymapping1,
    connection_type="dynamodb",
    connection_options={
        "dynamodb.output.tableName": "timeseries",
        "dynamodb.throughput.write.percent": "1.0"
    }
)

job.commit()

Glue ジョブを実行すると DynamoDB のテーブルにデータがロードされた。

AWS Glue で Amazon S3 にある CSV を Amazon DynamoDB にロードする

AWS Glue の Spark ジョブで Amazon S3 にある CSVAmazon DynamoDB にロードしてみた。

  • src_table.csv を作成する。
x
y
z
  • src_table.csv を S3 バケットにアップロードする。
  • AWS Glue のクローラでアップロードした CSV をクロールしてテーブルを作成する。
  • Glue Spark ジョブを作成する。
    • ジョブ名: csv2ddb_job
    • Type: Spark
    • Glue Version: Spark 2.4, Python 3 (Glue Version 2.0)
import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job

## @params: [JOB_NAME]
args = getResolvedOptions(sys.argv, ['JOB_NAME'])

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)

datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "test", table_name = "test_src_table_csv", transformation_ctx = "datasource0")

applymapping1 = ApplyMapping.apply(frame = datasource0, mappings = [("key", "string", "key", "string")], transformation_ctx = "applymapping1")

datasink2 = glueContext.write_dynamic_frame_from_options(
    frame=applymapping1,
    connection_type="dynamodb",
    connection_options={
        "dynamodb.output.tableName": "src_table",
        "dynamodb.throughput.write.percent": "1.0"
    }
)

job.commit()
  • 作成したジョブを実行すると DynamoDB のテーブルにデータがロードされた。