file-typeでファイルのMIME Typeを取得する
概要
npmパッケージの file-type を利用して、ファイルのMIME Typeを取得します。
内容
- パッケージのインストール
$ npm install file-type
- ファイルから取得
const fileType = require('file-type') (async () => { const ft = await fileType.fromFile('path/to/file') console.log(ft) // { ext: 'xxx', mime: 'xxx/xxx' } })()
- バッファから取得
const fs = require('fs') const fileType = require('file-type') (async () => { const ft = await fileType.fromBuffer(fs.readFileSync('path/to/file')) console.log(ft) // { ext: 'xxx', mime: 'xxx/xxx' } })()
- ストリームから取得
const fs = require('fs') const fileType = require('file-type') (async () => { const ft = await fileType.fromStream(fs.createReadStream('path/to/file')) console.log(ft) // { ext: 'xxx', mime: 'xxx/xxx' } })()
- URLから取得
const fileType = require('file-type') // npm install node-fetch const fetch = require('node-fetch') (async () => { const res = fetch('https://placehold.jp/150x150.png') const ft = await fileType.fromStream(res.body) console.log(ft) // { ext: 'png', mime: 'image/png' } })()
備考
CloudWatch Logsに出力したログをログストリーム名でフィルタする
概要
AWS ECSでコンテナのログをCloudWatch Logsに出力している場合、CloudWatch Logs Insightsを利用すると様々な条件でフィルタすることができる。 今回は、ログストリーム名でフィルタするクエリ構文を記載します。
クエリ構文
- 対象のログストリームが1つの場合
fields @timestamp, @message | filter @logStream = '${ログストリーム名}' | sort @timestamp desc | limit 100
- 対象のログストリームが複数の場合
fields @timestamp, @message | filter @logStream in ['${ログストリーム名1}', '${ログストリーム名2}', '${ログストリーム名3}', ...] | sort @timestamp desc | limit 100
参考
Lambda Layersで最新バーションのAWS SDKを利用できるようにする
はじめに
Lambdaで最新バージョンのAWS SDKを利用したい場合に、Lambda Layersを用いた方法を記載します。
AWS SDKのバージョンを確認する
利用されているAWS SDKのバージョンを確認しておきます。
- Lambda Execution Roleの作成
$ aws iam create-role \ --role-name lambda-ex \ --assume-role-policy-document \ file://trust-policy.json
trust-policy.jsonの内容は以下の通り。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
作成したIAM Roleに「AWSLambdaBasicExecutionRole」ポリシーをアタッチします。
$ aws iam attach-role-policy \ --role-name lambda-ex \ --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- Lambda関数の作成
関数を作成して、ファイル名をindex.jsとして保存します。
const AWS = require('aws-sdk') exports.handler = async (event) => { return AWS.VERSION }
デプロイパッケージを作成します。
$ zip function.zip index.js
Lambda関数を作成します。
$ aws lambda create-function \ --function-name get-aws-sdk-nodejs-version \ --zip-file fileb://function.zip \ --handler index.handler \ --runtime nodejs14.x \ --role <LAMBDA_EXEC_ROLE_ARN>
- Lambda関数を実行します。
$ aws lambda invoke \ --function-name get-aws-sdk-nodejs-version \ --log-type Tail \ version-before $ cat version-before "2.804.0"
Lambda Layerの作成
次に、最新バージョンのAWS SDKのLayerを作成します。
デプロイパッケージは、Lambda環境と互換性がある必要があり、Lambdaランタイムと一致するOSを利用することが推奨されているようです。
ここでは、amazonlinux2のdockerイメージを利用してデプロイパッケージを作成します。
- dockerコンテナの起動
$ docker run -it --rm -v $(pwd):/tmp/aws-sdk-layer amazonlinux
- デプロイパッケージの作成
# amazon-linux-extras install -y epel # yum -y install nodejs zip # mkdir nodejs # cd nodejs # npm install aws-sdk # zip -r /tmp/aws-sdk-layer/package.zip ../nodejs # exit
- Lambda Layerの作成
aws lambda publish-layer-version \ --layer-name aws-sdk-nodejs \ --description "aws sdk nodejs 2.868.0" \ --license-info "MIT" \ --compatible-runtimes nodejs14.x \ --zip-file fileb://./package.zip
- Lambda関数にLayerを適用する
$ aws lambda update-function-configuration \ --function-name get-aws-sdk-nodejs-version \ --layers <LAYER_ARN>
Lambda Layerの適用を確認する
- Lambda関数の実行
$ aws lambda invoke \ --function-name get-aws-sdk-nodejs-version \ --log-type Tail \ version-after $ cat version-after "2.868.0"
参考
Amazon ECS Execを試してみる
はじめに
AWS Fargate上のコンテナに対して対話型のシェル、または、任意のコマンドを実行できるようになったようなので、試してみる。
手順などは、以下に記載のものをそのままなぞってます。
AWS CLI v1のインストール
現時点では、AWS CLI v1のみの対応(v2も数週間以内に対応)のようなので、v1をインストールします。 すでにv2をインストール済みだったため、以下の記事を参考にして、v2とv1を共存させるようにしてます。
$ curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip" $ unzip awscli-bundle.zip $ sudo ./awscli-bundle/install -i /usr/local/aws-cli-v1 -b /usr/local/bin/aws-v1 $ aws-cli/1.19.29 Python/3.8.0 Darwin/19.6.0 botocore/1.20.29
ECSタスクを起動する
上記の手順だと、VPCとそのVPCに含まれる2つのパブリックサブネットが存在していることが前提のようなので、作成しておきます。
- VPCの作成
$ aws-v1 ec2 create-vpc \ --cidr-block 172.16.0.0/16
$ aws-v1 ec2 create-internet-gateway $ aws-v1 ec2 attach-internet-gateway \ --internet-gateway-id <INTERNET_GATEWAY_ID> \ --vpc-id <VPC_ID>
- サブネットとRoute Tableの作成、その関連付け
$ aws-v1 ec2 create-subnet \ --vpc-id <VPC_ID>\ --cidr-block 172.16.0.0/24 \ --availability-zone ap-northeast-1a $ aws-v1 ec2 create-subnet \ --vpc-id <VPC_ID> \ --cidr-block 172.16.1.0/24 \ --availability-zone ap-northeast-1c $ aws-v1 ec2 create-route-table \ --vpc-id <VPC_ID> $ aws-v1 ec2 create-route \ --route-table-id <ROUTE_TABLE_ID> \ --destination-cidr-block 0.0.0.0/0 \ --gateway-id <INTERNET_GATEWAY_ID> $ aws-v1 ec2 associate-route-table \ --route-table-id <ROUTE_TABLE_ID> \ --subnet-id <SUBNET1_ID> $ aws-v1 ec2 associate-route-table \ --route-table-id <ROUTE_TABLE_ID> \ --subnet-id <SUBNET2_ID>
ここからは、ほぼ手順の通りに。。。
- KMSキー作成
$ aws-v1 kms create-key \ --region=ap-northeast-1 $ aws-v1 kms create-alias \ --alias-name alias/ecs-exec-demo-kms-key \ --target-key-id <KMS_KEY_ID> \ --region ap-northeast-1
- ECSクラスターの作成
$ aws-v1 ecs create-cluster \ --cluster-name ecs-exec-demo-cluster \ --region ap-northeast-1 \ --configuration executeCommandConfiguration="{ logging=OVERRIDE, \ kmsKeyId=<KMS_KEY_ID>, \ logConfiguration={ \ cloudWatchLogGroupName="/aws/ecs/ecs-exec-demo", \ s3BucketName=ecs-exec-demo-output-xxxxxxxxxx, \ s3KeyPrefix=exec-output \ } \ }"
- CloudWatch ロググループの作成
$ aws-v1 logs create-log-group \ --log-group-name /aws/ecs/ecs-exec-demo \ --region ap-northeast-1
- S3バケットの作成
$ aws-v1 s3api create-bucket \ --bucket ecs-exec-demo-output-xxxxxxxxxx \ --region ap-northeast-1 \ --create-bucket-configuration LocationConstraint=ap-northeast-1
- セキュリティグループの作成
$ aws-v1 ec2 create-security-group \ --group-name ecs-exec-demo-SG \ --description "ECS exec demo SG" \ --vpc-id <VPC_ID> \ --region ap-northeast-1 $ aws-v1 ec2 authorize-security-group-ingress \ --group-id <SECURITY_GROUP_ID> \ --protocol tcp \ --port 80 \ --cidr 0.0.0.0/0 \ --region ap-northeast-1
TCP80番ポートへのアクセスを許可しています。
- IAMロールの作成
$ aws-v1 iam create-role \ --role-name ecs-exec-demo-task-execution-role \ --assume-role-policy-document file://ecs-tasks-trust-policy.json \ --region ap-northeast-1 $ aws-v1 iam create-role \ --role-name ecs-exec-demo-task-role \ --assume-role-policy-document file://ecs-tasks-trust-policy.json \ --region ap-northeast-1
ECS Task Execution RoleとECS Task Roleをそれぞれ作成しています。
ecs-tasks-trust-policy.jsonの内容は以下の通り。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ecs-tasks.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }
- ECS Task Execution Roleへポリシーを追加
$ aws-v1 iam attach-role-policy \ --role-name ecs-exec-demo-task-execution-role \ --policy-arn "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
- ECS Task Roleへ権限を追加
$ aws-v1 iam put-role-policy \ --role-name ecs-exec-demo-task-role \ --policy-name ecs-exec-demo-task-role-policy \ --policy-document file://ecs-exec-demo-task-role-policy.json
ecs-exec-demo-task-role-policy.jsonの内容は以下の通り
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ssmmessages:CreateControlChannel", "ssmmessages:CreateDataChannel", "ssmmessages:OpenControlChannel", "ssmmessages:OpenDataChannel" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "logs:DescribeLogGroups" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:DescribeLogStreams", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:ap-northeast-1:<AWS_ACCOUNT_ID>:log-group:/aws/ecs/ecs-exec-demo:*" }, { "Effect": "Allow", "Action": [ "s3:PutObject" ], "Resource": "arn:aws:s3:::ecs-exec-demo-output-xxxxxxxxxx/*" }, { "Effect": "Allow", "Action": [ "s3:GetEncryptionConfiguration" ], "Resource": "arn:aws:s3:::ecs-exec-demo-output-xxxxxxxxxx" }, { "Effect": "Allow", "Action": [ "kms:Decrypt" ], "Resource": <KMS_KEY_ARN> } ] }
- ECS タスク定義の追加
$ aws-v1 ecs register-task-definition \ --cli-input-json file://ecs-exec-demo.json \ --region ap-northeast-1
ecs-exec-demo.jsonの内容は以下の通り。
{ "family": "ecs-exec-demo", "networkMode": "awsvpc", "executionRoleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ecs-exec-demo-task-execution-role", "taskRoleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ecs-exec-demo-task-role", "containerDefinitions": [ { "name": "nginx", "image": "nginx", "linuxParameters": { "initProcessEnabled": true }, "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/aws/ecs/ecs-exec-demo", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "container-stdout" } } } ], "requiresCompatibilities": [ "FARGATE" ], "cpu": "256", "memory": "512" }
- ECSタスクの起動、その確認
$ aws-v1 ecs run-task \ --cluster ecs-exec-demo-cluster \ --task-definition ecs-exec-demo \ --network-configuration awsvpcConfiguration=" \ { \ subnets=[<SUBNET1_ID>, <SUBNET2_ID>], \ securityGroups=[<SECURITY_GROUP_ID>], \ assignPublicIp=ENABLED \ }" \ --enable-execute-command \ --launch-type FARGATE \ --tags key=environment,value=production \ --platform-version '1.4.0' \ --region ap-northeast-1 $ aws-v1 ecs describe-tasks \ --cluster ecs-exec-demo-cluster \ --region ap-northeast-1 \ --tasks <TASK_ID>
- nginxへのアクセス
ECSタスクに設定されたパブリックをIPを取得して、
$ aws-v1 ec2 describe-network-interfaces \ --network-interface-ids <NETWORK_INTERFACE_ID>
アクセスすると nginxのデフォルトのページが取得できます。
$ curl http://<PUBLIC_IP> <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
ECS Execで対話型のシェルを実行する
aws-v1 ecs execute-command \ --region ap-northeast-1 \ --cluster ecs-exec-demo-cluster \ --task <TASK_ID> \ --container nginx \ --command "/bin/bash" \ --interactive The Session Manager plugin was installed successfully. Use the AWS CLI to start a session. Starting session with SessionId: ecs-execute-command-xxxxxxxxxxxxxxxxx This session is encrypted using AWS KMS. root@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxx:/# hostname xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxx root@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxx:/# whoami root root@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxx:/# ls bin docker-entrypoint.d home managed-agents opt run sys var boot docker-entrypoint.sh lib media proc sbin tmp dev etc lib64 mnt root srv usr root@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxx:/# echo "This page has been created with ECS Exec" > /usr/share/nginx/html/index.html root@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxx:/# exit exit Exiting session with sessionId: ecs-execute-command-xxxxxxxxxxxxxxxxx
ECS Execで任意のコマンドを実行する
$ aws-v1 ecs execute-command \ --region ap-northeast-1 \ --cluster ecs-exec-demo-cluster \ --task <TASK_ID> \ --container nginx \ --command "ls" \ --interactive The Session Manager plugin was installed successfully. Use the AWS CLI to start a session. Starting session with SessionId: ecs-execute-command-xxxxxxxxxxxxxxxxx This session is encrypted using AWS KMS. bin docker-entrypoint.d home managed-agents opt run sys var boot docker-entrypoint.sh lib media proc sbin tmp dev etc lib64 mnt root srv usr Exiting session with sessionId: ecs-execute-command-xxxxxxxxxxxxxxxxx
作成したリソースを削除する
$ aws-v1 ecs stop-task \ --cluster ecs-exec-demo-cluster \ --region ap-northeast-1 \ --task <TASK_ID> $ aws-v1 ecs delete-cluster \ --cluster ecs-exec-demo-cluster \ --region ap-northeast-1 $ aws-v1 logs delete-log-group \ --log-group-name /aws/ecs/ecs-exec-demo \ --region ap-northeast-1 $ aws-v1 s3 rm s3://ecs-exec-demo-output-xxxxxxxxxx \ --recursive $ aws-v1 s3api delete-bucket \ --bucket ecs-exec-demo-output-xxxxxxxxxx $ aws-v1 iam detach-role-policy \ --role-name ecs-exec-demo-task-execution-role \ --policy-arn "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" $ aws-v1 iam delete-role \ --role-name ecs-exec-demo-task-execution-role $ aws iam delete-role-policy \ --role-name ecs-exec-demo-task-role \ --policy-name ecs-exec-demo-task-role-policy $ aws-v1 iam delete-role \ --role-name ecs-exec-demo-task-role $ aws-v1 kms schedule-key-deletion \ --key-id <KMS_KEY_ID> \ --region ap-northeast-1 \ --pending-window-in-days 7 $ aws-v1 kms delete-alias \ --alias-name alias/ecs-exec-demo-kms-key $ aws-v1 ec2 delete-security-group \ --group-id <SECURITY_GROUP_ID> \ --region ap-northeast-1 $ aws-v1 ec2 disassociate-route-table \ --association-id <SUBNET1_ASSOCIATION_ID> $ aws-v1 ec2 disassociate-route-table \ --association-id <SUBNET2_ASSOCIATION_ID> $ aws-v1 ec2 delete-route-table \ --route-table-id <ROUTE_TABLE_ID> $ aws-v1 ec2 delete-subnet \ --subnet-id <SUBNET1_ID> $ aws-v1 ec2 delete-subnet \ --subnet-id <SUBNET2_ID> $ aws-v1 ec2 detach-internet-gateway \ --internet-gateway-id <INTERNET_GATEWAY_ID> \ --vpc-id <VPC_ID> $ aws-v1 ec2 delete-internet-gateway \ --internet-gateway-id <INTERNET_GATEWAY_ID> $ aws-v1 ec2 delete-vpc \ --vpc-id <VPC_ID>
さいごに
ECS Execを試すところより、ECSタスクを起動する手順のほうが多かったですが、ECS Fargate上のコンテナにアクセスできることが確認できました。
環境構築時や開発中など、Fargate上のコンテナに簡単にアクセスできればなぁと思うことも、それなりあったので、今後は活用できそうです。
AWS CLIでページ分割を無効にする
概要
AWS CLI バージョン2では、コマンドラインオプション、config、環境変数などを利用して、ページ分割を無効化できる
ページ分割の無効化
- コマンドラインオプションで指定する場合
$ aws ec2 describe-images --owners self amazon --no-cli-pager
- configで指定する場合
configファイル(~/.aws/config)にcli_pager
の指定を追加
[default] region = ap-northeast-1 cli_pager =
$ aws ec2 describe-images --owners self amazon
- 環境変数で指定する場合
$ AWS_PAGER= aws ec2 describe-images --owners self amazon