- 投稿日:2021-06-21T23:00:20+09:00
Amazon Elasticsearch Serviceで特定のIPからのみアクセスを許可する2つの方法
はじめに Amazon Elasticsearch Serviceで特定のIPからのみアクセスを許可する方法を紹介します。 調べた限り、大きく以下の2つの方法があるようです。 VPCに配置してセキュリティグループを設定する IAMポリシーで設定する VPC配置してセキュリティグループを設定する 設定方法 Elasticsearchドメイン作成のStep3でネットワーク構成を選択することが出来ます。 ここで、「VPCアクセス」にすると、VPC、サブネット、セキュリティグループの設定が行えます。 セキュリティグループにIPアドレスを登録することで、アクセスを制限することが出来ます。 メリット 通信がVPC内で完結するので、パブリックで使うよりも安全です。 デメリット パブリックサブネットに配置してセキュリティグループを設定しても、ローカル環境からKibanaを見ることが出来ません。 試していませんが、ローカルからKibanaを見るためには踏み台サーバを利用するなどの工夫が必要なようです。 VPC内にあるAWS Elastic Search の kibanaをサクッと見たい時のメモ - Rso's Jotter VPC内に置いたElasticsearch ServiceにEC2のプロキシ経由でアクセスする - Qiita IAMポリシーで設定する ここでは、ネットワーク構成は「パブリックアクセス」にします。 アクセスポリシーに以下のような記述をします。 { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "es:*", "Resource": "arn:aws:es:ap-northeast-1:*********:domain/es1/*!, "Condition": { "IpAddress": { "aws:SourceIp": [ "***.***.***.***/32" ] } } } ] } 肝となるのは以下の部分です。 aws:SourceIp配下に記述したIPアドレスからのみアクセス出来るようになります。 何も設定しない場合はフルオープンになります。 "Condition": { "IpAddress": { "aws:SourceIp": [ "***.***.***.***/32" // 許可したいIPアドレス ] } } メリット ローカルからでもKibanaにアクセス出来る。 デメリット 設定を忘れてしまった場合にフルオープンになってしまうので注意が必要です。 最後に 今回紹介した2つの方法は、開発のしやすさとセキュリティがトレードオフになっています。 開発状況によって適切な選択をしていきたいものです。 参考 VPC を使用した Amazon Elasticsearch Service ドメインの起動 - Amazon Elasticsearch Service Elasticsearch ServiceへのアクセスをIPで制限する - サーバーワークスエンジニアブログ
- 投稿日:2021-06-21T19:43:18+09:00
【とりあえずハンズオン】AWS×LINEで実践!AWS利用料返信Botをつくろう
はじめに この記事では AWS のサービスと LINE Messaging API 連携させて AWS の請求情報を返してくれる LINE bot を作成するハンズオンです。 ベストプラクティスや間違いがあれば書き直していく予定です。 そもそもなんで Bot なんか作ろうと思ったんすか? 大人の事情があるんですけど それはタテマエでホンネを言うと 多額の請求でクラウド破産する人が いらっしゃるので手軽に請求情報にアクセスできる仕組みが欲しい。 あと、コンソールにログインするのが面倒 という事情があったりします。 開発環境 ヤマダにペペロンチーノをこぼされた初代 Surface Book 実装 RAM 8GB エディション Windows 10 Pro バージョン 20H2 OS ビルド 19042.867 Chrome 89.0.4389.90(Official Build) (64 ビット) Python 3 Version 3.95 今回は Web ベースで行うので利用する PC は Mac でも問題ありません。 が、途中で Python のソースコード編集したり、pipでパッケージをダウンロードするので Python3 がインストールされていること が最低条件になります。あとは ご自身が使いやすい環境に合わせていただけると幸いです。 今回扱うサービス AWS 側 AWS Lambda AWS API Gateway AWS IAM LINE 側 LINE Developers Console LINE Messaging API おことわり 今回は外部に漏らしてはいけない重要な情報を扱います。 LINE Developers Console で言うと Channel ID チャンネルシークレット Your user ID Bot basic ID および QR コード AWS 側では API Gateway で作成した API の URL アカウントのエイリアス ID および IAM ユーザ名 また、これらに加えて IAM ユーザおよびIAMロールは 最小権限の原則を守ってアカウントを運用しましょう。 事前準備 LINE Developers LINE Developers とは ざっくり言うと LINE の開発者向けサービス 自身の開発したアプリケーションに LINE を組み込む際に 必要な開発者向けの情報や API が提供されています。 LINE Developers Console にログインする LINE Developers Console を開く 「Messaging API」をクリックします。 「今すぐ始めよう」をクリック LINE アカウントにログイン ご自身の LINE アカウントで認証をしていただければと思います。 チャネルを作成 今回はこのように設定しました。 項目 入力内容 チャネルの種類 LINE Messaging API プロバイダー AWS 請求表示 チャネル名 AWS 請求確認 チャネル説明 AWS の請求情報を返信してくれる Bot です。 大業種 ウェブサービス 小業種 ウェブサービス(その他) 一応、各項目について説明すると チャネルの種類:LINE Messaging API プロバイダー:「新規プロバイダーの作成」を選択 プロバイダー名:管理コンソール上で表示される名前を入力 チャネル名:実際に LINE で表示される名前を入力 チャネル説明:チャネルの説明を書く 大業種:該当の業種を選択 小業種:大業種に合わせた該当の業種を選択 最後に規約を読んでチェック、作成をクリック 重要な情報をコピー 先ほど作成した チャネル を開く チャネルの基本設定にある以下の 2 項目をそれぞれメモしておく チャンネルシークレット Your user ID IAM ロールを作成する 今回は請求情報にアクセスする為の IAM ロールを JSON 形式で作成します。 IAM のダッシュボードにある「ロール」をクリック 一般的なユースケースから Lambda を選択 次のステップをクリック json でポリシーを作成する。このとき権限は最小限にとどめる。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["ce:GetCostAndUsage"], "Resource": ["*"] } ] } 「ポリシーの作成」画面から JSON タブをクリックして 上記のポリシーをコピペ タグを追加せずに次のステップへ 次のステップに進み、「MyCostExplorerRead」という名前を設定して 「ポリシーの作成」をクリック bot 用スクリプトの作成 今回は Pyhton を利用します。 ソースコードは雲のメモ帳さんにある ソースコードを引用してチョットだけアレンジしてみました。 lambda_function.py import os import sys import boto3 import json import calendar from datetime import datetime, date from linebot import (LineBotApi, WebhookHandler) from linebot.models import (MessageEvent, TextMessage, TextSendMessage,) from linebot.exceptions import (LineBotApiError, InvalidSignatureError) ce_client = boto3.client('ce') # Line API利用に必要な変数設定 user_id = os.getenv('LINE_USER_ID', None) channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None) line_bot_api = LineBotApi(channel_access_token) # 指定した期間のAWS利用料を返す関数 def get_aws_cost(start_day, end_day): try: response = ce_client.get_cost_and_usage( TimePeriod={ 'Start': datetime.strftime(start_day, '%Y-%m-%d'), 'End': datetime.strftime(end_day, '%Y-%m-%d') }, Granularity='MONTHLY', Metrics=['UnblendedCost'], ) except Exception as e: # boto3 Client error でも以下の文が表示される err_res = e.response['Error']['Message'] message = '[Error]' + '\n' + 'specify up to the past 12 months.' push_message(datetime.strftime(start_day, '%Y-%m-%d') + "-" + datetime.strftime(end_day, '%Y-%m-%d') + "\n" + message + "\n" + err_res) raise e return response['ResultsByTime'][0]['Total']['UnblendedCost']['Amount'] # 指定した年月の初日と最終日を返す関数 def get_frst_last_date(year, month): return calendar.monthrange(year, month) # Lineに送信するメッセージを作成する関数 def create_message(start_day, end_day, aws_cost): message = '開始日: ' + start_day.strftime('%Y年%m月%d日') + '\n' + '終了日: ' + end_day.strftime( '%Y年%m月%d日') + '\n' + 'AWS利用料: $' + str(round(float(aws_cost), 1)) return message # Lineにメッセージを送信する関数 def push_message(message): messages = TextSendMessage(text=message) line_bot_api.push_message(user_id, messages=messages) # Main def lambda_handler(event, context): # Lineに入力したテキストを変数に格納 # YYYY MMを想定。それ以外は、月初から今日までのAWS利用料金の取得。 args = json.loads(event['body'])['events'][0]['message']['text'].split(" ") # 引数チェック if len(args) == 2: try: check_date_format = args[0] + args[1] datetime.strptime(check_date_format, '%Y%m') year = args[0] month = args[1] except ValueError: message = '[Error]' + '\n' + \ 'Incorrect data format, should be YYYY MM' push_message(message) raise ValueError(message) else: year = None month = None # 変数YearとMonthがNullでなければ、指定した年月の月額利用料を取得する # Nullの場合は、月初から本日までの利用料を取得する if all(v is not None for v in [year, month]): # 指定した年月の月額利用料を取得する year_int = int(year) month_int = int(month) first_last_day = get_frst_last_date(year_int, month_int) start_day = date(year_int, month_int, 1) end_day = date(year_int, month_int, first_last_day[1]) aws_cost = get_aws_cost(start_day, end_day) # Line送信用メッセージの作成 message = create_message(start_day, end_day, aws_cost) # Lineにメッセージ送信 push_message(message) return # 月初から今日までのAWS利用料金の取得 today = datetime.today() first_day = today.replace(day=1) aws_cost = get_aws_cost(first_day, today) # Line送信用メッセージの作成 message = create_message(first_day, today, aws_cost) # Lineにメッセージ送信 push_message(message) return LINE SDK をダウンロード LINE bot 作成に必要なパッケージをインストールする為 pip install を利用します。 python -m pip install LINE-bot-sdk -t . ※最初、venv で作成しようと考えて仮想環境構築などという小賢しい手を使いましたが そもそも PC では動かさない上に import されている boto3 は AWS SDK の用意されているモノを利用するのであんまり仮想化の意味がなかったりなんだり。 boto3 用スクリプトと一緒に圧縮して保存します。 インストールが終わったら圧縮をして zip にしておきます。 うまく圧縮できると 2.2MB 弱になるかと思います。 ※今後、LINE の SDK に変化があれば、サイズも変わるかと思います。 Lambda を利用 Lambda とは ざっくり Web API としてコンピューティングリソースを利用できる AWS のサービス AWS の中ではコンピューティングリソースを提供してくれるサーバレスサービスの代表例 Lambda 関数を作成 LINE bot から利用する API を作成します。 まずは、Lambdaのダッシュボードから関数をクリック 関数の作成をクリック 関数名のところに任意の関数名を入力 Lambdaの関数名は「aws_cost_bot」としました。 Pythonは Version 3.8を利用 Lambdaのコードソース画面からzip をアップロード 環境変数を設定 「設定」項目をクリック後、環境変数をクリック 今回は以下の2点を環境変数に設定します。 環境変数名 設定する内容 LINE_CHANNEL_ACCESS_TOKEN チャンネルシークレット LINE_USER_ID Your user ID この環境変数を間違えていると Lambda から LINE bot を操作できません。 IAM ロールを 設定 同じく「設定」項目から実行ロールを設定する。 「アクセス権限」をクリック 実行ロールの編集をクリックすると以下のような画面が表示される。 実行ロールの「既存ロール」に先ほど作成した IAM ロールをアタッチして「保存」をクリック ※今回作成したロール名:「MyCostExplorerRead」 Lambda 関数をデプロイ 「コード」の「コードソース」画面に戻ってデプロイをクリック しばらくすると、デプロイが完了します。 ※LINE のメッセージを受信する前提で作成している為 テストを実行してもエラーになります。 { "errorMessage": "'body'", "errorType": "KeyError", "stackTrace": [ " File \"/var/task/lambda_function.py\", line 75, in lambda_handler\n args = json.loads(event['body'])['events'][0]['message']['text'].split(\" \")\n" ] } API Gateway を設定 ざっくり手順 リソースの作成 メソッドの作成 デプロイ リソースの作成 アクションからリソースの作成を選択 リソース名を決めます。 この名前は API の名前になります。わかりやすい名前をつけましょう。 メソッドの作成 アクションからメソッドの作成を選択 メソッドタイプを POST にしましょう。 メソッド作成がうまくいくと設定画面が右のフレームに表示されます。 項目 設定内容 統合タイプ Lambda 関数 Lambda プロキシ統合の使用 オン Lambda リージョン ap-northeast-1 Lambda 関数 aws_cost_bot ※Lambda 関数の設定内容は 各自、作成した Lambda 関数名に合わせていただければと思います。 デプロイ アクションから「API のデプロイ」を選択 設定画面が表示される。 ステージ名とステージの説明を入力 入力が終わったらデプロイ API の URL をコピー 先ほどのデプロイボタンをクリックすると api ステージエディターに画面が遷移 ステージ名、/(スラッシュ)、API 名、POST の順にクリックすると URL の呼び出しに API の URL が表示される。 LINE Developpers Console を設定 Webhook URL に APIGateway で取得した URL を登録 LINE Developers Console から Messaging API のプロバイダを開きます。 LINE チャネル名が保存されているプロバイダ名をクリック チャネル名をクリック チャネルの「チャネル基本設定」の右側にある Messaging API をクリック 「Webhook 設定」から Webhook URL を編集します。 Webhook URL は API Gateway でコピーした API の URL を貼り付けて「更新」をクリック ここで API の検証をする場合は「検証」をクリックすると 502 Bad Gateway が返ってきますが、問題ありません。 このとき「Webhook の利用」の利用にチェックが入っていない場合はオンにしてください。 実際に Bot を使ってみる 今回の返信パターンは 2 パターン 「料金」または適当な文字列を送信すると現時点における今月の料金を返信 「YYYY MM」と送信すると指定された日付の月初から月末までの利用料金を返信 パターン 1 現時点における今月の料金を聞く Success! うまくいった。 パターン 2 指定された月の料金を聞く Success! うまくいった。 こんな感じでうまくいったのですが実際は結構苦労した話があったりします。 次に続く 開発の過程で困ったこととその解決方法 IAM 周りの認証エラー 「IAM ポリシーで Billing 系のアクセスを有効にしたが、認証エラーになったこと」 ポリシーがわからずとにかく Cost Explorer の IAM ユーザアクセスをオンにしたり 他の Billing 関連のポリシーをオンにしたりと無意味なことをした。 AWS が用意する IAM ポリシー「Billing」には今回のポリシーが含まれていないので ロールとして利用しても意味がない。 ちなみに Billing を適用した場合は以下のようなポリシーを利用する。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "aws-portal:*Billing", "aws-portal:*Usage", "aws-portal:*PaymentMethods", "budgets:ViewBudget", "budgets:ModifyBudget", "ce:UpdatePreferences", "ce:CreateReport", "ce:UpdateReport", "ce:DeleteReport", "ce:CreateNotificationSubscription", "ce:UpdateNotificationSubscription", "ce:DeleteNotificationSubscription", "cur:DescribeReportDefinitions", "cur:PutReportDefinition", "cur:ModifyReportDefinition", "cur:DeleteReportDefinition", "purchase-orders:*PurchaseOrders" ], "Resource": "*" } ] } 確かに Cost Explorer (ce)のポリシーは存在するが とりわけ、AWS の利用料を取得するポリシーが存在しない。 じゃあ、CostExplorer の設定を全部オンにすれば解決するんじゃない。 確かに解決はしますが、利用予定のないポリシーは付与すべきではないです。 以下はダメな例 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["ce:*"], "Resource": ["*"] } ] } ※参考資料の StackOverFlow にはアスタリスクで全許可になっていますが 最小権限の原則を守る前提で考えるとキレイなポリシーではないです。 どう解決したか try-except をしているところで エラーオブジェクトの Class Name や詳細を閲覧した。 具体的には以下のエラー内容を bot につぶやかせることで解消 User: arn:aws:sts::000000000000:assumed-role/BillingFullAccess/aws_cost_bot is not authorized to perform: ce:GetCostAndUsage on resource: arn:aws:ce:us-east-1:000000000000:/GetCostAndUsage ※000000000000 にはアカウントエイリアス ID が入ります。 調査過程 1 回目 過去 12 ヵ月の請求情報を指定するようにエラーが出る。 ※get_aws_cost の try except にある文章を返している。 bot に入力した日付が取れているかを確認する為に入力内容をオウム返ししてくれるか検証するも うまいこと返してくれる。 2 回目 1 回目の内容から bot => API Gateway => Lambda => LINE bot の経路が確立できていることが確認できた。請求情報を閲覧できるかトライしてみるも Client エラーが出る。 そういえば、Lambda の IAM ロールってこれでいいんだっけと思い boto3 のエラーと Billing 系の IAM ポリシーを調べると IAM ロールがダメっぽいことに気づく。 いろいろ調べると Stack Overflow に辿り着き Cost Explorer 関連のポリシーを全部オンにするような内容で質問回答がなされていた。 ひょっとしてポリシー足りないんじゃないと思い、Client Error から IAM のエラーを拾えるか試してみる。 結果:拾えた。 どうやら、ce:GetCostAndUsage というポリシーがねぇよってことらしい。知らんがな。。。 ちなみに ローカルで作成したスクリプトをチェックすると boto3 のパッケージが入っていないように見えますが boto3 は AWS SDK に含まれるパッケージなので Lambda で利用する分にはインストール不要 ※つまり、pip install 不要 さいごに すぐにできそうな改修 AWS の利用料金に応じて Bot が返信してくれる 例えば 10 ドル以上なら「めっちゃつかっとるやんけ」 5 ドル以下ならば「そこそこつかっとるやんけ」 0 ドルなら「AWS 使ってあげて」 といった感じで請求内容に合わせて改修するとおもしろさが増すかも。 現状の課題 作成した bot で閲覧できる請求情報は作成時に利用したアカウントだけ 1個人につき一つのbotととなるうえにAWSの知識ないと構築が難しい。 botは1つでみんなが扱えるものとなるといろいろ問題にぶつかる。 bot 用のスクリプトは? Lambda 関数の作成は?エンドポイントどう作る? 請求情報を参照するユーザはどう認証する?。。。etc 返してくれる利用料金はドル表記で日本円ではない チョット前に流行った Google さんとこの為替レートって提供やめたんですね。 forex とかはたまた円表記をやめて BitCoin の価格表示にでもしてしまおうか。 Lambda が二重で叩かれる現象が起きている 以前、雑食サロンのもくもく会で聞いたことのあるエラー 確か、SQS を入れることで解決するんだっけ。 参考資料 boto3のドキュメント Cost Explorer boto3 Docs Stack OverFlow おわり
- 投稿日:2021-06-21T19:06:44+09:00
冗長性のあるブログサービスを構築する(冗長構成)
内容 この記事はAWS初学者を導く体系的な動画学習サービス 「AWS CloudTech」の課題カリキュラムで作成しました。 https://aws-cloud-tech.com 「基本的なブログサービスを構築する(シングル構成)」のレッスンに引き続き、 「冗長性のあるブログサービスを構築する(冗長構成)」のレッスンにて、より障害に強い冗長化の構成を学習しました。 前回のレッスン https://qiita.com/zakinicof/items/e040e1eb343e4c6220e9 このレッスンのゴール 前回の構成 上記の構成だと、EC2に障害が発生した場合、サービス全体が停止してしまうため、AZ 1cに新たにEC2とRDSを構築する。 2台のEC2はRDS Masterのデータを参照しているため、クライアントはどちらのEC2に通信しても最新のブログ記事を閲覧できる。(下記画像) 実施の流れ 前回作成したEC2を停止した場合 EC2の画面から前回作成したEC2を選択 「インスタンスの状態」タブを選択し、「インスタンスの開始」を選択 RDSを削除した場合 RDSの画面の左メニューから「スナップショット」を選択 スナップショット名のチェックボックスにチェックを入れ、「アクション」タブを選択 「スナップショットを復元」を選択 エンジン:「MySQL Community」であることを確認 DB インスタンス識別子:前回設定したものを入力 VPC:前回作成したVPCを選択 「追加の接続設定」タブを選択 サブネットグループ:前回作成したサブネットグループを選択 パプリックアクセス可能:前回と同様「なし」を選択 VPCセキュリティーグループ:「既存の選択」を選択し、前回作成したものを選択(デフォルトは×を選択して削除しておく) データベースポート:「3306」であることを確認 DBインスタンスクラス:「バースト可能クラス(tクラスを含む)」、「以前の世代のクラスを含める」を選択 ストレージタイプは「汎用SSD」、ストレージ割り当ては「20」であることを確認 マルチAZ配置:「スタンバイインスタンスを作成しないでください」が選択されていることを確認 アベイラビリティーゾーン:「ap-northeast-1a」を選択 データベース認証:「パスワード認証」を選択 「DBインスタンスの復元」を選択 復元したデータベースのステータスが「利用可能」となっていることを確認 ブラウザでブログが閲覧できることを確認 EC2インスタンスからパブリックIPアドレスを確認し、アドレスバーに貼り付けてEnterを押す。 正常に表示されればOK トップページを編集(WebServer1) Webサーバーを冗長構成するにあたり、どちらがWebサーバー1かWebサーバー2かを判断するために、トップページを編集して、Webサーバー1にどちらを表示しているか分かるようにする。 ターミナルを開き、EC2にSSH接続でログインする。(ssh -i キーペア名 ec2-user@WebServer1のパブリックIPアドレス) sudo su -コマンドで管理者権限にスイッチ cd /var/www/htmlでhtmlに移動 llで「index.php」ファイルがあることを確認 vi index.phpでファイルを開く iを押してインサートモードに切り替え、define( 'WP_USE_THEMES', true );の下の行にecho '<p>Web Server 1</p>';の一文を挿入(Webサーバー1と分かるようにするため) control + c → :wqで保存 EC2をコピーする EC2のAMIを取得して、取得したAMIをもう一方のAZで起動する。 EC2の画面で前回作成したインスタンスを選択 「インスタンスの状態」タブを選択 「インスタンスの停止」を選択 「インスタンスの状態」が「停止済み」になったら、「アクション」タブから「イメージとテンプレート(Image and templates)」→「イメージを作成」を選択 「イメージ名」と「イメージの説明」を入力 「イメージを作成」を選択 画面左のメニューから「AMI」を選択 作成したAMIのステータスが「pending」から「available」になるまで待つ。 左のメニューからインスタンスを選択 「インスタンスを起動」を選択 左のメニューから「マイAMI」を選択 先ほど作成したものが表示されるので選択 インスタンスタイプ:「t2.micro」を選択、次のステップへ ネットワーク:前回作成したVPCを選択 サブネット:「PublicSubnet2|ap-northeast 1c」を選択 自動割り当てパプリックIP:「有効」とし、次のステップへ ストレージは「8GiB」のままで次のステップへ 「タグの追加」を選択し、「キー」に「Name」、「値」に「WebServer2」とそれぞれ入力し、次のステップへ セキュリティグループの割り当て:「既存のセキュリティグループを選択する」を選択し、コピー元のWebサーバーのセキュリティグループを選択し、「確認と作成」を選択 これまで設定した項目を確認し、「起動」を選択 キーペアはコピー元のWebサーバーと同じものを選択し、「インスタンスの作成」を選択 コピー元のインスタンスを選択し、「インスタンスの状態」→「インスタンスを開始」を選択 データベースに保存されているURLを書き換える この後、再度ブログにアクセスしようとすると失敗してしまいます。 WordPressの仕様で、WordPressがインストールされた際に、データベースにサイトのURLの情報が保存されます。 先ほど、EC2のインスタンスを再起動した際にIPアドレスを固定化していなかったため、パブリックIPが変更されております。 このため、実際にサイトにアクセスするURLとデータベースに保存されているURLに不整合が生じたため、表示に時間がかかったり、レイアウトが崩れてしまう事象が発生するようです。 これを解決するために、データベースに保存されているURLの情報を新しいものに書き換えます。 1. ターミナルを開き、EC2にSSH接続でログインする。(ssh -i キーペア名 ec2-user@WebServer1のパブリックIPアドレス) 2. mysql -h RDSのエンドポイント名 -u ユーザー名 -pでMySQLにログイン(エンドポイント名はRDSの画面でデータベース名を選択すると確認できます。ユーザー名はWordPressをインストールした際に指定したユーザー名です。) 3. 続けてパスワードを入力 4. USE データベース名コマンドを実行(前回はデータベース名をwordpressとしたのでUSE wordpress) 5. 続けてSELECT * FROM wp_options WHERE option_name IN ('siteurl', 'home');を実行すると、現在設定されているサイトのURLが確認できる。 6. UPDATE wp_options SET option_value = 'http://xx.xx.xx.xx' WHERE option_name IN ('siteurl', 'home');コマンドを実行('xx.xx.xx.xx'はWebServer1のパブリックIPアドレス) 7. 再度SELECT * FROM wp_options WHERE option_name IN ('siteurl', 'home');を実行すると、EC2のパブリックIPアドレスに置き換わっていることが確認できる。 8. WebServer1のパブリックIPアドレスをコピーし、ブラウザに貼り付ける。 9. 正常に表示されればOK トップページを編集(WebServer2) ターミナルを開き、EC2にSSH接続でログインする。(ssh -i キーペア名 ec2-user@WebServer2のパブリックIPアドレス) sudo su -コマンドで管理者権限にスイッチ cd /var/www/htmlでhtmlに移動 llで「index.php」ファイルがあることを確認 vi index.phpでファイルを開く iを押してインサートモードに切り替え、define( 'WP_USE_THEMES', true );の下の行にあるecho '<p>Web Server 1</p>';の記述をecho '<p>Web Server 2</p>';に変更 control + c → :wqで保存 ELBを作成 EC2の画面の左メニューから「ロードバランサー」を選択 「ロードバランサーの作成」を選択 「Application Load Balancer」の作成を選択 「名前」を入力 スキーム:「インターネット向け」を選択 IP アドレスタイプ:「IPv4」を選択 VPC:作成したVPCを選択 アベイラビリティーゾーン:「ap-northeast-1a」と「ap-northeast-1c」を選択 サブネット:それぞれパブリックサブネットを選択し、次の手順へ 「HTTPS プロトコルをお使いください。」と警告が出るが、一旦次の手順へ進む。 セキュリティグループの割り当て:「新しいセキュリティグループを作成する」を選択、「セキュリティグループ名」、「説明」を入力し、次の手順へ ターゲットグループの名前を入力 ターゲットの種類:「インスタンス」を選択 プロコトルは「HTTP」、ポート:「80」、プロコトルバージョンは「HTTP1」を選択 ヘルスチェック/パス:「/readme.html」と入力 「ヘルスチェックの詳細設定」タブを開き、「正常のしきい値」を「2」、「間隔」を「10」とし、次の手順へ WebServer1とWebServer2にチェックを入れ、「登録済みに追加」を選択し、次の手順へ 設定に問題がなければ「作成」を選択 左メニューの「ターゲットグループ」を選択 作成したターゲットグループを選択し、「Targets」タブを選択 WebServer1,2の「Health status」が「initial」から「healthy」に変わるのを確認 RDSに設定されているサイトアドレスを書き換え ターミナルを開き、rootユーザーでhtmlディレクトリにいる状態でmysql -h RDSのエンドポイント -u WordPressインストール時のユーザー名 -pを実行 パスワードを入力 USE データベース名を実行 SELECT * FROM wp_options WHERE option_name IN ('siteurl', 'home');を実行、WebServer1のパブリックIPアドレスが設定されていることを確認 UPDATE wp_options SET option_value = 'http://ロードバランサーのDNS名' WHERE option_name IN ('siteurl', 'home');を実行(ロードバランサーのDNS名は、EC2の左メニュー「ロードバランサー」を選択すると確認できます) 再度SELECT * FROM wp_options WHERE option_name IN ('siteurl', 'home');を実行し、アドレスが変更されていることを確認 ロードバランサーの機能を確認 先ほどのDNS名をコピーし、アドレスバーに貼り付ける。 何度か更新ボタンを押すと左上の表示が変わることを確認できる。(ロードバランサーがWebServer1と2に振り分けている。) セキュリティーグループの設定を変更 現状だと、Webサーバーのセキュリティグループが全ての接続元からの80番通信が許可されているため、ロードバランサーのセキュリティグループからの通信のみOKとするよう設定を変更する。 EC2の画面のどちらかのインスタンスを選択し、「セキュリティ」タブから「セキュリティグループ」を選択 「インバウンドルールを編集」を選択 ポート範囲「80」のソースにロードバランサー作成時に設定したセキュリティグループを選択する。 「ルールを保存」を選択 再度ブラウザに戻り、更新ボタンを押し、表示に問題がないことを確認する。 障害テスト 1.EC2インスタンスのWebServer1を選択し、「インスタンスの状態」→「インスタンスの停止」を選択 1.ブログが閲覧できるか確認する。 RDSを冗長化 RDSの画面に移動し、左メニューの「データベース」を選択、ラジオボタンを選択した状態で「変更」を選択 下にスクロールし、「マルチAZ配置」を「スタンバイインスタンスを作成する (本稼働環境向けに推奨)」に変更する。 「続行」を選択 変更を適用するタイミング:「すぐに適用」に変更 「DBインスタンスを変更」を選択 データベースのステータスが「利用可能」、マルチAZが「あり」になるまで待つ。 RDSがマルチAZでフェイルオーバーするか確認 「アクション」タブから「再起動」を選択 「フェイルオーバーで再起動しますか?」にチェックを入れ、「確認」を選択 ブログが問題なく閲覧できることを確認する。 データベースの「ログとイベント」タブを選択し、「最近のイベント」を確認 「DB instance restarted」、「The user requested a failover of the DB instance.」、「Multi-AZ instance failover completed」のログを確認する。(マルチAZフェイルオーバーがスタートし、DBインスタンスがリスタート、フェイルオーバーが完了した) 今回はここまでになります。RDSが稼働したままだと料金がかかってしまいます。RDSを削除する場合は、「アクション」タブから「削除」を選択してください。
- 投稿日:2021-06-21T18:46:33+09:00
AWS Online Summit Japan(2021/5/11~12)参加レポ ②
はじめに こんにちは、新米プログラマーのYuu_Nです。 業務経験は研修でJavaを使用してECサイトを作成した後、C#を用いた業務アプリの開発の経験を経て今は社内研修(Java)のサブ講師をしています。 先月開催していたAWS Online Summit Japanの参加レポートの第二弾となります。 第一弾を読んでいただけている方は以下参加した目的、参加したセッションは第一弾と重複する内容となっているので飛ばして読んでいただけると幸いです。 参加した目的 4月に開催したAWSome Daysでは体系的にAWSの良さや主要のサービスについて学ぶことができたのでそこから更に基本的なサービスについて深堀して学びたいと思ったためです。 参加したセッション 参加したセッションは以下になります。 本イベントではセッション数が150を超えていたのでどうやって自分が学びたい内容のセッションを探せるか不安だったのですが、セッションの種類やタグで探すことができるようになっていました。 そのため今回は初学者向けのタグのついていたセッションの中からいくつか選択して参加してみました。 参加したセッション一覧 ・初学者向け AWS 学習パス ~まずはクラウドプラクティショナー認定資格から~ ・【基本の AWS サービス】今日からはじめる! AWS のデータベースと最適なサービスの選び方 ・【基本の AWS サービス】Amazon EC2 ことはじめ 〜あらゆるワークロードに対応する豊富な選択肢とコスト最適化オプション〜 ・【基本の AWS サービス】入門! AWS アイデンティティサービス ・【基本の AWS サービス】進化した Amazon S3 を最大限に活用する ・【基本の AWS サービス】AWS アカウントを守るためにおさえておきたいセキュリティ対策 ・【基本の AWS サービス】初心者向け Amazon VPC を中心としたネットワークの構成解説! ※公式サイトはこちら その中で特に印象に残った何点かのセッションについて記事を分けて記述します。 第二弾は以下セッションです。 【基本の AWS サービス】入門! AWS アイデンティティサービス こちらは初心者向けのタグが付いていたセッションだったので参加しました。 そもそもアイデンティティサービスとは何なのかという点から以下箇条書きと自分の感想を交えて記載します。 アジェンダ ・AWSのアイデンティティ ・マルチアカウント環境でのアイデンティティ管理 ・最小権限を実現するためのテクニック ・AWSのアイデンティティ AWSのアイデンティティは以下3つの基本要素があり、それぞれの管理対象を管理するために様々な管理方法がある。 ・Who(誰が) ・can access(アクセスできる) ・What(何に) それぞれの管理の対象 Who(誰が) →管理の対象:名前やメタデータ(所属や役職)など can access(アクセスできる) →管理の対象:ポリシーやコンプライアンス What(何に) →管理の対象:単一やグループ、共有されたリソース それぞれの管理方法 Who(誰が) →アイデンティティ管理 標準的な管理方法 Active DirectoryやSAML/OIDCなど can access(アクセスできる) →アクセス管理 環境に応じた管理方法 What(何に) →リソース管理 環境に応じた管理方法 ・AWSのアクセス管理 IAMでできること IAMとはAWS Identity and Access Management の略。 IAMではアクセス許可をポリシーで定義でき、数種類のアクセス定義方法を用意しているので IAMを使用することでアイデンティティ、アクセス、リソースの管理を行うことができる。 ・マルチアカウント環境でのアイデンティティ管理 AWSアカウントとは ・課金の分離単位 ・AWS環境の分割単位、リソース管理の枠組み ・サービスクォータ(サービス制限)の単位 ・セキュリティの境界 AWSアカウントは一つのコンテナと考えることができる(アカウントというコンテナに複数のリソースがあるイメージ)。 そのため、単一のアカウントではこの境界や単位のメリットを活用できないが、AWS利用が進み、より多くのアプリケーションやサービスを管理する際にこの境界や単位が活用できる。 AWSアカウント利用のメリット ・ガバナンス セキュリティ、及びガバナンス上の理由から開発環境、テスト環境、本番環境などでアカウントを分割することができる。 ・課金 課金に関する可視性、責任、及びアカウントごとのコントロールができる。 ・組織 リソースの操作権限を特定の事業部に委譲し、その中でより自由にAWSプラットフォームを活用しやすくすることができる。 ・運用 構成変更時の影響範囲を小さくし、他の組織を気にすることなく自身固有の環境を利用することができる。 上記アカウント利用のメリットは便利な反面管理が難しくなってしまうというデメリットがあるが、 以下提供されているサービスを利用することによってアカウント管理が容易になる。 AWS Single Sign-On(SSO) AWS アカウントとビジネスアプリケーションへのSSOを提供している AWS Control Tower ベストプラクティスにそったAWSマルチアカウント環境を簡単にセットアップできる ・最小権限実現のためのテクニック ・業務内容に応じた適切なアクセス権を必要なリソースに対して最小限にする ・継続的な確認:必要のないアクセス権を取り除く ステップ1:IAMのアクセスアドバイザーで各AWSサービスの最終利用時間をチェックして使われていない権限を見つける ステップ2:必要無いことを確認後、アクセス権限を削除する まとめ ・AWSのアイデンティティの基本要素とは「Who(誰が)」、「can access(アクセスする)」、「What(何に)」で構成されている。 ・上記アイデンティティをマルチアカウント環境とIAMを使用して管理することができる。 ・マルチアカウント実現のために必要の無い権限を取り除いて最小権限にするのがベストプラクティスである。
- 投稿日:2021-06-21T16:53:25+09:00
AWS EC2にDocker ComposeでGitlabを導入
事前準備 AWS EC2にDocker ComposeでJenkinsを導入 の続きとなります。 作業ディレクトリに移動 [ec2-user@ip-xxx-xx-xx-xxx container01]$ cd /home/docker/container01 docker-compose.ymlを編集 今回は試すにあたり、GitLab最小構成セットアップ(AWSに応用可) を参考にさせて頂きました。 AWS EC2にDockerでDocker Compose(1.29.2)を導入 にも記載しましたが、EC2のインスタンスタイプは「t2-medium」が最低レベルです。 ※複数コンテナ(Redmine, Jenkins, Gitlab)起動時、「t2-medium」でも何度かフリーズする事象が発生しています。 Gitlabのベースイメージには「gitlab/gitlab-ce:latest」を指定 8000番ポートでアクセス これまでRedmine, Jenkinsまではports指定のポート番号はシングルクォートで括っていなかったのですが、今回はシングルクォートで括らないと※1のエラーになり、ちょっとハマりかけました。(最初からシングルクォートで括る書き方していたら躓く事もないのでしょうが・・・) version: '3.9' services: #前回の続きのため、Redmine, MySQL, Jenkins部分のコンテナ設定は割愛 gitlab: image: gitlab/gitlab-ce:latest restart: always container_name: gitlab hostname: gitlab.example.com #他の方法を試していた名残と思うので不要かも ports: - '8000:80' #シングルクォートで括らないと※1のエラー - '4022:22' #シングルクォートで括らないと※1のエラー environment: - GITLAB_HOST=xx.xxx.xxx.xxx #elastic IPAdress(各自環境に応じて設定) - GITLAB_PORT=80 - GITLAB_SSH_PORT=4022 - GITLAB_ROOT_PASSWORD=root #root 初期パスワード volumes: - /var/gitlab/config:/etc/gitlab - /var/gitlab/logs:/var/log/gitlab - /var/gitlab/data:/var/opt/gitlab volumes: mysql-data: name: mysql-redmine docker-composeコマンドを実行し、Dockerコンテナ(Gitlabのみ)をバックグラウンド起動 ※1 以下は「docker-compose.yml」のports指定でポート番号をシングルクォートで括らずに実行した際のエラー(ご参考) [ec2-user@ip-xxx-xx-xx-xxx container01]$ docker-compose up -d gitlab Pulling gitlab (gitlab/gitlab-ce:latest)... latest: Pulling from gitlab/gitlab-ce 345e3491a907: Pull complete 57671312ef6f: Pull complete 5e9250ddb7d0: Pull complete 7f815eeffff6: Pull complete 1a4fe87ef93e: Pull complete eb13b56b9e19: Pull complete 2f19275b151e: Pull complete 84bbe8ae841a: Pull complete 0de204d1d029: Pull complete Digest: sha256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Status: Downloaded newer image for gitlab/gitlab-ce:latest Creating gitlab ... error ERROR: for gitlab Cannot create container for service gitlab: invalid port specification: "241342" ERROR: for gitlab Cannot create container for service gitlab: invalid port specification: "241342" ERROR: Encountered errors while bringing up the project. ports指定でポート番号を上記「docker-compose.yml」のようにシングルクォートで括り、再度Gitlabをバックグラウンド起動 [ec2-user@ip-xxx-xx-xx-xxx container01]$ docker-compose up -d gitlab Creating gitlab ... done Gitlab向けにEC2のポートを開放 作成した「docker-compose.yml」ではポート8000番を指定したため、EC2の「セキュリティグループ」を表示してインバウンドルールに8000番ポートを追加する必要があります。 Gitlabにアクセス ブラウザを起動し、 http://[Elastic IP アドレス]:8000/ にアクセスする。 以降、その後の画面遷移を参考としてキャプションを残しておきます。 ① 初期パスワード変更画面 ② ログイン画面 ③ Dashboard画面
- 投稿日:2021-06-21T16:20:45+09:00
Amazon Route 53 Resolver DNS Firewall 検証
こんにちは。弁護士ドットコム SRE 室のテイです。 今年(2021年)3 月にリリースされた Amazon Route 53 Resolver DNS Firewall を検証してみました。 DNS Firewall とは DNS Firewall は VPC からのアウトバウンド DNS リクエストを保護するサービスです。保護方法は以下のとおりです。 特定のドメイン名以外の名前解決をさせない 不良と判別されているドメイン名の名前解決をさせない 作成手順 Route 53 Resolver DNS Firewall という名前ですが、作成は Route53 ではなく、VPC のコンソールからです。 VPC コンソール画面で「DNS FIREWALL」→「ルールグループ」→「ルールグループを作成」の順でクリックします。 ルールグループの名前を記入して、「Next」をクリックします。 「ルールを追加」をクリックします。 ルール追加画面でルールの名前を記入します。 ドメインリストで「独自のドメインリストを追加」と「AWS マネージドドメインリストを追加」を選択できます。 今回は検証するため、「独自のドメインリストを追加」を選択します。 「新しいドメインリストを作成」を選択して、ドメイン名を記入して、ブロックしたいドメイン名を記入します。検証のため、www.google.co.jp をリストに入れました。 今回は対象ドメインをブロックするため、Action では BLOCK を選択します。 ALLOW:ドメインリストにあるドメインへのアクセスを許可する BLOCK:ドメインリストにあるドメインに対する名前解決できないようブロックする ALERT:アクセスを許可するけれど、DNS クエリログではアラートとして記録される ルールを追加した後、「Next」ではなく、「ルールを追加」ボタンをクリックします。間違って「Next」をクリックすると、設定したルールが追加されず、次の画面に行ってしまいます。 ちなみに、以下の2つが AWS からマネージドドメインリストとして提供されています。 AWSManagedDomainsMalwareDomainList(既知のマルウェアの通信先ドメインのリスト) AWSManagedDomainsBotnetCommandandControl(既知のボットネットの Command & Control サーバのドメインのリスト) どのようなドメインがこれらに含まれているか公表されてはいませんが、本番運用の時にマネージドドメインリストを利用するのが良いでしょう。 上記の画面で「ルールを追加」ボタンをクリックして、設定されたルールが追加されました。この画面で「Next」ボタンをクリックします。 複数ルールがある場合、優先度を設定し、「Next」をクリックします。 最後、タグの設定画面と確認画面がありますが、省略します。 ルールグループを作成した後、VPC と関連付けます。 対象ルールグループを選択して、下にある「関連付けられた VPC」をクリックして、「VPC を関連付け」をクリックします。 対象 VPC と関連付けた後、しばらくすると、ステータスが「完了」になりまして、DNS Firewall が動作し始めます。 動作確認 ルールグループと関連付けられた VPC 内で EC2 インスタンスを起動して、www.google.co.jp へアクセスしてみます。今回は curlとnslookupコマンドでテストしてみました。 「ルールを追加」画面で、BLOCK アクションを選択すると、NODATA、NXDOMAIN、OVERRIDE 3つからどのように応答するかが設定できます。それぞれをテストしてみます。 NODATA NODATA はクエリは成功したが、当該クエリについて利用可能な応答がないという結果になります。 NODATA に設定すると、 curl によるアクセスは対象ドメイン名の名前解決ができず、ちゃんとブロックされました。また、nslookup では No answer が表示されました。 $ curl -v www.google.co.jp * Rebuilt URL to: www.google.co.jp/ * Could not resolve host: www.google.co.jp * Closing connection 0 curl: (6) Could not resolve host: www.google.co.jp $ nslookup www.google.co.jp Server: 10.50.0.2 Address: 10.50.0.2#53 Non-authoritative answer: *** Can't find www.google.co.jp: No answer NXDOMAIN NXDOMAIN はクエリ内のドメイン名が存在しないという結果になります。 NXDOMAIN にする場合、curl の結果は同じになるのですが、nslookup を実行すると、NXDOMAIN が表示されることが分かります。 $ nslookup www.google.co.jp Server: 10.50.0.2 Address: 10.50.0.2#53 ** server can't find www.google.co.jp: NXDOMAIN OVERRIDE OVERRIDE はクエリに対するカスタムオーバーライドの応答を提供します。 ルールの編集画面で、「OVERRIDE」を選択して、当社が利用している情報共有サービス esa.io のドメインをオーバーライド用ドメインとして記入し、レコードタイプは CNAME を選択します。(CNAME しか選択できません) curl を実行して、301 になりまして、リダイレクトされたことが分かります。 $ curl -v www.google.co.jp * Rebuilt URL to: www.google.co.jp/ * Trying 54.199.**.**... * TCP_NODELAY set * Connected to www.google.co.jp (54.199.**.**) port 80 (#0) > GET / HTTP/1.1 > Host: www.google.co.jp > User-Agent: curl/7.61.1 > Accept: */* > < HTTP/1.1 301 Moved Permanently < Server: awselb/2.0 < Date: Tue, 08 Jun 2021 07:18:49 GMT < Content-Type: text/html < Content-Length: 134 < Connection: keep-alive < Location: https://www.google.co.jp:443/ < <html> <head><title>301 Moved Permanently</title></head> <body> <center><h1>301 Moved Permanently</h1></center> </body> </html> * Connection #0 to host www.google.co.jp left intact nslookup コマンドでも確認してみます。 www.google.co.jp に対するクエリには [team 名].esa.io の Public IP が返ってきています。 $ nslookup www.google.co.jp Server: 10.50.0.2 Address: 10.50.0.2#53 Non-authoritative answer: www.google.co.jp canonical name = [team 名].esa.io. Name: [team 名].esa.io Address: 52.194.**.** Name: [team 名].esa.io Address: 54.199.**.** 以上、Amazon Route 53 Resolver DNS Firewall の検証でした。 次回はブロック対象のドメインへアクセスすることが検知され、Slack へ通知する監視設定を紹介します。
- 投稿日:2021-06-21T16:13:25+09:00
AWSの資格を勉強してるときよく見る単語集その①
はじめに こんにちは!初めまして!喜村といいます! 今回はクラウドインフラの一つであるAWSの資格であるSAAやDVAを勉強しているときによく出てくる単語をざっくり纏めました。 よろしくお願いします!(。・ω・)ノ゙ API AWSだけに限らずWeb系の仕事に関わってくるとよく出てくるAPI。これは「Application Programming Interface」の頭文字です 英文字だけで意味を理解しようとすると、アプリケーション・プログラミング・インターフェイスで、大雑把に言うとアプリケーションをプログラミングするためのインターフェースという意味です。 インターフェース APIで出てきた単語インターフェースってなんでしょう?? これは「何か」と「何か」を繋げるものです。例えばUSBも「パソコン」と「周辺機器」を繋ぐものですのでインターフェースの一つになります。 プロビジョニング プロビジョニングとは、必要に応じてネットワークやコンピューターのなどの設備やリソースを提供できるように予測し、準備しておくこと。 供給や設備等の意味を表すプロビジョンという単語が元となって派生した単語です。 試験ではよくElastic BeanstalkやCloudFormationに関わる問題に出る単語 レイテンシ レイテンシとはデータ転送における指標のひとつで、転送欲求を出してから実際にデータが送られてくるまでに生じる通信の遅延時間のこと。 この遅延時間が短いことをレイテンシが小さいだったり遅延時間が長いことをレイテンシが大きいと表現したりします。 試験ではよくELBやRoute53に関わる問題によく出る単語 ロードバランシング(負荷分散) 負荷分散とは、文字の通り同種の複数の機器やシステムの間で、負荷がなるべく均等になるように処理を分散して割り当てること。そのような負荷の振り分けを行う聞きやシステムをロードバランサーという。 AWSではELBが負荷分散してくれる オートスケール オートスケールとはサーバーの負荷に応じて自動的にクラウドサーバーの台数を増減させる機能のこと。 システムにアクセスが集中したときはサーバーを自動で増やし、アクセスが少ない時はサーバーを自動で減らし常に必要最小限のサーバー数でシステムを安定的に稼働させることができる。 AWSのサービスではAutoScallingがこれ レプリケーション レプリケーションとはレプリカ(複製)をつくること。 同じネットワーク内や遠隔地にサーバーを設置してリアルタイムでデータをコピーする技術のこと。 マスターのデータベースと全く同じ内容のデータベースを作成できるため、負荷分散やホットスタンバイに有効な手段として普及しています。万が一障害が起こっても、システムを停止させることなく継続でき、予備を遠隔地に置くことで広域災害時の対策としても有効です。 AWSではRDS・Aurora・S3とかの問題によく出る リソース リソースとは資源や資産という意味のこと。パソコンやサーバーそのものやCPU・メモリといった構成要素の性能、容量であったり開発プロジェクトに投入される人的資源や予算のこと。 ミドルウェア ミドルウェアとはコンピュータを構成する要素の一つで、処理を行うアプリケーションと制御をするOSとの間に存在するソフトウェアのこと。 簡単に言うと、OSとアプリケーションの中間に位置して色々やってくれるヤツです笑 ワークロード ワークロードとは仕事量、作業不可などの意味を持つ英単語。ITの分野ではコンピュータやシステムにかかる処理の負荷の大きさを指すことが多い ソリューション ソリューションとは顧客の抱える問題・課題を解決したり要望・要求を満たすことが出来る製品やサービスのこと アーキテクト アーキテクトとはシステムや製品の全体的な設計を行う技術者を指すことが多い。 情報システムやソフトウェアの開発において、全般的な構造(アーキテクチャ)の設計や、基礎・中核部分の設計や仕様策定、全体のプロジェクト管理などを行うことが出来る技術者やそのような業務に関わるチームなどのこと。 アソシエイト アソシエイトとは補佐する役割を担う人を指す「準」「副」を表す。 さいごに さいごの3つの単語は合わせるとSAA(ソリューションアーキテクト・アソシエイト)になります。 間違ってる部分や意味が違うというご指摘があれば随時変更していきますのでコメントお待ちしております!! (。・ω・)ノ゙バイバイ
- 投稿日:2021-06-21T15:55:26+09:00
仮想MFAデバイスの設定時に発生した「エンティティは既に存在しています」の調査
仮想MFAデバイスの設定時に発生した「エンティティは既に存在しています」の調査 背景 社内の方からAWSを利用したいのでアカウントの作成を依頼されました。 アカウントの作成後、セキュリティ強化のため、設定登録を必須としているMFAデバイスの登録を依頼。 ところが、以下のようなエラーが発生してしまいました。 参考 AWS MFA 設定で「エンティティは既に存在しています」エラーの解決方法 環境 せっかくなので、先日構築したdocker desktop for Windowsに移設(コピー)したaws-cliのコンテナで作業してみることにします。 コンテナの起動 まずはdocker desktop for Windowsからコンテナを起動します。 しばらくすると起動しますので、「cli」をクリックします。 別ウィンドウでcliが起動します。 早速調査を開始しします。 詳細は割愛しますが、最初にaws configureを設定し、awsとの疎通を確認しておきます。 # aws configure AWS Access Key ID [None]: xxxxxxxxxx AWS Secret Access Key [None]: xxxxxxxxxx Default region name [None]: us-west-1 Default output format [None]: json # aws sts get-caller-identity { "UserId": "xxxxxxxxxx", "Account": "xxxxxxxxxx", "Arn": "arn:aws:iam::xxxxxxxxxx:user/xxxxxxxxxx" } list-virtual-mfa-devices で問題の SerialNumber を特定 こちらのコマンドを実行することで、仮想MFAデバイスのリストを取得できるようです。 実行してみたところ、エラーが発生しているIAMユーザのデバイスが登録されていることがわかりました。 # aws iam list-virtual-mfa-devices { "VirtualMFADevices": [ { "SerialNumber": "arn:aws:iam::xxxxxxxxxx:mfa/xxxxxxxxxx" }, { "SerialNumber": "arn:aws:iam::xxxxxxxxxx:mfa/root-account-mfa-device", "User": { "UserName": "xxxxxxxxxx", "UserId": "xxxxxxxxxx", "Arn": "arn:aws:iam::xxxxxxxxxx:root", "CreateDate": "2016-06-24T01:42:38+00:00", "PasswordLastUsed": "2020-02-19T07:06:41+00:00" }, "EnableDate": "2019-07-24T07:15:06+00:00" }, : : : delete-virtual-mfa-device で該当のデバイス情報を削除 listコマンドと同様にdeleteコマンドも用意されているようなので、該当のIAMユーザのデバイス情報を削除してみます。 # aws iam delete-virtual-mfa-device --serial-number "arn:aws:iam::xxxxxxxxxx:mfa/xxxxxxxxxx" 実行後は何もプロンプトにメッセージは表示されませんでしたので、再度LISTを取得し、正しく削除されていることを確認できました。 IAMユーザの利用者に連絡し、再度MFAデバイスの登録を実施してもらったところ、エラーは解消されており、無事にMFAデバイスの登録を行うことができました。 おわりに 実は当初、この方法を見つけることができず、別のIAMユーザを作成し、利用者の方に払い出し、AWS環境を利用してもらっていました。 しかし、根本的な解決にはなっていませんでしたので、今回調査と対処を実施、無事に解決に至りました。 エラーメッセージからして二重登録なのだろうとは思いましたが、調査方法や対処方法がすぐに出てこず、時間がかかってしまったのが反省点です。
- 投稿日:2021-06-21T15:46:45+09:00
Docker環境をUbuntuからWindowsへ移設(コピー)し起動する
Docker環境をUbuntuからWindowsへ移設(コピー)し起動する 背景 もともと、サブ機でUbuntuを稼働させており、そこでDockerやDocker-Composeを 利用できるような環境を構築していました。 今回、有志との活動の一環で、Windows上にDocker Desktopを構築したのですが、 その環境でも愛用していたaws-cliが利用できるコンテナを使いたくなり、 UbuntuからWindowsに移設(コピー)して両環境で利用できるようにしたいと考えました。 目的・やりたいこと ・ Windows10上のDocker Desktopでaws-cliが利用できるコンテナを稼働させる。 ・ 実際にAWSにアクセスしてaws-cliが利用できることを確認する。 環境 ・ Windows環境に、Docker DesktopとGit for Windows がインストールされていること。 ・ AWSにaws-cliでアクセスできること(アクセスキー、シークレットアクセスキーを入手済みであること) 関連記事 WindowsにDocker Desktopをインストールする 手順 まずはUbuntu環境からWindows環境へコンテナ起動に必要なファイルをコピーします。 コピー方法はいろいろあると思いますのでここでは割愛します。 最初に、Docker Desktopを起動します。 次に、コンテナ軌道に必要なファイルが格納されているフォルダにエクスプローラでアクセス。 フォルダ内で右クリックし、「Git Bash Here」をクリック。 以下のコマンドを実行し、コンテナを起動します。 $ docker-compose run --rm aws-cli bash ですが、Git for Windowsで実行すると、Ubuntu上で実行したときと動作が異なり、 プロンプトが帰ってきてくれませんでした。 $ docker-compose run --rm aws-cli bash Creating aws_aws-cli_run ... Creating aws_aws-cli_run ... done Docker Desktopを見ると起動はしているようです。 cliボタンがあるのでこちらをクリックしてみました。 すると、別ウィンドウでコンソールが表示されました。 ここからだと、普通にコマンドが打てるようでした。 ちょっとした操作の違いはあれど、何とか使えそうです。 aws-cliを利用するために、aws configureを実行し設定します。 # aws configure AWS Access Key ID [None]: xxxxxxxxxx AWS Secret Access Key [None]: xxxxxxxxxx Default region name [None]: xxxxxxxxxx Default output format [None]: json 試しにiamユーザ一覧でも取得してみます。 無事に実行でき、情報を取得できていることが確認できました。 # aws iam list-users --query 'Users[].UserName' 最後に aws-cliというコンテナ名ですが、このコンテナではansibleもkubectlも実行できるので 実はとても重宝しているコンテナだったりします。 (プロセス分離の考え方には反しているかもしれないとは思っていますが...) dockerの特性なので当たり前のことなのですが、環境が異なってもちゃんと起動でき、 しかも同じ環境を手に入れることができました。 知識としては理解していましたが、実際に異なる環境で起動させてことはなかったので 今回はとても良い検証となりました。
- 投稿日:2021-06-21T14:31:49+09:00
Amazon CloudWatch Logs Insight サンプル集
あまりサンプルがないように思えたのでメモとして残しておく 1000文字以上のメッセージを出力 fields @timestamp, @message, strlen(@message) as str_len | sort str_len desc | filter strlen(@message) > 1000 | limit 200 Lambdaの課金処理時間が1000ms以上のものを抽出 fields @timestamp, @message | parse @message '*Billed Duration: * ms*' as m1, lambda_time, m3 | filter lambda_time > 1000 | limit 200
- 投稿日:2021-06-21T14:15:56+09:00
CodeDeployエージェントのメモリ問題
事象 codepipelineから「変更をリリース」したところ、CodeDeployでコケた。 エラー 2021-06-16 09:47:03 ERROR [codedeploy-agent(2559)]: InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller: Error during perform: Errno::ENOMEM - Cannot allocate memory - rm -rf /opt/codedeploy-agent/deployment-root/b59fab18-5d0f-41bf-92e8-60410f9c6597/d-HCQHTD03B 2>&1 - /opt/codedeploy-agent/lib/instance_agent/platform/linux_util.rb:95:in メモリを割り当てられないらしい。 原因 デプロイ先のEC2インスタンスのメモリが80%を超えていた。 プロセスのメモリ使用率の割合を調べてみると、CodeDeployエージェントが異常にメモリ使っていた。53.8% ps aux --sort -rss USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 2559 0.0 53.8 1508016 1098544 ? Sl 5月13 23:05 codedeploy-agent: InstanceAgent::Plugins::CodeDepl 対応 CodeDeployエージェント再起動をすることでメモリ使用率が53.8%から2.7%になった。 今後の対応 CodeDeployエージェント再起動後にCodeDeploy実行を複数回行い、プロセスのメモリ使用率の上り具合を確認する。 codedeployエージェントメモリ使用率: 2.7 → 13.6 → 22.1 → 22.2 → 23.0 → 23.5 → 25.2 ... 結果 CodeDeploy実行する度にプロセスのメモリ使用率が大きく上がっていくことがわかった。 現状、定期的にCodeDeployエージェントの再起動を行わなければ、今回のようにメモリを割り当てられなくなり、CodeDeploy実行時にエラーになる。 こちらの参考サイトを元に以下対応 https://github.com/aws/aws-codedeploy-agent/issues/32 対応1 参考サイトによると、デプロイメントバンドルの解凍に使用されているサードパーティのメモリ内ライブラリが原因。unzipがインストールされていればメモリ使用量を小さくすることが出来るらしい。 しかし当サーバーではunzipはインストール済みだった。 確認コマンドyum info unzip 対応2 参考サイトによると、根本解決ではないが以下で回避はできる。 appspec.ymlファイルのValidateServiceフックから実行されるスクリプトにCodeDeployエージェントの再起動をスケジュールする行を追加 at -M now + 2 minute <<< $'service codedeploy-agent restart' 処理内容:CodeDeploy実行の2分後にCodeDeployエージェントの再起動を行う。 (atコマンドのオプション-Mに関して探しても出てこなかったのでつけないで設定) AppSpecのフックセクション appspec.yml (編集) version: 0.0 os: linux files: - source: src destination: /var/www/html/ permissions: - object: /var/www/html owner: apache group: apache hooks: ValidateService: // 追加 - location: deploy/codedeploy-restart.sh // 追加 runas: root deploy/codedeploy-restart.sh (新規作成) at now + 2 minute <<< $'service codedeploy-agent restart' 動作確認 CodeDeployログでシェルが実行されていることを確認 less /opt/codedeploy-agent/deployment-root/deployment-logs [2021-06-16 14:49:04.709] [d-N7S12UG4B]Script - deploy/codedeploy-restart.sh 複数回デプロイを実行してCodeDeployエージェントのメモリ使用率が上がらないことを確認 ps aux --sort -rss USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 16779 0.2 2.7 331548 55792 ? SNl 14:52 0:00 codedeploy-agent: InstanceAgent::Plugins::CodeDeploy
- 投稿日:2021-06-21T14:05:36+09:00
AWS Certificate Manager(ACM)でクライアント証明書を発行してnginxに設定する方法
はじめに ACMでプライベートCA(認証局)を立てて、有効期限を指定してクライアント証明書を発行してnginxに設定する方法をまとめます。 プライベートCAの構築には400USD/月の費用が発生するので気をつけてください。 1. ACMでプライベートCAを立てる ACMのコンソールにアクセスし、プライベート認証機関の「今すぐ始める」からプライベートCAを作成します。 ルートCAを選択し、認証機関名の設定をします。 全ての項目の入力が完了するとプライベートCAが作成されます。 2. ルート CA 証明書をインストールする ルートCA証明書の有効期限を10年に設定して作成します。 後ほど作成するクライアント証明書の有効期限はルートCA証明書の有効期限を超えることはできません。 3a. クライアント証明書の発行(有効期限13ヵ月固定) プライベートCAが作成されたので、Certificate Managerで証明書のリクエストをするときに「プライベート証明書のリクエスト」が選択できるようになります。 認証機関 (CA) の選択で先ほど作成したプライベートCAを選択し、クライアント証明書を発行します。 ACMのコンソールで証明書を発行した場合は有効期限が13ヵ月で固定されます。 クライアント証明書が発行されると、ACMのコンソールに表示されるので選択してアクション⇨エクスポートを選択します。 パスフレーズを入力します。 証明書本文、秘密鍵が表示されるので、ダウンロードします。 ダウンロードした秘密鍵のパスフレーズを解除するために下記コマンドを実行します。 openssl rsa -in private_key.txt -out private_key.pem 3b クライアント証明書の発行(任意の有効期限を指定) ACMのコンソールの代わりにAWS CLIを使用してクライアント証明書を発行します。 まずは、クライアント証明書の秘密鍵を生成します。 openssl genrsa 2048 > private-key.pem 生成した秘密鍵からプライベートCAに署名してもらうためのCSRを生成します。 -daysでクライアント証明書に任意の有効期限を設定します。 openssl req -new -key private-key.pem -out Client-csr.pem -days 730 プライベートCAでCSRを署名してクライアント証明書を発行します。 クライアント証明書の発行が成功すると、証明書のARNが出力されます。 --certificate-authority-arnにはプライベートCAのARNを指定します。 ValueにはCSRと同じ有効期限を設定します。 aws acm-pca issue-certificate --certificate-authority-arn arn:aws:acm-pca:us-west-2:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012 --csr file://Client-csr.pem --signing-algorithm "SHA256WITHRSA" --validity Value=730,Type="DAYS" --idempotency-token 1234 発行したクライアント証明書本文と証明書チェーンを取得します。 --certificate-authority-arnにはプライベートCAのARNを指定します。 --certificate-arnには先ほど発行したクライアント証明書のARNを指定します。 aws acm-pca get-certificate --certificate-authority-arn arn:aws:acm-pca:Region:Account:certificate-authority/12345678-1234-1234-1234-123456789012 --certificate-arn arn:aws:acm-pca:Region:Account:certificate-authority/12345678-1234-1234-1234-123456789012/certificate/66506378eb4e296c59b41bbb7b8dd068 --output text --query Certificate > certfile.pem aws acm-pca get-certificate --certificate-authority-arn arn:aws:acm-pca:Region:Account:certificate-authority/12345678-1234-1234-1234-123456789012 --certificate-arn arn:aws:acm-pca:Region:Account:certificate-authority/12345678-1234-1234-1234-123456789012/certificate/66506378eb4e296c59b41bbb7b8dd068 --output text --query CertificateChain > certchain.pem 発行したクライアント証明書をACMにインポートする際は下記のコマンドを実行します。 aws acm import-certificate --certificate file://certfile.pem --certificate-chain file://certchain.pem --private-key file://private-key.pem 4 nginxにプライベートCAの証明書を登録 ACMのコンソールからプライベートのCAの証明書を取得します。 構築したプライベートCAを選択し、アクション⇨CA証明書の取得を選択します。 証明書本文の内容をprivateCA.pemファイルにコピーします。 nginxの設定ファイルにプライベートCAの証明書を指定します。 server { listen 443 ssl; ssl_certificate ssl/allcert.pem ssl_certificate_key ssl/private.pem; ssl_verify_client on; ssl_client_certificate /path/to/privateCA.pem; #プライベートCAの証明書 ... } 5 動作確認 最後にcurlコマンドでクライアント証明書を指定してリクエストを送り、クライアント認証できていることを確認します。 curl --key ./private-key.pem --cert ./certfile.pem https://localhost --insecure 参考資料 https://aws.amazon.com/jp/premiumsupport/knowledge-center/resolve-acm-certificate-failed-error/ http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/node101.html
- 投稿日:2021-06-21T12:18:26+09:00
AWS WorkSpaces に Amazon LInux 2 の仮想デスクトップをJavaやPHP開発環境としてセットアップした時の作業履歴
前置き 備忘のための記録なので解説などは無し。 経緯 昨年末に新規購入した MacBook Pro が先日(2021年6月17日の晩)に突然起動しなくなった。 Appleサポートに問い合わせて最終的に修理してもらうことになったんだけど、修理が終わって帰ってくるのに7営業日ほどかかるとのこと。 その間、手元にある古い MacBook Air(2013-late 標準構成) を引っ張り出して仕事を代替しないといけなくなった。 今やってる仕事は「SpringBootを使ったWebアプリケーションを開発するためのDocker環境や各種IDE(EclipseやIntellij IDEA)やその他開発ツールを同時に立ち上げつつ、ZoomやMeet等のコミュニケーションツールで話しながらブラウザのタブをたくさん開いてる」なんていう状況が起きるので、もはやこの古い端末ではリソース不足。 そこで、Webアプリケーション開発環境を AWS WorkSpaces のLinux仮想デスクトップへ置いてリモートデスクトップ的に操作することにした。 構築して操作してみたら、コーディングと実装の動作確認を進めることはリモートデスクトップでもけっこう代替できる感触だったので、構築時の作業履歴をメモ代わりに残しておく。 作業履歴 ※重ねて言うが、備忘のための記録なので解説などは無し。 1. 選択した仮想デスクトップのスペック STEP3: バンドルの選択 バンドル: Standard with Amazon Linux 2 言語: Japanese(日本語) CPU: 2vCPU メモリ: 4GiB ルートボリューム: 80GB ユーザーボリューム: 100GB STEP4: WorkSPacesの設定 実行モード: AlwaysOn 暗号化: ※特に指定せず タグの管理: ※特に指定せず 上記の設定で仮想デスクトップのインスタンスを作成し、起動する。 2. Amazon WorkSpacesクライアントでLinux仮想デスクトップへアクセス後にやったこと ※起動してくる Amazon Linux 2 は fedoraベースのようなので、ネット上でCentOS7相当の情報を参考にすれば細かな問題は解決できる。 2-1: sudoのパスワード入力を省略する設定 $ sudo su - $ vi /etc/sudoers.d/01-ws-admin-user ※ログイン中のユーザのID行にて、末尾の ALL を NOPASSWD:ALL へ変更 2-2: 英語キーボードレイアウトへ変更 ※ 手持ちの MacBook Air が英語キーボードレイアウトなので。 GUIから 「システム>設定>キーボード」から「レイアウト」タブを開く 「英語US」のみにする キーボードの形式:「標準101キーPC」 2-2: 単語登録 参考 - http://www.ne.jp/asahi/akira/imakura/CentOS7.html 日本語入力にに変えるには、Super + スペースキーを押す。ただしこれを一度すると、次回からは、半角全角キーで日本語、英語入力の変更ができる。 登録したい単語を選択しAlt + R を押してから読みを入力すると、単語登録ができる。しかしAlt + Rは日本語入力ができる状態で押さなければならない。半角入力の状態で押すと記録しない。 登録した単語を削除するには、変換してその単語が出た時にCtrlキーとbackspaceキーを押す。 2-3: dockerセットアップ $ sudo yum check-update $ sudo amazon-linux-extras install docker $ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose $ sudo usermod -aG docker $(whoami) $ sudo systemctl start docker.service $ sudo systemctl status docker.service $ sudo systemctl enable docker.service 2-4: AWS環境下のLinuxインスタンスでdockerを利用する場合におけるネットワーク利用の問題に対処 上記でdocker使えるようになってはいるが、 docker-compose で作られる仮想ネットワーク配下の各種コンテナがDNSを解決できないらしく、下記の対応が必要。 (不採用) 対応策1: 極端な解決方法っぽいもの https://qiita.com/mosop/items/3784e1bf56b0d518e2c3 これだとローカルで app とか db とか mvn みたいなdocker-compose.yml に書いたサービス名でのホスト間のアクセスができなくなるので、困る。 (不採用) 対応策2: 根本的な対処方法?(っぽいけど、ちょっとよくわからない) (採用した対応策): dnsmasq の設定を行う 参考 - https://zenn.dev/sogaoh/scraps/d1cf2e766961e19a1a15 この記事の人が取り組んでいることがちょうど同じ問題のようだった。 dnsmasq なるものの使い方をちゃんと把握して、各種dockerコンテナからDNSリクエストにdnsmasqが応えるようにする必要がありそうだが... https://aws.amazon.com/jp/premiumsupport/knowledge-center/dns-resolution-failures-ec2-linux/ 上記に一通り目を通すと、書いてあるとおりにdnqmasqをセットアップするためのオートメーションスクリプトがAWSから提供されていて使い方も載っていた。 その通りにやったら、docker上でもDNSの解決ができるようになった。 3. 開発作業向けの準備 $ sudo yum install git 3-1: gitの設定 $ git config --global user.name "Tatsuhiko Kimita" $ git config --global user.email "nannbo@crappo.net" 3-2: Chromeのインストール $ sudo vi /etc/yum.repos.d/google-chrome.repo ### ↓編集内容 ### [google-chrome] name=google-chrome baseurl=http://dl.google.com/linux/chrome/rpm/stable/x86_64 enabled=1 gpgcheck=1 gpgkey=https://dl.google.com/linux/linux_signing_key.pub ### ↑編集内容ここまで ### $ sudo yum update $ sudo yum install --enablerepo=google-chrome google-chrome-stable 3-3: jdk 11系 のセットアップ $ sudo yum install java-11-amazon-corretto $ sudo alternatives --config java ## java-11-amazon-correttoを指定する $ sudo alternatives --install /usr/local/java_home java_home /usr/lib/jvm/java-11-amazon-corretto.x86_64 1 $ sudo alternatives --config java_home ## java-11-amazon-correttoを指定する $ sudo vi /etc/profile.d/java_home.sh ### ↓下記を入力して保存↓ ### export JAVA_HOME=/usr/local/java_home export PATH=$PATH:/usr/local/java_home/bin ### ↑入力内容ここまで↑ ### 3-4: anyenvやphpenvをセットアップ ################################### ## anyenv のセットアップ ################################### $ git clone https://github.com/riywo/anyenv ~/.anyenv $ echo 'export PATH="~/.anyenv/bin:$PATH"' >> ~/.bashrc $ echo 'eval "$(anyenv init -)"' >> ~/.bashrc $ ~/.anyenv/bin/anyenv install --init $ exec $SHELL -l $ ~/.anyenv/bin/anyenv init $ mkdir -p ~/.anyenv/plugins $ git clone https://github.com/znz/anyenv-update.git ~/.anyenv/plugins/anyenv-update $ git clone https://github.com/znz/anyenv-git.git ~/.anyenv/plugins/anyenv-git $ anyenv update ################################### ## phpenv, php8.0.x系 のセットアップ ################################### $ sudo amazon-linux-extras install -y epel $ sudo yum groupinstall 'Development Tools' $ sudo yum install \ re2c \ bzip2-devel \ freetype-devel \ krb5-devel \ libcurl-devel \ libicu-devel \ libjpeg-turbo-devel \ libpng-devel \ libtidy-devel \ libxml2-devel \ libxslt-devel \ libzip-devel \ oniguruma-devel \ openssl-devel \ readline-devel \ sqlite-devel \ systemd-devel \ zlib-devel $ anyenv install phpenv $ exec $SHELL -l $ echo 'export PATH="$(phpenv root)/bin:$PATH"' >> ~/.bashrc $ echo 'eval "$(phpenv init -)"' >> ~/.bashrc $ exec $SHELL -l $ phpenv --version $ mkdir -p $(phpenv root)/plugins/php-build $ git clone git://github.com/php-build/php-build.git $(phpenv root)/plugins/php-build $ phpenv install --list $ phpenv versions $ phpenv install -i development 8.0.7 $ phpenv global 8.0.7 $ php -v
- 投稿日:2021-06-21T11:22:23+09:00
ECS deploy通知
概要 ECSのdeployの開始と終了を通知する仕組み。 Amazon ECS のイベント内にデプロイ完了通知があるのでこちらを拾って通知する。 https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs_cwe_events.html 通知の流れ EventBridge→Lambda→slack(webhook)の流れ。 前提 予め通知したいslackのwenhookURLの取得をしておく。 Lambda まず、Lambda関数の作成。以下で作成する。 ラインタイム:Python3.8 タイムアウト値:1分 メモリ128M 以下code #!/usr/bin/python # -*- coding: utf-8 -*- import boto3 import urllib.request,urllib.parse import json def lambda_handler(event, context): msgdata = event['detail']['eventName'] resources = event['resources'][0] reason = event['detail']['reason'] client = boto3.client('ecs') fields = [] fields.append({ 'title': resources, 'value': msgdata, 'short': True, }) data = { 'attachments': [{ 'pretext': reason, 'color': 'good', 'fields': fields, }] } # Slack通知 url = 'https://hooks.slack.com/xxxxxxxx' req = urllib.request.Request(url, json.dumps(data).encode(), {'Content-Type': 'application/json'}) res = urllib.request.urlopen(req) res.read() res.close urlにはslackのwebhookを指定。 続いてEventBridgeを作成する。 EventBridge 全ての通知から、 ECS 関連の JSON のみをフィルターして抜き出す。 eventNameにデプロイステータスが入ってくる ステータスは以下2つ 開始 SERVICE_DEPLOYMENT_IN_PROGRESS 完了 SERVICE_DEPLOYMENT_COMPLETED パターンの定義で以下のルールを作成 カスタムパターンを選ぶ。 以下の例はdeploy完了のステータスを定義。ステータスごとにルールを作成する。 { "source": [ "aws.ecs" ], "detail-type": [ "ECS Deployment State Change" ], "resources": [ "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxxxx:service/clustername/hoge-service", "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxxxx:service/clustername/hoge01-service", "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxxxx:service/clustername/hgoe02-service", "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxxxx:service/clustername/hoge03-service" ], "detail": { "eventName": ["SERVICE_DEPLOYMENT_COMPLETED"] } } ターゲットを選択で上記で作成したLambda関数を選択する。 slackに通知するlambdaを指定する。 以下のように通知される。
- 投稿日:2021-06-21T11:09:37+09:00
WordPressでNephila clavata (絡新婦)を使って負荷分散をした話
目的と手段 管理しているHPの読み込み速度を上げたくて悩んでいました。画像や動画が多いサイトで読み込みに時間がかかっています。そこでWordPressのプラグインNephila clavata (絡新婦)を使って負荷分散をし、読み込み速度の改善を図りました。以下にその時の流れを書いておきます。 Nephila clavata (絡新婦) WordPressのメディアライブラリに画像をアップロードすると自動でAmazon S3へアップロードし、リンクも変更してくれる大変便利なプラグインです。 使い方 S3バケット作成 まずはS3のバケットを作ります。バケットネームはstatic.〇〇.com とかの静的ファイルを配布したいドメイン名が良いと思います。自サイトのドメイン名とは別のまだ使っていないサブドメインを利用してください。リージョンは日本なら東京です。作成したら、セキュリティ証明書画面で取得した「アクセスキー」「シークレットアクセスキー」をメモしておいてください。 Nephila clavata (絡新婦)の設定 Nephila clavata (絡新婦)をインストールし、有効化すると設定に「Nephila clavata」という追加メニューが表示されます。 先ほど作成したバケットがある「AWSアクセスキー」「AWSシークレットアクセスキー」「AWSリージョン」を入力します。入力した「AWSアクセスキー」「AWSシークレットアクセスキー」「AWSリージョン」が正しければ「S3 バケット」「S3 URL」という項目が表示され、作成済みの S3 バケットがリスト表示されます。「S3 バケット」には先ほどのバケットを「S3 URL」にはプロパティに書いてあるバケットのエンドポイントを入力します。※必ず http://となっていることを確認してください。 設定に問題が無ければ、画像ファイルが自動的にS3 バケットにアップロードされ、投稿中の画像URLがS3 バケットのURLに変更されます。
- 投稿日:2021-06-21T09:46:47+09:00
ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running? If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
sudo docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle コンテナを作成しようとしたところ、以下のエラーが発生しました。 ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running? If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable. 原因 結論から申し上げますと、今回の場合はdockerのサービスを開始していなかったのが原因でした。 解決策 sudo systemctl start docker を行ない、docker サービスを起動させ、再度 sudo docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle を実行したら解決しました。 補足 権限によっても同様のエラーが出る場合もあるようです。 その場合はDockerとdocker-composeにそれぞれ権限を付与する必要があります。 sudo usermod -aG docker $USER sudo chmod +x /usr/local/bin/docker-compose 実行後、設定を反映させるために一度ログアウトする必要があるようです。 Exit 参考 参考にさせていただきました。ありがとうございます。
- 投稿日:2021-06-21T09:26:19+09:00
AWS CloudShell とは
勉強前イメージ ブラウザで触れるコンソールの認識 調査 AWS CloudShell とは ブラウザから触れるコマンドラインになります。 Amazon Linux2ベールで、aws cli やコンテナサービスのcliなど予めインストールされています。 AWS CloudShell の特徴 Amazon Linux 2ベースの環境 パッケージインストールも可能 ファイルをアップロード,ダウンロード可能(ホームディレクトリは1GB保持することが出来ます。) 最大10個の同時シェルを無料で使用可能 起動方法 起動 ターミナルの画面、または検索から cloudshell で起動 1ダッシュボード _ EC2 Management Console - Google Chrome 2 起動 すぐに起動します。 2AWS CloudShell - Google Chrome 2021-06-19 14.51.18 いろいろ確認 amazon linux2でした $ cat /etc/system-release Amazon Linux release 2 (Karoo) /home配下は1GBで、logとかは20GB程度使える $ df -h Filesystem Size Used Avail Use% Mounted on overlay 30G 11G 18G 39% / tmpfs 64M 0 64M 0% /dev shm 1.9G 0 1.9G 0% /dev/shm tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup /dev/xvdcz 30G 11G 18G 39% /aws/mde /dev/loop0 976M 2.6M 907M 1% /home tmpfs 1.9G 0 1.9G 0% /proc/acpi tmpfs 1.9G 0 1.9G 0% /sys/firmware tmpfs 1.9G 0 1.9G 0% /proc/scsi rootにもなれました。 $ sudo su - -bash-4.2# 勉強後イメージ ちょっとaws cliでコマンド叩きたいねんって時に良いかもですね 参考 待望の新サービス AWS CloudShell がリリースされました! #reinvent ほぼ無料の「AWS Cloud Shell」を利用して「Amazon S3」の署名付きURLを発行する
- 投稿日:2021-06-21T09:11:32+09:00
AWS NetWork Firewall を使用した Web フィルタリングの実装 - Suricata compatible IPS rules -
本記事では AWS Network Firewall にて実装が可能な Suricata互換のIPSルールの解説と簡易的なルールを記載する Suricataとは Suricataとは、簡単にいうとオープンソースのセキュリティ監査エンジン。 Network Firewall では互換性のあるステートフルルールとしてSuricataが使用可能である。 以下、公式ドキュメント 特徴 他のステートフルルールである 5tuple あるいは domain list との大きな違いは、定義したシグネチャー通りに動作を行うところ。要は以下に記載したルールによって、検査を行う動作内容を表現する事が出来る。 また、5tuple あるいは domain list で実装が出来ないシグネチャー単位で優先順位を付ける事が可能。 ルール形式 基本的には公式ドキュメントに記載がある形式を使用する。 ルール形式は以下の3構成で定義される。 項目 動作内容 アクション 検査後にどのような対応を行うか ヘッダ プロトコル、IPアドレス、ポート、ルールの方向を指定 オプション ルールの詳細を定義 以下を例として色付けによる解説を行う。 drop http any any -> any any (msg:"HTTP traffic detected"; sid:200000; rev:1;) アクション アクションでは以下 3つが定義可能 Pass : パケットの検査を終了し、目的の宛先への送信を許可。 drop : ファイアウォールにアラートログが設定されている場合は、メッセージを送信する。パケットのすべての検査を終了し、目的の宛先に送信されないようにブロックする。 alert : ファイアウォールにアラートログが設定されている場合は、メッセージを送信する。パケットが目的の宛先に送信されることを許可。 Network Firewall では reject アクションはサポートされない。 ヘッダ ヘッダは以下大きく分けて 4つの構成から定義されている protocol : 検査するプロトコルを定義。指定可能なプロトコル一覧は以下となる。 tcp / udp / icmp / ip (allまたは any) / http / ftp / tls (sslを含む) /smb / dns / dcerpc / ssh /smtp /imap / ikev2 / krb5 / ntp /dhcp src and dest: 通信の送信元と、送信先のIP を指定。以下のように特定の演算子や変数の指定も可能。任意の送信先とする場合は any -> , -> any にて表現する。 演算子 内容 ../.. CIDR ! 否定/例外 [.., ..] グループ化 $HOME_NET / $EXTERNAL_NET 自分のネットワークの範囲 / 自分以外のネットワークの範囲 port :送信元と送信先のポートを指定する。 以下のように演算子を用いた指定も可能。任意ポートは any -> , -> any にて表現する。 演算子 内容 : ポート範囲 ! 否定/例外 [.., ..] グループ化 direction :通信の方向を指定する。 direction の記述については、以下の通り2パターン 演算子 内容 -> source から destionation への通信 <> 双方向の通信 このようにヘッダは記述を行う。先述したルールを上記に倣って解釈すると、全ての送信元から http プロトコルにて全ての送信先へ通信をする場合、 drop する。となる。 drop http any any -> any any (msg:"HTTP traffic detected"; sid:200000; rev:1;) オプション ルールの残りの部分はオプションで構成される。 これらは括弧 ( ) で囲まれ、; セミコロンで区切られる。 オプションはキーワードによって構成され、sid キーワード以外は任意のメタキーワードとなる。 一部の msg オプションには設定があり、キーワード、コロン、設定の順に指定される。その他には設定がなく、キーワードとなる。 sid : オプションで唯一必須の項目となる。任意のID を定義し、他のシグネチャーと重複しないようにする。 rev : シグネチャーのバージョンを表記する。変更があった際に更新をかけるキーワード msg : アラートに関するテキスト情報を提供する。 オプションはキーワードの数が多く、適切なキーワードを使用してシグネチャーを作成する。先述したルールを上記に倣って解釈すると、全ての送信元から http プロトコルにて全ての送信先へ通信をする場合、通信は drop され、"HTTP traffic detected" といったテキスト情報をアラートログへ記述するようになる。 drop http any any -> any any (msg:"HTTP traffic detected"; sid:200000; rev:1;)