amazon.com のアカウントで利用できる Amazon Web Services (AWS) に関する操作を Web 画面からだけでなくコマンドラインツールからも行うために必要な知識をまとめます。AWS 全般を対象とした汎用的なコマンドラインツールの解説です。似たものに EC2 に特化した Java ベースのコマンドラインツールツールが存在しています。混乱しないように注意してください。
Identity and Access Management (IAM) は限定的な権限をもったユーザを作成および管理するための仕組みです。コマンドラインツールから AWS を操作するときには IAM ユーザを事前に作成し、そのユーザの権限で処理を実行します。こちら の手順で IAM ユーザを作成して認証情報 (Access Key ID, Secret Access Key) を用意しましょう。
UNIX 系 OS にシステムインストールする手順を抜粋して記載します。その他のインストールパターンについてはこちらをご覧ください。Python 2.6.3 以降が必要です。
python --version
ダウンロードおよび解凍
curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
unzip awscli-bundle.zip
/usr/local/aws にインストールして実行ファイルへのシンボリックリンクは /usr/local/bin/aws として作成
sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
ヘルプは以下のようにして閲覧できます。
./awscli-bundle/install -h
問題なくインストールできたら以下のコマンドが有効になります。
aws help
基本的な用途であれば以下のコマンドにしたがって設定するだけです。
aws configure
設定内容は以下のファイルに格納されます。
簡易的には、以下のように環境変数に設定することもできます。
export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
正しく設定されていれば以下のコマンドが有効になります。
aws ec2 describe-regions
IAM ユーザが EC2 操作権限のあるグループに所属していなければ
A client error (UnauthorizedOperation) occurred when calling the DescribeRegions operation: You are not authorized to perform this operation.
などと表示されます。グループを作成して IAM ユーザを所属させましょう。また、プロキシ設定のためには環境変数を追加します。
aws ec2 create-security-group --group-name MySecurityGroup --description "My security group"
aws ec2 delete-security-group --group-name MySecurityGroup
TCP 22 番ポートをすべてのホストに対して開放する例 (authorize-security-group-ingress)
aws ec2 authorize-security-group-ingress --group-name MySecurityGroup --protocol tcp --port 22 --cidr 0.0.0.0/0
aws ec2 revoke-security-group-ingress --group-name MySecurityGroup --protocol tcp --port 22 --cidr 0.0.0.0/0
aws ec2 create-key-pair --key-name my-key-pair
何らかの手段で my-key-pair.pem を作成します。
chmod 400 my-key-pair.pem
aws ec2 delete-key-pair --key-name my-key-pair
aws ec2 run-instances --image-id ami-cbf90ecb \
--count 1 --instance-type t2.micro --key-name my-key-pair \
--security-groups MySecurityGroup
インスタンス ID 一覧の取得例 (describe-instances)
aws ec2 describe-instances --filters "Name=instance.group-name,Values=MySecurityGroup" \
--output text | grep ^INSTANCES | cut -f8
i-30f3b9c3
i-d4f4be27
名前タグを付与します (create-tags)
aws ec2 create-tags --tags Key=Name,Value=myInstance --resources \
`aws ec2 describe-instances --filters "Name=instance.group-name,Values=MySecurityGroup" \
--output text | grep ^INSTANCES | cut -f8 | tr '\n' ' '`
接続してみましょう。
ssh -i my-key-pair.pem ec2-user@xxx.xxx.xxx.xxx
即時削除されます。実行時には注意しましょう (terminate-instances)
aws ec2 terminate-instances --instance-ids \
`aws ec2 describe-instances --filters "Name=instance.group-name,Values=MySecurityGroup" \
--output text | grep ^INSTANCES | cut -f8 | tr '\n' ' '`
jq チートシートをご参照ください。
us-west-2
リージョンにある my-us-west-2-bucket
バケット内のオブジェクトを us-east-1
リージョンにある my-us-east-1-bucket
バケット内にコピーします。更に --delete
によってコピー先バケットにあるオブジェクトのうちコピー元バケットにないオブジェクトは、コピー先バケットから削除します。
aws s3 sync s3://my-us-west-2-bucket s3://my-us-east-1-bucket --source-region us-west-2 --region us-east-1 --delete
並列処理の設定を変更することで高速化できます。特に、マルチパートアップロードは断片が残存する危険性があるためなるべく使用しないようにする場合の例です。
aws configure set default.s3.max_concurrent_requests 256
aws configure set default.s3.max_queue_size 100000
aws configure set default.s3.multipart_threshold 5GB
aws configure set default.s3.multipart_chunksize 5GB
Windows の awscli は SJIS/cp932 で動作するように設定されています。Git Bash 等のターミナルで UTF-8 で処理する必要がある場合は、以下の方法で対処できます。
AWSCLIV2.msi (c:/Program Files/Amazon/AWSCLIV2/aws.exe)
C:\Users\username>aws s3 ls s3://mybucket-20211017/
2021-10-17 13:34:52 0 日本語.txt
Python3
C:\Users\username>python -m awscli s3 ls s3://mybucket-20211017/
2021-10-17 13:34:52 0 日本語.txt
Python2
C:\Users\username>python2 -m awscli s3 ls s3://mybucket-20211017/
C:\Python27\lib\site-packages\dateutil\parser\_parser.py:1183: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
elif res.tzname and res.tzname in time.tzname:
2021-10-17 13:34:52 0 日本語.txt
AWSCLIV2.msi
$ aws s3 ls s3://mybucket-20211017/
2021-10-17 13:34:52 0 ▒▒▒{▒▒.txt
Python3
$ python -m awscli s3 ls s3://mybucket-20211017/
2021-10-17 13:34:52 0 ▒▒▒{▒▒.txt
Python2
$ python2 -m awscli s3 ls s3://mybucket-20211017/
2021-10-17 13:34:52 0 ???.txt
C:\Python27\lib\site-packages\dateutil\parser\_parser.py:1183: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
elif res.tzname and res.tzname in time.tzname:
AWSCLIV2.msi
$ aws s3 ls s3://mybucket-20211017/ | iconv -f CP932 -t UTF-8
2021-10-17 13:34:52 0 日本語.txt
Python3
$ python -m awscli s3 ls s3://mybucket-20211017/ | iconv -f CP932 -t UTF-8
2021-10-17 13:34:52 0 日本語.txt
PYTHONIOENCODING
環境変数の指定Python3
$ PYTHONIOENCODING=utf-8 python -m awscli s3 ls s3://mybucket-20211017/
2021-10-17 13:34:52 0 日本語.txt
Python2
$ PYTHONIOENCODING=utf-8 python2 -m awscli s3 ls s3://mybucket-20211017/
2021-10-17 13:34:52 0 日本語.txt
c:\Python27\lib\site-packages\dateutil\parser\_parser.py:1183: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
elif res.tzname and res.tzname in time.tzname:
AWSCLIV2.msi
C:\Users\username\Desktop>aws s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt
upload: .\日本語.txt to s3://mybucket-20211017/日本語.txt
Python3
C:\Users\username\Desktop>python -m awscli s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt
upload: .\日本語.txt to s3://mybucket-20211017/日本語.txt
Python2
C:\Users\username\Desktop>python2 -m awscli s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt
upload: .\日本語.txt to s3://mybucket-20211017/日本語.txt
AWSCLIV2.msi
$ aws s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt
upload: .\▒▒▒{▒▒.txt to s3://mybucket-20211017/▒▒▒{▒▒.txt
Python3
$ python -m awscli s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt
upload: .\▒▒▒{▒▒.txt to s3://mybucket-20211017/▒▒▒{▒▒.txt
Python2 の場合に限り、文字化けではなくエラーとなります。
$ python2 -m awscli s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt
'utf8' codec can't decode byte 0x93 in position 0: invalid start byte
AWSCLIV2.msi
$ aws s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt | iconv -f CP932 -t UTF-8
upload: .\日本語.txt to s3://mybucket-20211017/日本語.txt
Python3
$ python -m awscli s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt | iconv -f CP932 -t UTF-8
upload: .\日本語.txt to s3://mybucket-20211017/日本語.txt
PYTHONIOENCODING
環境変数の指定Python3
$ PYTHONIOENCODING=UTF-8 python -m awscli s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt
upload: .\日本語.txt to s3://mybucket-20211017/日本語.txt
Python2 (エラー)
$ PYTHONIOENCODING=UTF-8 python2 -m awscli s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt
'utf8' codec can't decode byte 0x93 in position 0: invalid start byte
$ PYTHONIOENCODING=CP932 python2 -m awscli s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt
upload: .\▒▒▒{▒▒.txt to s3://mybucket-20211017/▒▒▒{▒▒.txt
$ PYTHONIOENCODING=CP932 python2 -m awscli s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt | iconv -f CP932 -t UTF-8
upload: .\日本語.txt to s3://mybucket-20211017/日本語.txt
$ python2 -m awscli --debug s3 cp 日本語.txt s3://mybucket-20211017/日本語.txt
Traceback (most recent call last):
File "c:\Python27\lib\site-packages\awscli\clidriver.py", line 218, in main
return command_table[parsed_args.command](remaining, parsed_args)
File "c:\Python27\lib\site-packages\awscli\customizations\commands.py", line 190, in __call__
parsed_globals)
File "c:\Python27\lib\site-packages\awscli\customizations\commands.py", line 139, in __call__
parsed_args, remaining = parser.parse_known_args(args)
File "c:\Python27\lib\site-packages\awscli\argparser.py", line 200, in parse_known_args
args, namespace)
File "c:\Python27\lib\site-packages\awscli\argparser.py", line 115, in parse_known_args
encoded.append(v.decode(terminal_encoding))
File "c:\Python27\lib\encodings\utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0x93 in position 0: invalid start byte
2021-10-17 14:14:08,292 - MainThread - awscli.clidriver - DEBUG - Exiting with rc 255
'utf8' codec can't decode byte 0x93 in position 0: invalid start byte
awscli\argparser.py
の terminal_encoding = getattr(sys.stdin, 'encoding', 'utf-8')
が None
となっていることが原因です。
def parse_known_args(self, args, namespace=None):
parsed, remaining = super(CLIArgParser, self).parse_known_args(args, namespace)
terminal_encoding = getattr(sys.stdin, 'encoding', 'utf-8') # ここが None となる。
if terminal_encoding is None:
# In some cases, sys.stdin won't have an encoding set,
# (e.g if it's set to a StringIO). In this case we just
# default to utf-8.
terminal_encoding = 'utf-8' # utf-8 がセットされてしまいます。cp932 をセットすると正常に動作します。
for arg, value in vars(parsed).items():
if isinstance(value, six.binary_type):
setattr(parsed, arg, value.decode(terminal_encoding))
elif isinstance(value, list):
encoded = []
for v in value:
if isinstance(v, six.binary_type):
encoded.append(v.decode(terminal_encoding))
else:
encoded.append(v)
setattr(parsed, arg, encoded)
return parsed, remaining