- 投稿日:2021-01-21T22:51:14+09:00
AWS EC2 AMIを利用して構築したRedash9.0(beta)でCloudWatch Logs Insightsのデータを取得する
What's this?
Redash9.0(beta)でデータソースとしてCloudWatch Logs Insightsが新規追加されたので、Redash9.0の構築からデータ取得までの手順をまとめた記事です。
Redashとは
Redashは、(主に)SQLの分析結果をわかりやすく可視化し共有するオープンソースBIツールです。
「RDS」「Redshift」「BigQuery」「Google Spreadsheet」など50種類以上の様々なデータソースと連携が可能で、複数のデータソースのデータを結合させることも可能です。Redash9.0で追加されたデータソース
New Data Sources: Amazon Cloudwatch, Amazon CloudWatch Logs Insights, Azure Kusto, Exasol.
Redash公式のchange logを見るとまだbeta版ですが、9.0から下記データソースが新規で追加されています。
- Amazon Cloudwatch
- Amazon CloudWatch Logs Insights
- Azure Kusto
- Exasol
構築手順
前提
- ローカル環境はmacOS + iTerm2
- AWSアカウントは既に作成済
- CloudWatch Logsにデータが存在している
【手順1】Redash8.0セットアップ
EC2インスタンス作成
Docker on EC2のAMIがRedashの公式から提供されているので、こちらを利用します。
今回は東京リージョンでのインスタンス作成をしたいので、「ap-northeast-1」を選択
次にインスタンスタイプを選択します。
Launch the instance with the pre-baked AMI we create (for small deployments t2.small should be enough):
Redash公式ページでは小規模の開発環境であれば
t2.small
で十分とありましたが、9.0については、t2.small
ではメモリが不十分で上手く動作しなかったため、t2.medium
を選択しました。
どちらのインスタンスタイプも無料枠ではないので注意してください。インスタンスタイプを選択したら、「確認と作成」ボタンを押します。
インスタンス起動前に下記画面が表示されるので、キーペアを作成していない場合は、
任意のキーペア名をつけてキーペアの作成をします。
このとき発行されるキーペアはインスタンスにSSH接続する際に必要になるため安全な場所に保存しておきます。これでインスタンスの作成は完了です。
今回利用したAMIにインストールされているRedashのバージョンは8.0になるので、後ほど9.0へのバージョンアップを行います。セキュリティグループの作成
次にセキュリティグループの作成をします。
下記ポートをインバウンドルールに追加します。
- SSH接続のための22番ポート
- HTTP接続のための80ポート
- HTTPS接続のための443ポート
この際、検証用に利用する方は自宅や職場など特定のIPアドレスのみを許可する設定にしておいた方が安全です。
セキュリティグループの作成が完了したら、先ほど作成したEC2インスタンスとの関連付けを行います。
インスタンス一覧画面に戻り、セキュリティグループを変更します。
作成したセキュリティグループを選択し保存します。
もし余分なセキュリティグループがインスタンスに関連付けされている場合は削除します。
これでセキュリティグループの関連付けは完了です。Elastic IPの作成
今回検証用に有料のインスタンスタイプを利用しているため、利用しない時はインスタンスを停止し費用を抑えたいです。
EC2にデフォルトで付与されるパブリックIPアドレスは停止、再起動の度に変わってしまうため固定IPアドレスを設定します。Elastic IPの新規作成をします。
作成したElastic IPをEC2インスタンスに関連付けます。
これで固定IPの作成とインスタンスへの関連付けの完了です。
この時点でブラウザに発行されたElasticIPアドレスでアクセスするとRedashの管理画面が表示されるはずです。
EC2インスタンスへSSH接続確認
作成したインスタンスにSSH接続できるか確認します。
ここからはローカル環境での作業となります。
<Home Directory>/.ssh/config
に下記を追記します。
<ホスト名>
,<Elastic IP>
,<キーペアファイルのパス>
は適宜各自の環境に置き換えてください。Host <ホスト名> HostName <Elastic IP> User ubuntu Port 22 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile <キーペアファイルのパス> IdentitiesOnly yesコマンドラインツールから
ssh <ホスト名>
でサーバ接続できればOKです。【手順2】Redash9.0へのバージョンアップ
Redash8.0→9.0へのバージョンアップを行います。
ssh <ホスト名>
でRedashサーバに接続
- コンテナの起動確認
# redashディレクトリに移動 cd /opt/redash/ # コンテナの起動確認 sudo docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------ redash_adhoc_worker_1 /app/bin/docker-entrypoint ... Up 5000/tcp redash_nginx_1 nginx -g daemon off; Up 443/tcp, 0.0.0.0:80->80/tcp redash_postgres_1 docker-entrypoint.sh postgres Up 5432/tcp redash_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp redash_scheduled_worker_1 /app/bin/docker-entrypoint ... Up 5000/tcp redash_scheduler_1 /app/bin/docker-entrypoint ... Up 5000/tcp redash_server_1 /app/bin/docker-entrypoint ... Up 0.0.0.0:5000->5000/tcp redash_worker_1 /app/bin/docker-entrypoint ... Up 5000/tcp
- コンテナの停止
sudo docker-compose down
- docker-compose.ymlの変更
redash/CHANGELOG.mdのUpgradingを参考に下記を変更します。
- imageをredash/redash:8.0.0.b32245→redash/redash:previewに変更
- services/schedulerのenvironmentを削除
- services 配下にworkerを追加
sudo vi docker-compose.yml修正後のdocker-compose.yml
version: "2" x-redash-service: &redash-service #最新のimageに変更 image: redash/redash:preview depends_on: - postgres - redis env_file: /opt/redash/env restart: always services: #workerを追加 worker: <<: *redash-service command: worker environment: QUEUES: "periodic emails default" WORKERS_COUNT: 1 server: <<: *redash-service command: server ports: - "5000:5000" environment: REDASH_WEB_WORKERS: 4 scheduler: <<: *redash-service command: scheduler #schedulerのenvironment を削除 scheduled_worker: <<: *redash-service command: worker environment: QUEUES: "scheduled_queries,schemas" WORKERS_COUNT: 1 adhoc_worker: <<: *redash-service command: worker environment: QUEUES: "queries" WORKERS_COUNT: 2 redis: image: redis:5.0-alpine restart: always postgres: image: postgres:9.6-alpine env_file: /opt/redash/env volumes: - /opt/redash/postgres-data:/var/lib/postgresql/data restart: always nginx: image: redash/nginx:latest ports: - "80:80" depends_on: - server links: - server:redash restart: always
- コンテナのビルド
docker-compose up --force-recreate --build
- Redashにログインしversion9.0になっていることを確認
画面左下のユーザー名をクリックするとRedashの現在のバージョンが表示されます。
9.0.0-betaになっていればバージョンアップ完了です。【手順3】CloudWatch Logs Insightsデータの取得
最後に作成したRedashでCloudWatch Logs Insightsのデータ取得を行います。
IAMでRedashユーザーの作成
RedashからAWSリソースにアクセスするためにIAMにRedashユーザーを作成します。
AWS IAMから ユーザー > [ユーザーを追加]
プログラムによるアクセスにチェックを付けます
アクセス権限から既存のポリシーをアタッチを選択します。
今回はLambdaのCloudWatch Logs Insightsデータを取得したいためAWSLambdaFullAccess
にチェックを入れます。ユーザーの作成が完了すると、アクセスキーが発行されるためダウンロードし安全な場所に保管します。
データソースの追加
Setting > Data Sources > [New Data Data Source] からAmazon CloudWatch Logs Insightsを選択します。
データソース追加に必要な情報を設定します。
- Name:任意
- AWS Region:東京リージョンなら「ap-northeast-1」
- AWS Access Key:IAMで発行したもの
- AWS Secret Key:IAMで発行したもの
Create後、[Test Connection]が成功すればデータソースの追加完了です。
指定のロググループのデータを取得
最後です。
Queriesからデータ取得のクエリを作成します。
左上のプルダウンから先ほど追加したデータソースを選択記法についてはCloud Watch Logs Insightsの記法と変わりません。
今回はTwitter APIのログデータを取得しました。無事取得できました。
{ logGroupName: '/aws/lambda/rep_Tweet', startTime: 1590926139, queryString: ' fields @timestamp,@message | filter @message like /event/ | sort @timestamp desc | display @timestamp,follow_events.0.target.name,follow_events.0.type,follow_events.0.target.screen_name,follow_events.0.target.description | limit 1 ' }
- 投稿日:2021-01-21T19:10:12+09:00
sdk-goでdynamoDBの複雑なstructの値をupdateする
やりたいこと
GoでのdynamoDBに対しての操作は割とめんどかったりします。単純なStringやIntのものであればまだ良いのですが、ListのMapのなかのListとか、値の構造が複雑になってくると気が滅入ります。
// シンプルなパターン &dynamodb.UpdateItemInput{ TableName: aws.String("sampleTable"), Key: // 省略, ExpressionAttributeValues: map[string]*dynamodb.Attribute{ ":ssv": { S: aws.String("sampleStringValue") }, ":siv": { N: aws.String(strconv.Itoa(0)) // ここもintをstringに型変換してそれをaws.String()してkeyにはNを指定って感じでわかりづらい。 }, }, UpdateExpression: aws.String("set sampleStringValue=:ssv and sampleIntValue=:siv") } // 複雑なパターン &dynamodb.UpdateItemInput{ TableName: aws.String("sampleTable"), Key: //省略, ExpressionAttributeValues: map[string]*dynamodb.Attribute{ ":slv": { L: [ { M: { ":smp": { aws.String("sample") }.... } } ] }, } }これを楽にやれるのがsdk-goのexpressionってやつです。
expressionの使い方
update := expression.UpdateBuilder{}.Set( expression.Name("sampleComplexValue"), expression.Value(sampleCompexValue) ) expr, err := expression.NewBuilder().WithUpdate(update).Build() &dynamodb.UpdateItemInput{ TableName: aws.String("sampleTable"), Key: //省略, ExpressionAttributeNames: expr.Names(), ExpressionAttributeValues: expr.Values(), UpdateExpression: expr.Update() }上の例よりかなりスマートにかけますね。可読性も格段に上がります。
expression.Valuesの引数に複雑な(もちろん単純なものでもなんの問題もありませんが)値を渡すだけで、ここまでできるのは結構ありがたい。もちろんexpressionは上記の例のような更新処理だけでなく、Query処理等にも使えるので積極的に使っていきたいところですね。
- 投稿日:2021-01-21T16:16:00+09:00
AWS 認定 デベロッパー – アソシエイト(DVA-C01)取得するまでにやったこと
はじめに
DX 技術本部の yu-yama です。
AWS 認定 デベロッパー – アソシエイトを取得したので取得までの流れを記します。受験前の AWS 経験
AWS 経験は 4, 5 年で、コアサービスは一通り触っており、ソリューションアーキテクトアソシエイトを 2020 年 6 月に取得しています。
AWS 認定ソリューションアーキテクトアソシエイト(SAA-C02)取得するまでにやったこと
学習期間
- 7 カ月間薄く(
だらだらと)- 試験直前の 1 週間は毎日少しでもと決めて DVA 関連のテキストに目を通すようにしていました
学習方法
試験ガイドを参照し、試験範囲を確認する
合格記を読み、試験のイメージをつかむ
- 【AWS】AWS認定『デベロッパー - アソシエイト』(DVA)に合格した話 - Rのつく財団入り口
- 「AWS 認定 デベロッパー – アソシエイト」の学習方法・勉強法・試験対策・合格体験記 ~ How to study for AWS Certified Developer – Associate(DVA)~ | Magtranetwork マグトラネットワーク
- AWS 認定Developer Associate に合格するまで - Qiita
- AWS実務未経験者がAWS認定デベロッパーアソシエイトに勉強時間60時間ぐらいで合格した話 - Qiita
- AWS DVA合格記|あきの/D-En|note
- 【AWS認定試験】アソシエイト3冠 + SAP を取ったので振り返ってみる | Developers.IO
AWS 認定 – 試験準備ワークショップ 「デベロッパー - アソシエイト」を受ける
- Exam Readiness: AWS Certified Developer – Associate (Digital) (Japanese) | AWS トレーニングと認定 より試験の攻略法を確認します
- 解答を選択する際の観点
- 問題の狙いを見極める方法
- アーキテクチャ設計の原則
などが分かります。ここのアーキテクチャ設計の原則は超重要なので暗記しましょう
ブラックベルトを読む
上記ワークショップで試験で出題される AWS サービスが分かるので、それぞれのブラックベルトの資料を読み、概要を把握します。
yu-yama は以下でリンク張っているものを読みました。リンク張られていないものは試験受けてみて、読んどいた方が良かったと思ったものです。
AWS 認定デベロッパー アソシエイト模擬試験問題集(5 回分 325 問) | Udemy
- 1周目は終了後、正解・不正解関わらず解説も全部読み、理解が浅すぎると思ったサービスについてはブラックベルトも読みました。
- 2周目は終了後、不正解のみのチェックを行いました。
試験結果推移
- 演習テスト1: 1 周目は 24%でした...
- 演習テスト2: 1 周目は 33%でした...
- 演習テスト1: 2 周目は 56%でした...
- 演習テスト2: 2 周目は 75%でした...
思ったより点数が上がらないのと、この問題集は難易度が高いというのを他で見かけたので 演習テスト2までを2周した時点で1度試験を受けてみることにしました。
模擬試験
- 受けませんでした。Udemy の模擬試験を実施していれば問題文のボリュームも解答の選択肢の雰囲気も同じなので不要だと思います。
試験を受けた感想と試験のコツ
- 時間にはかなり余裕があります。全問解いた時点で1時間程度余っていました。
- SAA の時と同様に、確信をもって正解を選択できないが、消去法で残ったものを選択して進めました。 試験終了ボタンを押下してアンケート回答後にすぐに結果が表示されるので試験終了ボタンを押すときは緊張感あります...
- 問題の難易度ですが、AWS 認定デベロッパー アソシエイト模擬試験問題集(5 回分 325 問) | Udemyの問題と比べると少しだけUdemyの方が難しいという印象です。試験準備ワークショップとブラックベルトだけではちょっと足りないかもしれないので、演習テストを受けないにしても解答解説全斜め読みくらいはしておくと良いかも。
試験のコツ
- まずは一通り解きましょう。迷いがあるものは後で見直しにチェックを付けて最後に一気に見直せます。
正解が分からない場合、原則に従い正解を選択する。
- 今回はこれが功を奏した気がしています。DVA の原則は Exam Readiness: AWS Certified Developer – Associate (Digital) (Japanese) | AWS トレーニングと認定で教えてもらえます
今回特に役立った原則は以下になります。
- スケールアップよりもスケールアウト
- アクセスキーより IAM ロールが望ましい
- アンマネージドサービスよりもマネージド
- リソースや API を直接公開する事は避け、AWS エッジサービスや API ゲートウェイを使用する
- サーバーにセッション状態を保存していては優れたアーキテクチャにはならない
- インフラストラクチャを疎結合化する
- サーバーレス化する
- トラブルシューティング時には、セキュリティグループや NACL を常に確認する
- VPC のプライベートサブネット内に作成されたインスタンスは、NAT を使用しない限りインターネットと通信することが出来ない
- インターネットと通信するには、インターネットゲートウェイとルートテーブルのルートが必要
- EBS ボリュームは、EC2 インスタンスに疎結合されている。
- ブートボリュームの場合を除いて、アタッチまたはデタッチできる
ユースケースに対する最適なアーキテクチャを問われる問題が出た場合、各々の単語の意味は分からなくても、原則に従った解答を選択しておけば良い結果に近づける筈。
次
次はAWS 認定 SysOps アドミニストレーター – アソシエイト(SOA-C01)を受けようと考えています。SOA-C02が出るという話もありますが...
勉強方法
- 試験ガイドを読む
- 試験準備ワークショップを受けて、抑えるべきサービスと原則を確認する
- ブラックベルトを読む
- 問題集(Udemyかよく聞くkoiwaclubを検討中)
- 投稿日:2021-01-21T15:25:32+09:00
CloudWatchAlarmの動作確認をしてみる
目的
わが社ではCloudWatchAlarmを設定し、アラート内容をタスクとしてチケット化するシステムを作っているのですが、「アラート内容をタスクとしてチケット化」の部分を確認したいので、CLIで無理やりアラートを発報させる方法を調査しました。備忘録です。
手順
CloudWatchの権限を持ったユーザでCloudShellからCLIをたたくだけ。
cat << EOF > ALARM.json { "AlarmName": "【Alarm名】", "StateValue": "ALARM", "StateReason": "Test Alarm" } EOF aws cloudwatch set-alarm-state --cli-input-json file://./ALARM.json rm -f ./ALARM.json今回はファイルインプットを採用。
ファイルインプットのほうが、設定内容の可視性を上げやすいのでよさげですね。以上。
- 投稿日:2021-01-21T15:03:51+09:00
[Alibaba Cloud] オンプレミスからVM移行ができるServer Migration Center 触ってみた
この記事の目的
Alibaba CloudのマイグレーションツールがServerMigrationCenterとして新たにリリースされていたので軽く触ってみました。
CentOSのサーバーのイメージコピーして、Alibaba Cloud環境に移してみます。ServerMigrationCenterの概要
- Alibaba Cloudのマネージドサービスの1つ
オンプレミス
やクラウド環境
から複数サーバーをAlibaba Cloud環境に移行するために利用するツール- 増分移行をサポートしているので、サーバーを停止する必要なく移行が可能
- 複数タスクを同時実行可能(利用シチュエーションは不明)
- ソースディスクのパーティションスキーマを取得してディスクパーティションも複製可
※この際にディスクサイズを指定可
その他の特徴
増分データ同期
- サーバー停止をする必要がない.
- ソースサーバーの増分データをAlibabaCloudに同期する.
コンテナレジストリへのデータ移行
- サーバーをContainerRegistryに移行可能.
マルチスレッドデータ送信
- マルチスレッドデータ送信をサポート.
- 高帯域幅が利用可能な場合に帯域幅の使用量と伝送効率が向上
移行タスクのステータス監視が可能
- 監視ができるのでエラーを早期に特定しトラブルシューティングが迅速に.
ローカル作業
- ローカルのMacbookにマイグレーションのエージェントツールをDL
- ダウンロードURL:(https://p2v-tools.oss-cn-hangzhou.aliyuncs.com/smc/Alibaba_Cloud_Migration_Tool.zip?spm=5176.13581910.904.4.72796145SwdqYh&file=Alibaba_Cloud_Migration_Tool.zip) *エージェントはアップデートされる可能性があるので、最新版はAlibaba CloudのSMCコンソールよりDLが必要
## マイグレーションツールDL後、対象のディレクトリに移動. ## llでファイルを確認. ## 今回はLinux_x86*64bitのエージェントを利用します. root@tnoce:~/dev-main/Alibaba_Cloud_Migration_Tool$ ll total 58968 drwx------@ 7 SHU staff 224 Jan 21 13:22 ./ drwxr-xr-x 25 SHU staff 800 Jan 21 13:23 ../ -rwxr-xr-x@ 1 SHU staff 21010 Jan 12 15:39 Release Note.txt* -rwxr-xr-x@ 1 SHU staff 6111564 Jan 18 20:04 go2aliyun_client2.5.2_linux_i386.zip* -rwxr-xr-x@ 1 SHU staff 6044981 Jan 18 20:04 go2aliyun_client2.5.2_linux_x86_64.zip* -rwxr-xr-x@ 1 SHU staff 8727685 Jan 12 15:39 go2aliyun_client2.5.2_windows_i386.zip* -rwxr-xr-x@ 1 SHU staff 9277052 Jan 12 15:39 go2aliyun_client2.5.2_windows_x86_64.zip* ## SFTPで対象マイグレサーバーにログイン $ sftp -oIdentityFile=`YOUR KEY-PAIR` root@[IPアドレス] ## sftp put -r でマイグレツールのディレクトリをまるごとサーバー側にアップロード. > sftp put -r /dev-main/Alibaba_Cloud_Migration_Tool/go2aliyun_client2.5.2_linux_x86_64.zip*サーバー作業
## sshでログイン. ## llでsftpでputされたディレクトリが存在するか状態確認 [root@eigo-split go2aliyun_client2.5.2_linux_x86_64]# ll total 5208 drwxr-xr-x 3 root root 4096 Jan 8 17:32 Check -rw-r--r-- 1 root root 6357 Jan 6 17:51 client_data -rw-r--r-- 1 root root 20169 Jan 6 17:51 EULA drwxr-xr-x 2 root root 4096 Jan 6 17:55 Excludes -rwxr-xr-x 1 root root 5289072 Jan 18 19:56 go2aliyun_client -rw-r--r-- 1 root root 100 Jan 21 12:31 user_config.json ## vimでACK, ACK-Sを編集 [root@eigo-split go2aliyun_client2.5.2_linux_x86_64]# vim user_config.json { "access_id" : "YOUR ACK-ID INPUT HERE", "secret_key" : "YOUR ACK-SECRET-KEY INPUT HERE" } ## chmodでアプリケーションに実行権限を付与 [root@eigo-split go2aliyun_client2.5.2_linux_x86_64]# chmod +x go2aliyun_client ## ./go2aliyun_clientでアプリケーションの実行 [root@eigo-split go2aliyun_client2.5.2_linux_x86_64]# ./go2aliyun_client [2021-01-21 12:34:23] [Info] ========= Goto Aliyun Client 2.5.2. ========= [2021-01-21 12:34:24] [Info] ========= Run In Daemon Mode ========= [2021-01-21 12:34:24] [Info] Goto Aliyun Begin... [2021-01-21 12:34:24] [Info] Load User Config... [2021-01-21 12:34:24] [Info] Load Client Data... [2021-01-21 12:34:24] [Info] Check System Info [CentOS x86_64]... OS Info: CentOS Linux 7 (Core) (3.10.0-1062.18.1.el7.x86_64) CPU Info: Intel(R) Xeon(R) Platinum 8269CY CPU @ 2.50GHz CPU Usage: 2 Cores (1.01%) Memory Usage: 1.81GB/4.00GB (45.25%) Hostname: eigo-split IP Address: 10.68.30.177 Mac Address: 00163E004478 [2021-01-21 12:34:25] [Info] Verify User Account... You Have Not Created ServiceLinkedRole For SMC: When you import source server for the first time, a service linked role is automatically created for you to use relevant features. Role Name: AliyunServiceRoleForSMC Role Policy: AliyunServiceRolePolicyForSMC Role Description: By default, SMC assumes this role to access your resources in other Alibaba Cloud services, such as ECS, VPC, and RAM. Documentation: https://help.aliyun.com/document_detail/122993.html Do You Want To Created It and Continue? (yes/no): yes [2021-01-21 12:34:29] [Info] Generate SSH Key... [2021-01-21 12:34:29] [Info] Import Source Server... [2021-01-21 12:34:31] [Info] Import Source Server [s-bp13vdcjxh8tg0y9eyj4] Successfully! [2021-01-21 12:34:32] [Info] Check Source Server Status... [2021-01-21 12:34:33] [Info] Check Replication Job Status... Please Goto SMC Console To Create New Job, time: 2m30s \Alibaba Cloud作業
- SMCコンソールで移行ソースが作成されているのを確認
基本セッティング
- Target Region:イメージをコピーするターゲットリージョン
- Task name:移行タスクの名前
- Description:移行タスクの説明
- Target Disk Size (GiB):ターゲットのディスクサイズ
- Resource Type:ECSイメージかコンテナイメージ
- Image Name:イメージの名前
- 许可证类型:ICPの取得
- タグ&ネットワーク(オプション)
- Migration Task Tag:タグ付け(任意)
- Network Type:Public Network OR VPC ⇒ VPCは閉域接続かVPN接続が必要
- アドバンス設定(オプション)
- Transmission speed limit (KB/S):
- Compression Level:コンプレッションレベルを上げると伝送効率は上がるが、CPU負荷が上がる
- Checksum:チェックサム機能(*ファイルデータの整合性を高めますが、移行速度は落ちる)
イメージからECSの作成
イメージから作成したインスタンス
まとめ
マイグレーションに時間はかかりましたが、シンプルでわかりやすく使えました。
あとは、速度を速めたい場合はオプション値の設定も有効かなと。
イントラ経由でVMイメージの移行もできるようなので、VPCモードを試してみる価値はありそうです。
- 投稿日:2021-01-21T14:47:24+09:00
sam local start-apiでヘッダーが勝手にキャメルケースになるんだが?
表題の通り、sam local start-apiでヘッダーが勝手にキャメルケースになる問題についてです。
こちらにドンピシャの回答があるのですが、内部で使っているFlaskの仕様だそうです。
Headers are received in Camel-Case · Issue #1860 · aws/aws-sam-cli仕方ないのでNode.jsでは下記ワークアラウンドをしてヘッダーをすべて小文字にして対応しましょう。
(Pythonならissueのコメントにサンプルコードが載っています)const toLowerCaseKey = function(object) { let newObject = {}; for (let key in object) { if (object.hasOwnProperty(key)) { newObject[key.toLocaleLowerCase()] = object[key]; } } return newObject }
- 投稿日:2021-01-21T12:34:38+09:00
【フロントエンド開発】初投稿
- 投稿日:2021-01-21T11:14:29+09:00
AWSのRDSを削除したのに課金され続けてしまった話。。。原因が分かった。。。
AWSのRDSを使いアプリを作成していましたが、
結構月額が高いし、あまり使わなくなったので
RDSを削除しました。ですが、なぜが、まだ課金されている???
なぜ?????
結論:スナップショットが残っていると課金し続けるようです。。。
https://ap-northeast-1.console.aws.amazon.com/rds/home?region=ap-northeast-1#snapshots-list:
スナップショットが残っている人は削除しましょう!!!!!!
やはり
AWSは奥が深いですね。。。
- 投稿日:2021-01-21T11:04:39+09:00
CloudFormationでApiGatewayのログを有効化に必要な諸々の設定をする
共通の設定が必要なのでどっかに書く
Resources: APIGatewayPushToCloudWatchLogsRole: Type: AWS::IAM::Role Properties: Description: "Allows API Gateway to push logs to CloudWatch Logs." AssumeRolePolicyDocument: Version: 2012-10-17 Statement: Effect: Allow Principal: Service: apigateway.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs ApiGatewayAccount: Type: AWS::ApiGateway::Account Properties: CloudWatchRoleArn: !GetAtt APIGatewayPushToCloudWatchLogsRole.Arn
- 投稿日:2021-01-21T10:02:08+09:00
RailsアプリをAWSにデプロイするまでにすごく苦労したので教訓メモ
何コレ
ポートフォリオを作成する上で以下の環境構築を行っていたが、個人的にとても苦労したので備忘録として残しておきたいと思い書いた。
設定環境
AWS EC2(1年間無料で使えるインスタンス)
AWS RDS
Ruby 3.0.0
Rails 6.1.1
puma 5.1.1
mysql 5.7アプリはまだRails newしただけの状態
使った教材
こちらの記事を参考に環境構築を行った。わからない単語などは都度調べながら。
https://qiita.com/take18k_tech/items/5710ad9d00ea4c13ce36
記事自体はタイトルの通り、知識としては今は無くとも環境構築できるのではと思う(インフラ大事だからいずれはもっと学習するつもり)。何が苦労したのか
主に以下の点でとても苦労した。
・記事とおりやっているが、capistranoの設定あたりから壮大につまずく
→これは記事が悪いわけでは無く(それ以外はすんなり設定できたので非常に感謝している!)、環境というのはどうしても個々で異なるので、あまり鵜呑みにせず、できたらラッキーぐらいの心持ちで参照した方が良かったなと思った。
具体的な箇所は後述。・エラー解決しようと検索するも英語記事ばかり
→当然といえば当然なのかもしれない。日本語記事無いかな〜と甘えたことばかり考えていた。
解決策は英語記事(特にgithubのissue)に載っていることが多かったと思う。初学者ありがちだと思うが、本当に英語に慣れないといけないなと。具体的につまずいた箇所①
・デプロイ先のサーバーにリポジトリをpushできない
→少し前にRails newしたアプリなら、マスターブランチ名がmaster
かもしれない。
しかし最近デフォルトのブランチ名がmaster
→main
になってしまった為、このままではpushできないという話。
https://capistranorb.com/documentation/getting-started/configuration/
こちらを参考に英語と戦いながら設定を変更すればうまくいく!具体的につまずいた箇所②
・デプロイしてみたら
--daemon
が無効だと怒られる
→エラー内容そのままですが、デーモンプロセスが無効と表記されている。daemon無効エラーログ05:38 puma:start using conf file /var/www/hogehoge/shared/puma.rb 01 $HOME/.rbenv/bin/rbenv exec bundle exec puma -C /var/www/shikaku_sns/shared/puma.rb --daemon 01 bundler: failed to load command: puma (/var/www/hogehoge/shared/bundle/ruby/3.0.0/bin/puma) 01 /var/www/hogehoge/shared/bundle/ruby/3.0.0/gems/puma-5.1.1/lib/puma/cli.rb:50:in `initialize' 01 : 01 invalid option: --daemon 01 ( 01 OptionParser::InvalidOption 01 ) 01 長いので割愛。hogehogeはアプリ名なるほどわからん、となりコミュニティで質問したところ、こちらを紹介いただく。
https://github.com/seuros/capistrano-puma#systemd
ここらを見ることで解決の糸口を見つけることができた!
(今思うと、コミュニティにいらっしゃる強者エンジニアの方はほとんどgithub(一次ソース)を真っ先にみていることがわかった。)具体的につまずいた箇所③
・Capistranoを使ったデプロイができない!
→参考記事の中では、
capistrano3-pumaのバージョン5にpumaを再起動できないバグが出ている
とあります。確かにrestartすると以下のようなエラーが表示。restartエラーログ01:03 puma:restart 01 sudo /bin/systemctl restart puma 01 Failed to restart puma.service: Unit is not loaded properly: Invalid argument. 01 See system logs and 'systemctl status puma.service' for details. 以下長いので割愛マジかーと思い、途方にくれていたが、このままではイカンと思いコミュニティで恐る恐る質問。
このエラーは以下の記事で無事解決!
https://qiita.com/AQeNku/items/81ddae388d8615125a24今回得られた教訓
(1)エラーをきちんと読む
エラーが出たわかんね〜、で済ませない。
この記事が自分にはとても有効。質問する際はこちらを念頭に質問する。
https://qiita.com/rhiroe/items/4349b9f412364aa2c729(2)エラー内容を見て、まずは一次ソースを検索する
自分がつまずいた箇所は何もGithubのusageに詳しく載っていたりしたので。それ以外にも例えばAWSに関するエラーだったらAWSの公式ドキュメントを見る。そこを見て何言ってんだこいつ?みたいになってしまったらQiitaなどの記事を見るのは悪くなさそう。(3)質問して返ってくることをあまり期待しない
メンタサービスなどを利用している場合は別だが、無料のコミュニティで質問をしても絶対に返ってくる保証は無い。
世の中の人たちそんなに暇では無い。基本的には自分で考えては検証し、また考えては検証の繰り返しを行うマインドセットを持っていないと多分この先もダメ。まだまだ先は長いのでドンドン進む
- 投稿日:2021-01-21T08:30:16+09:00
AndroidからAWS Cognitoのユーザプールをさっくり使う
サインアップやサインイン、パスワード再発行など、ユーザ管理がないアプリケーションを見かけない日はありません
とはいえ自前でバックエンドのシステムを作るのも大変...
でもAmplifyはちょっとリッチすぎる気がする...そんな私のための備忘録です
下記のことができます
- メールアドレス、パスワードによるサインアップ、ログアウト
- メールアドレス認証
- パスワード再発行
メールアドレスやパスワードはガッツリ個人情報です
その辺りの管理をAWSにお願いできるのはかなり気楽ですよねー前準備
SES (Simple Email Service)に配信用のメールアドレスを登録する
AWSのSESに、認証コードを送信する用のメールアドレスを登録、認証しておきます
登録したメールアドレスに確認用のURLが届くのでクリックすると認証できます
Verification Statusが"verified"になっていれば使用可能です"Send a Test Email"ボタンで自分自身にテストメールを送り、無事受信できればOKです
Cognitoにユーザプールを作成する
AWS Cognitoのダッシュボードにアクセスし、UserPoolを作成します
送信元のEメールアドレスに、先ほど認証したメールアドレスを登録し、Amazon SESによるEメール配信を”はい”に指定しますアプリクライアント側の設定はこんな感じです
Androidクライアントを実装する
依存関係
依存関係に、下記を追加します
build.gradleimplementation 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.19.0'いよいよ実装
初期化
val userPoolId = "ap-northeast-1_xxxxxxxx" val clientId = "yyyyyyyyyyyyy" val clientSecret = "zzzzzzzzzzzzzz" val userPool = CognitoUserPool(context, userPoolId, clientId, clientSecret, Regions.AP_NORTHEAST_1)先ほど作成したCognitoUserPoolのUserPoolId, ClientId, ClientSecretを使ってインスタンスを作成します
以後、このuserPoolインスタンスを使って各種アクセスをおこないますサインアップ
サインアップをするには2つのメソッドが必要です
- signUpInBackground : userPoolにユーザを作成する
- confirmSignUpInBackground : cognitoユーザを認証する
まずはsignUpInBackgroundです
この時点でuserPoolにユーザが追加され、本人確認用コードが送信されます
ただしUNCONFIRMEDの状態で何もできませんfun signUp(username: String, password: String, successCallback: () -> Unit, failureCallback: (exception: Exception?) -> Unit ) { val userAttributes = CognitoUserAttributes() userPool.signUpInBackground(username, password, userAttributes, null, object : SignUpHandler { override fun onSuccess(user: CognitoUser?, signUpResult: SignUpResult?) { successCallback() } override fun onFailure(exception: java.lang.Exception?) { failureCallback(exception) } } ) }このままだとサインインも何もできないので、続いて本人確認をする必要があります
送信された認証用コードを使ってconfirmSignUpInBackgroundを呼ぶとCONFIRMED状態になりますfun confirmSignUp(username: String, verifyCode: String, successCallback: () -> Unit, failureCallback: (exception: Exception?) -> Unit ) { userPool.getUser(username).confirmSignUpInBackground(verifyCode, false, object : GenericHandler { override fun onSuccess() { successCallback() } override fun onFailure(exception: Exception?) { failureCallback(exception) } }) }サインイン
サインインにはgetSessionInBackgroundを使用します
一度サインインに成功すると端末内にセッションとして状態が保持されるようです
今回は2段階認証を有効化していないので、getMFACodeなどはコールされない(はず)fun signIn(username: String, password: String, successCallback: () -> Unit, failureCallback: (exception: Exception?) -> Unit ) { userPool.getUser(username).getSessionInBackground( object : AuthenticationHandler { override fun onSuccess(userSession: CognitoUserSession?, newDevice: CognitoDevice?) { successCallback() } override fun getAuthenticationDetails( authenticationContinuation: AuthenticationContinuation?, userId: String? ) { val authenticationDetails = AuthenticationDetails(userId, password, null) authenticationContinuation!!.setAuthenticationDetails(authenticationDetails) authenticationContinuation.continueTask() } override fun getMFACode(continuation: MultiFactorAuthenticationContinuation?) { /* should not be called */ } override fun authenticationChallenge(continuation: ChallengeContinuation?) { /* should not be called */ } override fun onFailure(exception: Exception?) { failureCallback(exception) } }) }パスワード再発行
パスワードの再発行にはforgotPasswordInBackGroundを使います
実行するとパスワード再発行用の認証コードがメールアドレスに送られ、getResetCodeコールバックが返ってきます
その時に一緒に得られるcontinuationを使って、新しい認証コードとパスワードを設定すると完了です認証周りはサインアップと似たようなものかと思いきや、少し違いますね
fun forgotPassword(username: String, successCallback: () -> Unit, verifyCallback: () -> Unit, failureCallback: (exception: Exception?) -> Unit ) { userPool.getUser(username).forgotPasswordInBackground( object: ForgotPasswordHandler { override fun onSuccess() { successCallback() } override fun getResetCode(forgotPasswordContinuation: ForgotPasswordContinuation?) { continuation = forgotPasswordContinuation verifyCallback() } override fun onFailure(exception: Exception?) { failureCallback(exception) } }) } fun verifyPasswordReset(password: String, verifyCode: String) { continuation?.apply { setPassword(password) setVerificationCode(verifyCode) continueTask() } }まとめ
cognito側の仕様にはあまり触れていませんが、これでさっくり使えます!
- 投稿日:2021-01-21T01:28:20+09:00
LaravelアプリをAWSにデプロイする
LaravelアプリをAWSにデプロイする手順をメモ書き程度に残す
- 投稿日:2021-01-21T01:07:28+09:00
PythonでS3バケット内の一覧を取得し、特定のKeyで検索 Key名と最終更新日、カウント数をファイルに出力
所用で必要になったので
# -*- coding: utf-8 -*- import boto3 PUBLIC_S3_BUCKET_NAME_TEST = 'バケット名' def access_count(): count = 0 with open('file.txt', 'w') as f: # バケットの一覧取得 S3 = boto3.resource('s3') S3BUCKET = S3.Bucket(PUBLIC_S3_BUCKET_NAME_TEST) for obj in S3BUCKET.objects.all(): if '検索名' in obj.key: count += 1 print(count, obj.key, obj.last_modified, file=f) print('total=' + str(count), file=f)
- 投稿日:2021-01-21T00:36:26+09:00
AWSのControl Towerマスターアカウントからセルフマネージド型StackSetsを展開してみた
構成
前回、AWSのControl Towerマスターアカウントからサービスマネージド型StackSetsを展開してみたの記事を作成しましたが、いくつかデメリットがあったのでセルフマネージド型StackSetsバージョンとしてこちらの記事を執筆します。
今回の構成はこちら。アカウント払い出し時に、BudgetsとSNSをアカウントに展開した上で払い出します。
セルフマネージド型StackSetsで、OUではなくアカウント指定でBudgets,SNSを展開します。
セルフマネージド型StackSetsを使用するには、以下のロールが必要です。
アカウント ロール 管理アカウント AWSCloudFormationStackSetAdministrationRole 各ターゲットアカウント AWSCloudFormationStackSetExecutionRole StackSetsの展開先が増える度に、ターゲットアカウントにサインインしてIAMロールを作成するのは面倒なので、各ターゲットアカウントの展開は親アカウントからサービスマネージド型StackSetsで展開します。
StackSets 展開するサービス サービスマネージド型 IAMロール、ポリシー セルフマネージド型 Budgets,SNS セルフマネージド型のStackSetsを展開するために、事前にサービスマネージド型のStackSetsでIAMロールを展開します。
なぜBudgets等をセフルマネージド型で作成するのか
冒頭でも述べましたが、サービスマネージド型で展開すると今回の場合ではデメリットの方が大きいと判断したからです。
なお、サービスマネージド型に一般的な欠陥があると言うわけではありません。あくまで私がしたいことと合わなかっただけです。デメリットは二つあり、
・無駄なサブスクリプションの確認が生じる
・メールアドレス変更時に一から設定をし直す必要がある
ことです。構成図の通り、各アカウントのBudgets等はアカウントごとに設定が異なります。
そのため、サービスマネージド型でターゲットをOUで指定すると、OU内のアカウント全てにデフォルトのメールアドレスをエンドポイントとしたSNSが作成されます。
また、OU内にアカウントが追加されると自動的にStackSetsを展開する自動デプロイ機能も有効化するので、そのときもデフォルトのメールアドレスをエンドポイントとしたSNSが作成されます。SNSが作成されると、SNSサブスクリプションの確認メールが通知先に飛びます。
リンクをクリックするだけの作業ですが、できればしたくありません。
デフォルトのメールアドレスは実際の通知先として使わないからです。
後からアカウントごとに通知先を変更します。
使用しないサブスクリプションの確認メールをクリックすること自体は意味がありません。
これが一つ目のデメリットです。二つ目のデメリットがセルフサービス型に決めた理由です。
諸事情によりデフォルトのメールアドレスを更新する場合、ターゲットOU内の全アカウントのSNS通知先が、変更した新しいメールアドレスになるからです。
当然各アカウントが通知したいメールアドレスは新しいメールアドレスではないので、再度設定を上書きし直す必要があります。
結構な労力になるので、これを避けるためにセルフサービス型で展開します。なお、なぜ実際に通知先として使用しない無駄なデフォルトのメールアドレスを設定していたかと言うと、各アカウントで同じ内容のSNSを作成しないからです。
StackSetsはOU単位で展開するので、複数アカウントで展開します。
Aアカウントで実際に通知先として使用するメールアドレスで展開しても、BアカウントやCアカウントでは通知先として使用しないので、BやCにとっては後で変更する無駄な通知先となります。
どのメールアドレスを使用しても、いずれかのアカウントでは無駄な通知先となるので、自分が使用するメールアドレスをデフォルトのメールアドレスとしていました。管理者アカウントでIAMロール作成
StackSetsがIAMロールを利用するので、信頼関係はCloudFormationに対して行います。
ターゲット先アカウントで作成したIAMロールを引き受けられるポリシーを作成します。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" ], "Resource": [ "arn:aws:iam::*:role/AWSCloudFormationStackSetExecutionRole" ], "Effect": "Allow" } ] }ポリシーに適当な名前をつけます。
作成したポリシーをロールに割り当てます。
ロールの名前を間違えないようにつけます。
AWSCloudFormationStackSetAdministrationRole
です。
管理アカウントでIAMロール作成完了です。ターゲットアカウントでIAMロール作成
ターゲットアカウントで、管理アカウントを信頼するIAMロールを作成します。
ポリシーは最低限のポリシーを作成します。
ポリシーに適当な名前をつけます。
作成したポリシーをロールにアタッチします。
あとはIAMロールの名前を間違えずに設定しましょう。
AWSCloudFormationStackSetExecutionRole
です。セルフマネージド型StackSetsでBudgets,SNS展開
まず、StackSets用にテンプレートをS3にアップロードします。
いつもは事前にS3にアップロードしませんが、気まぐれでやってみます。S3のアップロード完了しました。
StackSetsを作成します。取り合えず予算額は100ドルにします。
セルフサービスのアクセス許可から、IAMロールを選択し、実行ロール名はデフォルトのままにします。
先ほどIAMロールを作成したターゲットアカウントを指定します。
StackSetsでBudgets、SNSを展開しました。
成功しましたが、ターゲットアカウントで展開されているか確認します。SNSは作成されているようです。
Budgetsも100ドルで作成されています。
リソースは無事に展開されていました。サービスマネージド型StackSetsでIAMロール展開
ターゲットアカウントでのIAMロール作成は、コンソールではうまく行きました。
ターゲットアカウントにいちいちサインインして作成するのも面倒です。
次はIAMロールをStackSetsで展開してみます。
IAMロールはOU単位で展開しても問題ないので、サービスマネージド型で展開します。
テンプレートは最後に載せます。サービスマネージド型を選択する画面のキャプチャを撮るのを忘れていますが、サービスマネージド型を選択しています。
IAMロールの展開が成功しました。
念のため、ちゃんと作成されているかアカウントを移動してみてみます。ポリシー、信頼関係ともに正常に作成できています。
セルフマネージド型StackSetsでスタックの追加を行い、新アカウントにBudgets,SNSを展開する
ターゲットOUへのIAMロール展開が終了したので、ターゲットOU内のアカウントを指定して、StackSetsでBudgets、SNSを展開します。
上書き指定します。
写真には載っていませんが、スタックを追加する新しいアカウントのIDを指定して作業をしているので、既存のスタックインスタンスには影響を及ぼしません。
指定した予算額、メールアドレスになっているか確認します。予算額は50ドルになっているので合っています。
SNSも作成され、指定したメールアドレスになっています。
StackSetsで展開したIAMロールと、StackSetsで展開したBudgets等が正常に機能していることが確認できました。テンプレート
Budgets,SNSDescription: "Basic Budget" Parameters: Amount: Type: String Default: 100 Description: Budgeted amount email: Type: String Description: Notification email1 address user Resources: Budget: Type: AWS::Budgets::Budget Properties: Budget: BudgetName: test1 BudgetLimit: Amount: !Ref Amount Unit: USD TimeUnit: MONTHLY BudgetType: COST NotificationsWithSubscribers: - Notification: NotificationType: FORECASTED ComparisonOperator: GREATER_THAN Threshold: 50 ThresholdType: PERCENTAGE Subscribers: - Address: !Ref SNS SubscriptionType: SNS - Notification: NotificationType: FORECASTED ComparisonOperator: GREATER_THAN Threshold: 100 ThresholdType: PERCENTAGE Subscribers: - Address: !Ref SNS SubscriptionType: SNS SNS: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: !Ref email Protocol: email TopicName: StackSetsBudgets1 SNSPolicy: Type: AWS::SNS::TopicPolicy Properties: PolicyDocument: Id: MyTopicPolicy Version: '2012-10-17' Statement: - Sid: My-statement-id Effect: Allow Principal: Service: budgets.amazonaws.com Action: SNS:Publish Resource: !Ref SNS Topics: - !Ref SNSIAMロール・ポリシーAWSTemplateFormatVersion: 2010-09-09 Description: Configure the AWSCloudFormationStackSetExecutionRole to enable use of your account as a target account in AWS CloudFormation StackSets. Parameters: AdministratorAccountId: Type: String Description: AWS Account Id of the administrator account (the account in which StackSets will be created). MaxLength: 12 MinLength: 12 Resources: ExecutionRole: Type: AWS::IAM::Role Properties: RoleName: AWSCloudFormationStackSetExecutionRole AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: AWS: - !Ref AdministratorAccountId Action: - sts:AssumeRole Path: / ExecuteBudgetsPolicy: Type: AWS::IAM::Policy Properties: PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "cloudformation:*" - "budgets:*" - "sns:*" Resource: "*" PolicyName: AWSCloudFormationStackSetExecutionRoleBudgetsPolicy Roles: - !Ref ExecutionRoleさいごに
セルフサービス型StackSets作成が初めてだったので結構身構えていましたが、やってみると思ったより簡単であることがわかりました。
CloudFormationの中にポリシーを入れることに対して苦手意識を持っていましたが、多少改善されたような気がします。
セルフサービス型にすることで無駄な確認メールが減り、最初から自分が望む設定のリソースを展開できるので結構嬉しいです。
ただIAMロールをOU単位でばらまくので、使わないアカウントが出る可能性があるのが残念ですが、これは仕方ないですね(たぶん)。
権限も最低限にしていますし、親アカウントしか使用できないので大丈夫でしょう。
- 投稿日:2021-01-21T00:33:00+09:00
Cloud Runでカスタムドメインの設定方法(Route53編)
- 投稿日:2021-01-21T00:19:08+09:00
【初心者】Amazon Inspector を使ってみる
1.目的
- セキュリティ関連サービスを一通り復習している。一度も触ったことの無かった Amazon Inspector について、チュートリアルレベルの確認を行い概要を理解する。
2.Amazon Inspector とは(自分の理解)
- EC2インスタンスに対する脆弱性評価を実施し、リスクを可視化するサービス。
- 分かりやすい解説は Developers.io記事:「AWS再入門ブログリレー Amazon Inspector編」 などにあるので、それを見ながら、自分の手で確認したことを記載する。
3.やったこと
- 評価対象とするインスタンスを作成する。
- Inspectorで以下を行う。
- 評価ターゲットの作成: ターゲット(評価対象インスタンス)を指定し、Agentをインストールする。
- 評価テンプレートの作成: ターゲット及び評価項目の選択を行う。
- 評価を実行し、結果を確認する。
- 評価結果に基づきOSの設定修正(脆弱性対応)を行い、再度評価を行い結果が変わることを確認する。
4.構成図
- 監査対象となるインスタンス(Amazon Linux 2)を1つ作成する。
- Systems Manager (Agentのインストールに使用)との通信のため、インスタンスにEIPを付与してインターネット通信可能とする。
5. 作業手順
5.1 事前準備
- 評価対象インスタンス(Amazon Linux 2)をパブリックサブネットに作成し、EIPを付与する。(標準のAMIからそのまま起動する。)
- Inspectorにおいて、評価対象インスタンスの指定はタグを用いて行うため、インスタンスに「Name:mksamba-inspector-target-instance」のタグを付与しておく。
- Inspectorの評価対象とするにはインスタンスにAgentをインストールする必要がある。Agentは今回はSystems Manager経由でインストールを行うため、インスタンスに対して、Systems Manager を用いるためのrole「AmazonSSMManagedInstanceCore」を付与しておく。
5.2 Inspector 評価ターゲットの作成
- 「評価ターゲット」の画面にて、評価対象とするインスタンスをタグにより指定し、「評価ターゲット」を作成する。
- 今回は先ほど作成したインスタンスだけが評価対象となるように、「Name:mksamba-inspector-target-instance」を指定する。
- 「Systems Manager - ノード管理 - Run Command」の画面で、評価対象インスタンスに対し、runコマンド(inspector agent のインストール)が実行されたことを確認する。
- 「評価ターゲット - Preview Target」の画面で、AgentのステータスがHealthyであることを確認する。
5.3 Inspector 評価テンプレートの作成
- 「評価テンプレート」の画面にて、「評価ターゲット」と「評価項目」の組み合わせをテンプレートとして作成する。
- 今回は以下のように設定した。
- 評価ターゲット: 前の手順で作成した評価ターゲットを指定
- ルールパッケージ: あらかじめ定義された4つのルールパッケージ(評価項目集)のどれを用いるのかを選択する。今回は4つのルールパッケージ全てを選択する。
- Assessment Schedule: 今回は1回のみ実行とするためチェックは外す。
- 「作成及び実行」を行い、評価テンプレートの作成及び初回評価実行を行う。
- なお、4つのルールパッケージの概要は以下の通り。
ルールパッケージ 内容 CIS Operating System Security Configuration Benchmarks-1.0 CIS (Center for Internet Security) ベンチマークは、システムを安全に構成するための構成基準およびベストプラクティス (Microsoft社によるCISの説明 を参照) Network Reachability-1.1 外部ネットワーク(VPC外)からのネットワーク到達性 Common Vulnerabilities and Exposures-1.1 CVE(common vulnerabilities and exposures) に基づく評価 Security Best Practices-1.0 ssh経由のrootログイン可否などの、AWSが推奨するベストプラクティス 5.4 結果の確認
- 「評価の実行」画面で、評価実行結果をダウンロードし、レポートとして見ることができる。
- 今回の結果は以下の通り。「CIS Operating System Security Configuration Benchmarks-1.0」で97件、「Common Vulnerabilities and Exposures-1.1」で4件、「Network Reachability-1.1」で1件、「Security Best Practices-1.0」で1件検出された。
ルールパッケージ 検出数 内容 CIS Operating System Security Configuration Benchmarks-1.0 97 「/tmp を適切に設定しているか確認せよ」などの細かい指摘が多数。 Network Reachability-1.1 1 「sshが空いてる」という想定内の指摘。SRCPortは絞ってあるので問題なし。 Common Vulnerabilities and Exposures-1.1 4 cloud-initに関して3件、chronyが1件。それぞれバージョンが古いとのこと。 Security Best Practices-1.0 1 rootログインが有効とのこと。 5.5 設定の修正と再評価
- 「Common Vulnerabilities and Exposures-1.1」で検出された脆弱性を試しに修正してみることにした。
- 検出された4件の内容(該当するCVE IDと対象のソフトウェア)は以下の通り。
CVE ID 対象のソフトウェア CVE-2018-10896 cloudinit-0:19.3-3.amzn2 CVE-2020-14367 chrony-0:3.2-1.amzn2.0.5 CVE-2020-8631 cloudinit-0:19.3-3.amzn2 CVE-2020-8632 cloudinit-0:19.3-3.amzn2
- 普通に yum update したところ、chronyもcloudinitも新しいバージョンに更新された。
[ec2-user@ip-172-16-0-41 ~]$ sudo yum update Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 3.7 kB 00:00 amzn2extra-docker | 3.0 kB 00:00 Resolving Dependencies --> Running transaction check ---> Package chrony.x86_64 0:3.2-1.amzn2.0.5 will be updated ---> Package chrony.x86_64 0:3.5.1-1.amzn2.0.1 will be an update --> Processing Dependency: libnettle.so.4()(64bit) for package: chrony-3.5.1-1.amzn2.0.1.x86_64 ---> Package cloud-init.noarch 0:19.3-3.amzn2 will be updated ---> Package cloud-init.noarch 0:19.3-4.amzn2 will be an update
- yum update実施後、再度、同じ評価テンプレートを用いて評価したところ、上記については解消(検出されない)になった。
6.所感
- 概念としては、昔からある「ホスト型脆弱性スキャナ」という感じで、そんなに抵抗感なく理解することができた。
- 気軽に実行はできるが、出てきた脆弱性のチェック(本当に対処する必要があるのかの確認)は大変なので、使うにしてもルールパッケージの選択などに注意したいと感じた。