- 投稿日:2021-12-05T23:37:56+09:00
AWS CLIで Web サイトを構築、管理、運用する(6日目)
5日目では、コンテンツ配信ネットワークのサービスである、CloudFront を導入しました。 6日目は、ついに、Web サイトに独自ドメインを割り当てます! 6日目の要約 独自ドメインを使うことで、アクセスしやすくするよ! AWS CLI の準備 このあたりをみて、好きなバージョンとお使いのOSにあった環境設定をしてくださいね。 なんなら、 AWS CloudShell で実行するのも楽でよいと思います。 この記事シリーズは、AWS CloudShell で実行し、実行例を載せています。 バージョン1 https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv1.html バージョン2 https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2.html 概要 Route 53 に独自ドメインを設定して Web サイトにアクセスできるようにするよ! さあ、やってみよう! 独自ドメインの取得 何は無くともまずは、独自ドメインを取得しましょう。無料ドメインで試行するのであれば、freenomでどうぞ。 .tk、.ml、.ga、.cf 、.gq ドメインが無償で取得できます。 .com や .net などを取りたい方はお名前.comなどで。 Route53 のホストゾーンを作成する 独自ドメインを取得しても利用可能な状態いしないといけません。 というわけで、Route53 で取得したドメインを利用可能な状態にします。 まずは、ホストゾーンを作成します。route53 create-hosted-zone コマンドを使用します。 # caller-reference オプションのためにユニークキー(uuid)を作成しておく uuid=`uuidgen` aws route53 create-hosted-zone ¥ --name <取得したドメイン名> ¥ --caller-reference ${uuid} コマンド実行が成功すると以下のように出力されます。 このあと、DelegationSet 内の NameServers を使うので確認しておきます。 { "Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/Z0*******************", "HostedZone": { "Id": "/hostedzone/Z0*******************", "Name": "<domain-name>", "CallerReference": "<uuid>", "Config": { "PrivateZone": false }, "ResourceRecordSetCount": 2 }, "ChangeInfo": { "Id": "/change/C00*******************", "Status": "PENDING", "SubmittedAt": "YYYY-MM-DDThh:mm:ss.000000+00:00" }, "DelegationSet": { "NameServers": [ "ns-***.awsdns-**.com", "ns-****.awsdns-**.co.uk", "ns-***.awsdns-**.net", "ns-****.awsdns-**.org" ] } } ドメイン取得元で ネームサーバの設定を行う freenom や お名前.comなどで設定を行います。 freenom であれば、取得したドメイン名を画面上部の Services > My Domains から表示し、Manage Domainボタンをクリックします。 そして、Management Tools > Nameservers を選択し、Use custom nameservers (enter below)から、先ほど確認したネームサーバを入力して保存します。 Certificate Manager(ACM) を使って、証明書作成のリクエストを行う 5日目のまとめでお伝えした通り、CloudFront を使用すると https で通信が可能です。 すごくざっくりといえば、独自ドメインでの暗号化のための証明書が必要です。 そこで、ACM を使って証明書をリクエスト、作成します。 この際、気をつけないとならないのは、「バージニア北部(us-east-1)」リージョンでないと、CloudFrontの独自ドメイン用の証明書として利用できないことです。 コマンドは acm request-certificate を使用します。 また、証明書の認証方法は DNS を用います。併せて、バージニア北部リージョンを指定します。 aws acm request-certificate --domain-name <ドメイン名> \ --validation-method DNS --region us-east-1 正常に終了すると、以下のように出力されます。 { "CertificateArn": "arn:aws:acm:us-east-1:************:certificate/********-****-****-****-************" } ドメイン認証をするために、Route53 にレコードを追加する 証明書のリクエストを行うと、ドメイン認証が済むまで保留状態になります。 acm describe-certification コマンドを使って、ドメイン認証に必要な情報を確認します。 aws acm describe-certificate --certificate-arn <証明書リクエストのARN> --region us-east-1 コマンドが正常に実行できると以下の json が返されます。 DomainValidationOptions の ResourceRecord に入っている、NAME と Value が必要な情報です。 { "Certificate": { "CertificateArn": "arn:aws:acm:us-east-1:************:certificate/********-****-****-****-************", "DomainName": "<ドメイン名>", "SubjectAlternativeNames": [ "ドメイン名" ], "DomainValidationOptions": [ { "DomainName": "ドメイン名", "ValidationDomain": "ドメイン名", "ValidationStatus": "PENDING_VALIDATION", "ResourceRecord": { "Name": "この後必要になる情報1", "Type": "CNAME", "Value": "この後必要になる情報2" }, "ValidationMethod": "DNS" } ], "Subject": "CN=ドメイン名", "Issuer": "Amazon", "CreatedAt": "YYYY-MM-DDThh:mm:ss.000000+00:00", "Status": "PENDING_VALIDATION", "KeyAlgorithm": "RSA-2048", "SignatureAlgorithm": "SHA256WITHRSA", "InUseBy": [], "Type": "AMAZON_ISSUED", "KeyUsages": [], "ExtendedKeyUsages": [], "RenewalEligibility": "INELIGIBLE", "Options": { "CertificateTransparencyLoggingPreference": "ENABLED" } } } acm describe-certificate コマンドの実行結果から、DomainValidationOptions の ResourceRecord に入っている、NAME と Value を使って、 Route53 に CNAME レコードを作成し、認証できる状態にします。 まずは、レコード作成用の json を以下のように作成します。 CNAME.json { "Changes": [{ "Action": "CREATE", "ResourceRecordSet": { "Name": "前述の「この後必要になる情報1」", "Type": "CNAME", "TTL": 300, "ResourceRecords": [{ "Value": "前述の「この後必要になる情報2」" }] } }] } 作成した json ファイルをインプットにして、 route53 change-resource-record コマンドを実行します。 ホストゾーンを作成した際の ホストゾーンIDの確認をお忘れなく! aws route53 change-resource-record-sets --hosted-zone-id <ホストゾーンのID> \ --change-batch file://CNAME.json 正常に実行できると以下のような json が返却されます。 { "ChangeInfo": { "Id": "/change/C0******************", "Status": "PENDING", "SubmittedAt": "YYYY-MM-DDThh:mm:ss.000000+00:00" } } ドメイン認証のステータスを確認する 概ね、数分以内にはドメイン認証が完了しますが、念のため、 acm describe-certificate コマンドで状況を確認します。 aws acm describe-certificate --certificate-arn <証明書の ARN> --region us-east-1 正常に成功したら、json が返るので DomainValidationOptions 内の ValidationStatus の値を確認します。 SUCCESS になっていればドメイン認証が成功しています。 (省略) "DomainValidationOptions": [ { "DomainName": <ドメイン名>", "ValidationDomain": "<ドメイン名>", "ValidationStatus": "SUCCESS", (省略) CloudFront の設定を変更する準備 証明書が作成できたら、次に、 CloudFront の設定を変更します。 現在の設定情報をもとに、変更を加えるので、 cloudfront get-distribution-config コマンドを実行します。 aws cloudfront get-distribution-config --id <CloudFront の Distribution ID> > distributionconfig_tmp.json ファイルに書き込みが行えたら、次に、必要な部分だけ抽出して更新用の元ファイルにします。jq コマンドを使うので、必要に応じてインストールしてください。AWS CloudShell であれば標準でインストール済みです。 cat distributionconfig_tmp.json | jq .DistributionConfig > distributionconfig.json また、get-distribution-config の出力内容のうち、 Etag の値が必要なので確認しておきます。 cat distributionconfig_tmp.json | grep ETag 以下のように出力されます。 "ETag": "**************", さて、distributionconfig.json を編集し、Distribution の更新が行えるように準備します。 以下の属性を編集します。 Aliases ViewerCertificate Aliases の見本 独自ドメインを指定します。 未設定の場合は、以下のようになっています。 "Aliases": { "Quantity": 0 }, 以下のように設定します。 "Aliases": { "Quantity": 1, "Items": [ "<独自ドメイン名>" ] }, ViewerCertificate の見本 証明書の情報を指定します。 未設定の場合は、以下のようになっています。 "ViewerCertificate": { "CloudFrontDefaultCertificate": true, "MinimumProtocolVersion": "TLSv1", "CertificateSource": "cloudfront" }, 以下のように設定します。 "ViewerCertificate": { "ACMCertificateArn": "<証明書のARN>", "SSLSupportMethod": "sni-only", "MinimumProtocolVersion": "TLSv1.2_2021", "Certificate": "<証明書のARN>", "CertificateSource": "acm" }, さらに、本ファイルに対して、以下のように頭と末尾に情報を入力します。 distributionconfig.json_頭 { “DistributionConfig”: { "CallerReference": (省略) 1行目に波括弧({)があるので、その2行目に対して、 “DistributionConfig”: { を追加します。 次に末尾です。 distributionconfig.json_末尾 (省略) "WebACLId": "", "HttpVersion": "http2", "IsIPV6Enabled": true } } 末尾に閉じ波括弧(})を追加します。 CloudFront の設定を変更する 準備ができたら、 cloudfront update-distribution コマンドを実行して、設定変更を行います。 aws cloudfront update-distribution --id <CloudFront Distribution ID> --cli-input-json file://distributionconfig.json --if-match 確認したETag の値 コマンド実行に成功すると、Distribution の内容が記された json が返されます。 これで、CloudFront に独自ドメイン名と証明書を割り当てることができました。 Route53 のホストゾーンにエイリアスレコードを作成する ホストゾーンを作成し、ネームサーバの設定を行い、そして、CloudFrontの設定を行ったので、Route53 に名前解決用のレコードを登録します。 コマンドは route53 change-resource-record を使用します。 コマンド実行前に、レコードの情報が入った json ファイルを作成しておきます。 HostedZoneId は AWSが管理/利用している Route53 のHostedIdです。こちらのマニュアルから確認できます。 record.json { "Changes": [{ "Action": "CREATE", "ResourceRecordSet": { "Name": "<ドメイン名>", "Type": "A", "AliasTarget": { "HostedZoneId": "Z2FDTNDATAQYW2", "DNSName": "<CloudFrontのディストリビューションドメイン名>", "EvaluateTargetHealth": false } } }] } ファイルが完成したら、 route53 change-resource-record-sets コマンドを実行します。 aws route53 change-resource-record-sets --hosted-zone-id <ホストゾーンのID> \ --change-batch file://record.json コマンドが正常に実行できたら、以下のように出力されます。 { "ChangeInfo": { "Id": "/change/C0*******************", "Status": "PENDING", "SubmittedAt": "YYYY-MM-DDThh:mm:ss.000000+00:00" } } これで独自ドメインを Route53 に登録できました。 独自ドメインを使ってアクセスしてみましょう。 動作確認 いつも通り、 curl コマンドで確認してみます。 curl https://<独自ドメイン名>/ 名前解決ができ、各種設定に問題がなければ3日目に作成した HTML が表示されるはずです。 <!DOCTYPE html> <html lang="ja"> <head> <title>Advent calendar 2021</title> </head> <body> <h1>Hello world!!</h1> <h2>Advent calendar 2021 DAY 3</h2> </body> </html> まとめ 6日目にしてついに、独自ドメインかつHTTPS化にたどり着きました! 今回は、 3種類のサービスについて AWS CLI で操作しました。結構色々なコマンドを実行したのではないでしょうか? 7日目以降は、CloudFront + S3 となっている状況なので、設定を見直していきます。 今回使ったコマンド route53 create-hosted-zone acm request-certificate acm describe-certificate route53 change-resource-record-sets acm describe-certificate cloudfront get-distribution-config cloudfront update-distribution
- 投稿日:2021-12-05T22:47:57+09:00
【AWS】AWS Config
はじめに AWS認定試験取得に向けてAWSの知識を整理するためのまとめです。 今回はAWS Configについてまとめます。 AWS Configとは AWSリソースの設定を評価、監査、審査できるサービスです。 どのリソースに対して、誰が、いつ、何をしたかを自動で継続的に記録し、確認ができます。 特徴 AWS リソースの設定履歴 AWS リソースの変更の詳細を記録し、設定履歴を確認できます。 AWS マネジメントコンソール、API、CLI を使用して、過去の任意の時点でリソースが どのように設定されていたかの詳細を取得できます。 ソフトウェアの設定履歴 EC2やオンプレミスで稼働しているサーバーで実行されるソフトウェアの設定変更を 記録できます。 また、他のクラウドプロバイダーによって提供される環境におけるサーバーや 仮想マシンで実行されるソフトウェアの設定変更も記録できます。 スナップショット 任意のタイミング、もしくは自動で定期的に構成情報をスナップショットとして 保存することができます。 AWS Config Rules リソースの準拠すべきルールで事前に設定することで、AWS Configで記録された 関連リソースの設定変更に照らして評価されます。 (全てのEBSボリュームが暗号化されているか、EC2にタグ付けされているか、など) ルールによるリソースの設定変更の評価結果はダッシュボードで確認できます。 ConfigRulesを使用することで、設定の観点からの全体的なコンプライアンスおよび リスクステータスの評価、経時的なコンプライアンス傾向の確認、どの設定変更によって リソースがルールに違反したかの特定が可能です。 料金 設定項目や、Config Rulesの評価数に応じて課金されます。 参考サイト https://aws.amazon.com/jp/config/ https://d1.awsstatic.com/webinars/jp/pdf/services/20190618_AWS-Blackbelt_Config.pdf
- 投稿日:2021-12-05T22:40:31+09:00
【Rails×AWS】yamlファイルにおける'please note that yaml must be consistently indented using spaces'の解決
https://qiita.com/gyu_outputs/items/b123ef229842d857ff39 こちらの記事を参考にrailsアプリをawsにデプロイする過程で発生したエラーに関する備忘録です。 エラー詳細 ページトップに添付した記事の中の「credentials.ymlの設定」の箇所で直面したエラーです。 credentials.yml db: database: アプリ名 username: root password: 設定したPW socket: /var/lib/mysql/mysql.sock credentials.ymlを記述した後に、 database.yml production: <<: *default database: <%= Rails.application.credentials.db[:database] %> username: <%= Rails.application.credentials.db[:username] %> password: <%= Rails.application.credentials.db[:password] %> socket: <%= Rails.application.credentials.db[:socket] %> 上記のようにdatabase.ymlを記述してrspecでテストを実行したところ下記のエラーが発生しました。 RuntimeError: YAML syntax error occurred while parsing /Users/hoshiyuunari/Desktop/new_app/selftalk_app/config/database.yml. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Error: (<unknown>): found character that cannot start any token while scanning for the next token at line 75 column 13 ちなみに上記エラーコードの「at line 75 column 13」はdatabase.ymlの中では password: <%= Rails.application.credentials.db[:password] %> の最初の"<"の部分です。 原因 エラーコード上はインデントの問題とありましたがそうではありませんでした。 database.yml production: <<: *default database: <%= Rails.application.credentials.db[:database] %> username: <%= Rails.application.credentials.db[:username] %> password: "<%= Rails.application.credentials.db[:password] %>" #""をつけただけ socket: <%= Rails.application.credentials.db[:socket] %> credentials.ymlで設定したpasswordの項目が関係していました。 私の場合、パスワードの頭文字が@だったのですがyamlファイルの規則では@には""をつける必要があります。 credentials.ymlではpasswordに""を付けていましたが環境変数として記述する場合も付ける必要がありました。
- 投稿日:2021-12-05T21:33:08+09:00
awscliのよく使うコマンド
AWSを触り始めて2年ぐらいになります。awscliは普段どんなコマンドを使っているのか、ふとコマンド実行履歴から振り返ってみました。 以下のコマンドで私の実行履歴を見て、目についたものを本記事にまとめました。 $ cat ~/.zsh_history | perl -nle '/^[^;]*;(.+)$/ and print $1' | perl -nle '/^aws --profile \S+ (.+)$/ and print $1 or /^aws (.+)$/ and print $1;' | LC_ALL=C sort | less S3関連 awscliで一番多いのがS3関連でした。 S3のオブジェクト一覧 lsコマンドとよく使うオプションや、よく使う他のコマンドとの組み合わせ。 wcはオブジェクトの数を数えてます。grepはファイル名で検索しています。 $ aws s3 ls $ aws s3 ls S3_BUCKET $ aws s3 ls s3://S3_BUCKET/S3_PREFIX/ $ aws s3 ls --human s3://S3_BUCKET/S3_PREFIX/ $ aws s3 ls --recursive s3://S3_BUCKET/S3_PREFIX/ $ aws s3 ls --recursive s3://S3_BUCKET/S3_PREFIX/ | wc -l $ aws s3 ls --recursive s3://S3_BUCKET/S3_PREFIX/ | grep PATTERN バケットのバージョニング設定をしている場合で、過去バージョンも含めてオブジェクトの一覧を見たい場合。 $ aws s3api list-object-versions --bucket S3_BUCKET --prefix S3_KEY $ aws s3api list-object-versions --bucket S3_BUCKET --prefix S3_PREFIX/ S3オブジェクト閲覧 lessコマンドで表示するコマンド。gzで圧縮されている場合はgunzip併用。JSONの場合はjqコマンド併用で見やすくします。 $ aws s3 cp s3://S3_BUCKET/S3_KEY - $ aws s3 cp s3://S3_BUCKET/S3_KEY - | less $ aws s3 cp s3://S3_BUCKET/S3_KEY.gz - | gunzip | less $ aws s3 cp s3://S3_BUCKET/S3_KEY.json.gz - | gunzip | jq . -C | less -SRXF ローカルにコピーしてからゆっくり見てもよいです。tarファイルはローカルに展開してから見たほうが楽。 $ aws s3 cp s3://S3_BUCKET/S3_KEY LOCAL_FILE $ aws s3 cp --recursive s3://S3_BUCKET/S3_PREFIX/ LOCAL_DIR/ $ aws s3 cp s3://S3_BUCKET/S3_KEY.tar.gz - | tar xvzf - S3オブジェクト作成 ローカルにあるファイルをS3にコピー。s3apiはあまり使わない。 $ aws s3 cp LOCAL_FILE s3://S3_BUCKET/S3_KEY $ aws s3api put-object --bucket S3_BUCKET --key sample2/aaa/1 --body test.txt / で終わるキーのオブジェクトを作成するには、s3コマンドではなくs3apiコマンドが必要です。以下のコマンドはサイズ0のオブジェクトを作成しますが、フォルダがあるかのように見せかけるときによく使います。 $ aws s3api put-object --bucket S3_BUCKET --key S3_PREFIX/ 既存のS3オブジェクトを編集する方法は、以前に記事に書きました。 S3にあるテキストファイルをサクッと編集するには - Qiita S3オブジェクトコピー バケット内でオブジェクトのコピー、バケットをまたいだコピー、異なるAWSアカウントなどでプロファイルをまたいだコピー。 $ aws s3 cp s3://S3_BUCKET/S3_KEY s3://S3_BUCKET/OTHER_S3_KEY $ aws s3 cp s3://S3_BUCKET/S3_KEY s3://OTHER_S3_BUCKET/OTHER_S3_KEY $ aws --profile PROFILE s3 cp s3://S3_BUCKET/S3_KEY - | aws --profile OTHER_PROFILE s3 cp - s3://OTHER_S3_BUCKET/OTHER_S3_KEY フォルダまるごとコピー。 $ aws s3 cp --recursive s3://S3_BUCKET/S3_PREFIX/ s3://S3_BUCKET/OTHER_S3_PREFIX/ $ aws s3 cp --recursive s3://S3_BUCKET/S3_PREFIX/ s3://OTHER_S3_BUCKET/OTHER_S3_PREFIX/ S3オブジェクトのキーをリネーム $ aws s3 mv s3://S3_BUCKET/S3_KEY s3://S3_BUCKET/OTHER_S3_KEY $ aws s3 mv --recursive s3://S3_BUCKET/S3_PREFIX/ s3://S3_BUCKET/OTHER_S3_PREFIX/ S3オブジェクトを削除 $ aws s3 rm s3://S3_BUCKET/S3_KEY $ aws s3 rm --recursive s3://S3_BUCKET/S3_PREFIX/ $ aws s3 rm --recursive --quiet s3://S3_BUCKET/S3_PREFIX/ S3バケットの各種設定 $ aws s3api list-bucket-analytics-configurations --bucket BUCKET_NAME $ aws s3api get-bucket-analytics-configuration --bucket BUCKET_NAME --id CONFIGURATION_ID $ aws s3api put-bucket-analytics-configuration --bucket BUCKET_NAME --id CONFIGURATION_ID --analytics-configuration JSON_STRING $ aws s3api get-bucket-encryption --bucket BUCKET_NAME $ aws s3api list-bucket-inventory-configurations --bucket BUCKET_NAME $ aws s3api get-bucket-inventory-configuration --bucket BUCKET_NAME --id CONFIGURATION_ID $ aws s3api put-bucket-inventory-configuration --bucket BUCKET_NAME --id CONFIGURATION_ID --inventory-configuration JSON_STRING $ aws s3api get-bucket-lifecycle-configuration --bucket BUCKET_NAME $ aws s3api get-bucket-logging --bucket BUCKET_NAME $ aws s3api list-bucket-metrics-configurations --bucket BUCKET_NAME $ aws s3api get-bucket-metrics-configuration --bucket BUCKET_NAME --id CONFIGURATION_ID $ aws s3api put-bucket-metrics-configuration --bucket BUCKET_NAME --id CONFIGURATION_ID --metrics-configuration JSON_STRING $ aws s3api get-bucket-policy --bucket S3_BUCKET | jq '.Policy' -r | jq . -C | less -SRXF $ aws s3api get-bucket-versioning --bucket S3_BUCKET CloudFormation $ aws cloudformation package --template-file TEMPLATE_FILE --output-template-file OUTPUT_FILE $ aws cloudformation deploy --template-file TEMPLATE_FILE --stack-name STACK_NAME $ aws cloudformation describe-stacks --stack-name STACK_NAME | jq -r '.Stacks[0].Outputs[0].OutputValue' $ aws cloudformation describe-stack-events --stack-name STACK_NAME $ aws cloudformation delete-stack --stack-name STACK_NAME デプロイ済みスタックのテンプレートを取得するにはget-templateコマンド。ただ、YAMLなのかJSONなのか、デプロイ時といま見たいのがどちらのフォーマットなのかで、どうしたらいいかは以前に記事に書きました。 $ aws cloudformation get-template --stack-name STACK_NAME AWS CloudFormationのデプロイ済みスタックのテンプレートを取得 - Qiita Lambda 一覧取得。 $ aws lambda list-functions $ aws lambda list-functions | jq -C ".Functions[].FunctionName" -r Lambdaの情報取得。2つ目のコマンドは、Lambdaのソースコード取得。 $ aws lambda get-function --function-name FUNCTION_NAME $ aws s3 cp "$(aws lambda get-function --function-name FUNCTION_NAME | jq .Code.Location -r)" LOCAL_FILENAME.zip Lambda実行。 $ aws lambda invoke --function-name FUNCTION_NAME /dev/null $ aws lambda invoke --function-name FUNCTION_NAME /dev/stdout CloudWatch Logs ロググループ関係。 $ aws logs create-log-group --log-group-name LOG_GROUP_NAME $ aws logs delete-log-group --log-group-name LOG_GROUP_NAME $ aws logs describe-log-groups --log-group-name-prefix LOG_GROUP_NAME $ aws logs put-retention-policy --log-group-name LOG_GROUP_NAME --retention-in-days NUMBER ログ自体をCUIで見るときは私はawslogsコマンドを使っています。 GitHub - jorgebastida/awslogs: AWS CloudWatch logs for Humans™ IAM IAM関係を見るコマンド。 $ aws iam get-user --user-name USER_NAME $ aws iam list-attached-user-policies --user-name USER_NAME $ aws iam get-user-policy --user-name USER_NAME --policy-name POLICY_NAME $ aws iam list-roles $ aws iam get-role --role-name ROLE_NAME $ aws iam get-policy --policy-arn POLICY_ARN IAMポリシーをawscliでいじる方法は、以前に記事に書きました。 AWS IAM Policyをawscliで作成・取得・更新 - suzuki-navi’s blog 次はインスタンスプロファイル関係。 $ aws iam list-instance-profiles $ aws iam get-instance-profile --instance-profile-name INSTANCE_PROFILE_NAME EC2 EC2を操作する機会は私は少ないです。こんなコマンド履歴は見つかりました。 $ aws ec2 describe-instances $ aws ec2 describe-instances --instance_ids INSTANCE_ID $ aws ec2 describe-network-interfaces $ aws ec2 describe-network-interfaces | jq '.NetworkInterfaces[] | [.VpcId, .AvailabilityZone, .SubnetId, .PrivateIpAddress, .RequesterId, .Attachment.InstanceId] | @tsv' $ aws ec2 describe-security-groups $ aws ec2 describe-subnets RDS RDS関係。 $ aws rds describe-db-instances $ aws rds describe-db-instances --db-instance-identifier INSTANCE_ID $ aws rds describe-db-parameter-groups $ aws rds describe-db-parameter-groups --db-parameter-group-name PARAMETER_GROUP_NAME $ aws rds describe-db-parameters --db-parameter-group-name PARAMETER_GROUP_NAME RDSのインスタンスにあるログを見る方法は以前に記事を書きました。 AWS RDSのログファイルを高速にダウンロードするスクリプト - Qiita Redshift RDSもRedshiftも、インスタンス自体をどうにかする場合はマネジメントコンソールで済ますことが多く、また中身のデータに対してクエリを投げたい場合はpsqlコマンドを使うことが多いです。従ってawscliでの実行履歴は少ないです。 $ aws redshift describe-clusters $ aws redshift describe-clusters --cluster-identifier CLUSTER_IDENTIFIER Glue データカタログ。 $ aws glue get-tables --database-name DATABASE_NAME $ aws glue get-tables --database-name DATABASE_NAME | jq '.TableList[].Name' -r $ aws glue get-table --database-name DATABASE_NAME --name TABLE_NAME クローラ。 $ aws glue get-crawler --name CRAWLER_NAME $ aws glue get-crawler --name CRAWLER_NAME | jq '.Crawler.State' -r $ aws glue get-crawler --name CRAWLER_NAME | jq '.Crawler.Targets.JdbcTargets[] | .Path' -r $ aws glue get-crawlers $ aws glue start-crawler --name CRAWLER_NAME コネクション。 $ aws glue get-connection --name CONNECTION_NAME ジョブ。 $ aws glue list-jobs --max-results 1000 $ aws glue list-jobs --max-results 1000 | jq '.JobNames[]' -r $ aws glue get-jobs $ aws glue get-jobs | jq -r ".Jobs[] | .Name" $ aws glue get-job --job-name JOB_NAME $ aws glue delete-job --job-name JOB_NAME $ aws glue start-job-run --job-name JOB_NAME Step Functions Step Functionsの実行をawscliからキックしてました。 $ aws stepfunctions start-execution --state-machine-arn STATE_MACHINE_ARN $ aws stepfunctions list-executions --state-machine-arn STATE_MACHINE_ARN CodeCommit レポジトリの一覧をawscliで見てました。 $ aws codecommit list-repositories その他 アクセスキーの設定とかAWSアカウントを確認できるコマンド。 $ aws configure list $ aws sts get-caller-identity 以上。
- 投稿日:2021-12-05T21:26:36+09:00
terraformをフレキシブルな変数化に組み直す
terraformをフレキシブルな変数化に組み直す はじめに これまで、terraformに触れ、いくつかのAWSリソースの構築を試してきました。 この検証で使用したterraformを有志に紹介し、試してもらう際に一つ困ったことがありました。 それは、AWSリソース名が重複してしまうこと... この問題を解決すべく、terraformの記述を変えず、変数定義だけ変更して対応できるように改修しました。 改修前のterraform 弊社のルールで、AWSリソース名の先頭には誰が作ったものかわかるように社員番号等で特定できるようにするというルールが有りました。 以下のterraformの「xxxxxxxx」は社員番号が記述されていると読み替えてください。 resource "aws_codecommit_repository" "xxxxxxxx_test" { repository_name = "xxxxxxxx_test" description = "This is the Sample App Repository" } このterraformを有志に展開し、試してもらうと、repository_nameが重複してエラーになってしまいます。 改修後のterraform そこで、terraform内に社員番号等の固有情報を保持せず、変数で補填するよう改修。 「xxxxxxxx」だった箇所を、「${var.user_prefix}」に置き換えます。 resource "aws_codecommit_repository" "repository" { repository_name = "${var.user_prefix}_test" description = "This is the ${var.user_prefix} Sample App Repository" } 変数定義ファイル このファイルには、どのような変数を使用するのか、また、AWS接続設定を定義しておきます。 ポイントは、このファイルにも固有情報は含んでいない点です。 # AWS接続に必要な個人情報の宣言 variable "aws_access_key" {} variable "aws_secret_key" {} variable "aws_region" {} # AWS接続設定 provider "aws" { access_key = "${var.aws_access_key}" secret_key = "${var.aws_secret_key}" region = "${var.aws_region}" } # 使用する変数の宣言 variable "user_prefix" {} 固有情報定義ファイル そして、このファイルに固有情報を定義します。 固有情報定義ファイルは共通的なファイル名でもよいか?とも思ったのですが、ここは個人単位にファイルを分けることにしました。 この考え方で用意しておけば、仮に、個人情報単位ではなく、開発、検証、商用と、環境単位に分けるという考え方にも応用できるからと考えたからです。 ファイル名は任意ですが、わかりやすいように社員番号を使用した「xxxxxxxx.tfvars」としました。 ※固有情報はマスクしています # AWS接続情報 aws_access_key = "xxxxxxxx" aws_secret_key = "xxxxxxxx" aws_region = "us-west-2" # 社員番号 user_prefix = "xxxxxxxx" 固有情報定義ファイルを指定してterraform planを実行 では、固有情報定義ファイルを指定して、terraform planを実行してみます。 変数の箇所が、ちゃんと固有情報に置き換わり実行されていることが確認出来ます。 # terraform plan -var-file=xxxxxxxx.tfvars Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_codecommit_repository.repository will be created + resource "aws_codecommit_repository" "repository" { + arn = (known after apply) + clone_url_http = (known after apply) + clone_url_ssh = (known after apply) + description = "This is the xxxxxxxx Sample App Repository" + id = (known after apply) + repository_id = (known after apply) + repository_name = "xxxxxxxx_test" + tags_all = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now. 固有情報定義ファイルを指定してterraform applyを実行 では、いよいよ固有情報定義ファイルを指定して、terraform applyを実行してみます。 変数の箇所が、ちゃんと固有情報に置き換わり構築されていることが確認出来ます。 # terraform apply -var-file=xxxxxxxx.tfvars -auto-applove Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_codecommit_repository.repository will be created + resource "aws_codecommit_repository" "repository" { + arn = (known after apply) + clone_url_http = (known after apply) + clone_url_ssh = (known after apply) + description = "This is the xxxxxxxx Sample App Repository" + id = (known after apply) + repository_id = (known after apply) + repository_name = "xxxxxxxx_test" + tags_all = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_codecommit_repository.repository: Creating... aws_codecommit_repository.repository: Creation complete after 2s [id=xxxxxxxx_test] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. 検証後は削除します 永続的にしようる環境ではなく、検証で作成した環境のため、最後には削除します。 このときも固有情報定義ファイルを指定して削除しました。 今回は対象リソースが一つだけだったので「-target」は指定していません。 # terraform destroy -var-file=xxxxxxxx.tfvars aws_codecommit_repository.repository: Refreshing state... [id=xxxxxxxx_test] Note: Objects have changed outside of Terraform Terraform detected the following changes made outside of Terraform since the last "terraform apply": # aws_codecommit_repository.repository has been changed ~ resource "aws_codecommit_repository" "repository" { id = "xxxxxxxx_test" + tags = {} # (7 unchanged attributes hidden) } Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the following plan may include actions to undo or respond to these changes. ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: # aws_codecommit_repository.repository will be destroyed - resource "aws_codecommit_repository" "repository" { - arn = "arn:aws:codecommit:xxxxxxx:xxxxxxxx:xxxxxxxx_test" -> null - clone_url_http = "https://git-codecommit.us-west-2.amazonaws.com/v1/repos/xxxxxxxx_test" -> null - clone_url_ssh = "ssh://git-codecommit.us-west-2.amazonaws.com/v1/repos/xxxxxxxx_test" -> null - description = "This is the xxxxxxxx Sample App Repository" -> null - id = "xxxxxxxx_test" -> null - repository_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx" -> null - repository_name = "xxxxxxxx_test" -> null - tags = {} -> null - tags_all = {} -> null } Plan: 0 to add, 0 to change, 1 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes aws_codecommit_repository.repository: Destroying... [id=xxxxxxxx_test] aws_codecommit_repository.repository: Destruction complete after 1s Destroy complete! Resources: 1 destroyed. おわりに これまでの検証はあまり変数化を意識出来ておりませんでしたが、変数化することで実行時にできるだけ手を加えなくても良い構成に改修できたかと思います。 これで、固有情報定義ファイルだけ修正すれば、有志も同じ検証を行うことができるようになりました。 まだ調査していませんが、この固有情報定義ファイルをファイルとして保持するのではなく、どこか別の箇所に保持しておき、実行時にそこから補填するような仕組みができないか?ということも考え始めています。 これができると、ファイルの修正は全く必要なく、固有情報を保持している箇所だけ修正するだけで、フレキシブルに環境を構築できるようになると思います。 このあたりの構想については一緒に活動している有志に相談しつつ検討を進めていきたいと思います。
- 投稿日:2021-12-05T21:20:04+09:00
EC2のWindowsサーバーで、PHP (Laravel ) + Apache + RDS(MySQL) + SFTP の環境構築 ②
はじめに 題名の通り環境構築の続きになります。 PHPのインストールからです。 ①はこちら↓ 流れ EC2を起動設定 Windowsサーバーにリモートデスクトップで接続する 日本語設定と時計合わせ Visual Studio Codeをインストール ApacheとVisual C++ ランタイムのインストール Apacheの起動↑①ではここまで PHPインストールし、Web上で確認 RDSの起動 composerとlaravelインストール プロジェクトを作成し、laravelページをWeb上で確認 phpmyadminインストールし、Web上で確認↑②ではここまで OpenSSH を使用して Windows に SFTP サーバーをセットアップ PHPインストール 以下の URL より PHP をダウンロードします。 https://windows.php.net/download/ PHP 8.1 の VS16 x64 Thread Safe版をZIPでインストールします。 Non Threatは、apacheを動かすphp8apache2_4.dllファイル等がないため、インストールしないようにしましょう。 解凍した中身を任意の場所に配置します。 今回は C ドライブ直下に php8 フォルダを作成し、中身をすべて移動します。 次に PHP の設定ファイルであるphp.iniを編集します。 php8フォルダ配下にphp.ini-developmentなどのファイルがあるので、これをコピーしてphp.iniを作成します。 プログラムの内容にもよりますが、おおむね以下の部分を編集すれば良いかと思います。 php.ini # 拡張モジュールのロード(コメント外す) extension=curl extension=fileinfo extension=gd2 extension=mbstring extension=mysqli extension=openssl extension=pdo_mysql # 追記 extension_dir = "c:\php8\ext" # 拡張モジュールの場所 date.timezone = Asia/Tokyo # タイムゾーンの設定 mysqli と mbstring と opensslは composerやlaravel で必要なため、拡張必須です。 必須というわけではありませんが、実行環境によっては設定変更が必要なパラメータをいくつか挙げてみます。 必要に応じて編集してください。 php.ini max_execution_time = 30 # 最大実行時間 [秒]、30秒過ぎると強制終了します max_input_time = 60 # リクエストを受け付ける最大時間 [秒]、受信に60秒以上かかると強制終了します memory_limit = 128M # スクリプトが確保できる最大メモリサイズ [byte] error_reporting = E_ALL # エラー出力レベル、お勧めは"E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT" display_errors = On # エラーを画面に出力(Offで出力しない) log_errors = On # エラーをerror_logに出力(Offで出力しない) post_max_size = 8M # POSTデータの最大サイズ [byte] upload_max_filesize =2M # アップロードファイルの最大サイズ [byte] session.gc_maxlifetime = 1440 # セッションデータが最短で破棄される時間 [秒]、お勧めは86400 php.iniのパラメータ詳細はこちら apacheのhttpd.confファイルの修正 Apache 側の設定も PHP の実行環境に合わせて編集が必要となります。 c:\Apache24\conf\httpd.confを編集します。 \Apache24\conf\httpd.conf # 編集 <IfModule dir_module> DirectoryIndex index.html index.php # index.phpを追加 </IfModule> # 追記 LoadModule php_module "C:/php8/php8apache2_4.dll" AddHandler application/x-httpd-php .php PHPIniDir "C:/php8" ・IfModule 当該モジュールが存在するときに処理されるディレクティブを指定するために利用します。 ・DirectoryIndex リクエストがファイル名を指定しなかった場合に表示するファイルを設定します。 デフォルトではindex.htmlのみ設定されているので、index.phpを追加します。 ・AddHandler 拡張子とハンドラを紐づけます。 この記述により拡張子 “.php” のファイルは PHP プログラムとして扱われます。 C:/php8/php8apache2_4.dllの確認 C:/php8/php8apache2_4.dllファイルがあることを確認しましょう。 なければ、インストールしたzipファイルがNon Threatのものになっている可能性があります。 参考記事 index.phpファイルを作成し、Web上で確認 c:\Apache24\htdocs配下にあるindex.htmlを削除し、index.phpを作成します。 index.php <?php phpinfo(); ?> Apache を再起動します。 ここまでの設定で、PHP のスクリプトが動作する状態になっているかと思います。 windowsサーバーのIPアドレスをブラウザのURL欄に入れてアクセスすると、以下のようにphp情報ページが表示されます。 PHPの環境変数設定 こちらの記事通りすると、コマンドプロンプトでphpコマンドが使用できます。 記事内で指定するパスはC:\php8とし、コマンドプロンプトは再起動しましょう。 C:\Users\Administrator> php --ini Configuration File (php.ini) Path: Loaded Configuration File: C:\php8\php.ini Scan for additional .ini files in: (none) Additional .ini files parsed: (none) phpコマンドが使え、自身で修正したphp.iniファイルが参照されていることが分かりました。 RDSの起動 RDSのタイムゾーンを東京にしたいので、まず、クラスターパラメータグループを作成します。 RDSで指定するバージョンは、mysql8.0ですので、パラメータグループファミリーも同様に設定します。 以下の記事を参考に、タイムゾーンを東京に変更します。 そして、auroraを起動設定しましょう。 バージョンは、Aurora MySQL 3.01.0 (Compatible with MySQL 8.0.23)を設定します。 セキュリティーグループは、EC2に対して、ポートを開けるのを忘れずに。 データベースを一つ作ります。今回はblogというDB名としてます。 パラメータグループは、先程作成したものを設定します。 auroraのクラスターのエンドポイント、ユーザ名、パスワードがlaravelの.envファイルで必要になりますので、メモしておきましょう。 composerとlaravelインストール 以下の記事通りにすると、インストールできます。 パスは、C:\php8\php.exeになっていることを確認しましょう。 composerインストール完了後は、コマンドプロンプトを再起動してから、composerと入力すると、インストールできていることが確認できると思います。 プロジェクトを作成し、laravelページをWeb上で確認 コマンドプロンプトでhtdocsフォルダに移動して cd c:\Apache24\htdocs laravelコマンドで新規プロジェクトを作成します。 C:\Apache24\htdocs> laravel new blog プロジェクト作成後、laravelのバージョンを確認してみます。 php artisanは、必ずプロジェクトディレクトリ内で行ってください。 C:\Apache24\htdocs>cd blog C:\Apache24\htdocs\blog> php artisan -v Laravel Framework 8.74.0 laravelの.envファイル修正 C:\Apache24\htdocs\blog\.envファイルを修正します。 .env APP_URL=http://IPアドレス ←サーバーのIPにする DB_CONNECTION=mysql DB_HOST=←RDSのエンドポイント(auroraの場合、ライターインスタンス) DB_DATABASE=データベース名 DB_USERNAME=RDS作成時のユーザ名 DB_PASSWORD=設定したパスワード laravelのindex.phpをWeb上で確認 apacheのhttpd.conf修正します。 Apache24\conf\httpd.conf #DocumentRoot "${SRVROOT}/htdocs" DocumentRoot "${SRVROOT}/htdocs/blog/public" #<Directory "${SRVROOT}/htdocs"> # AllowOverride All #</Directory> <Directory "${SRVROOT}/htdocs/blog/public"> AllowOverride All </Directory> httpdファイルを編集後、apacheを再起動します。 そして、アプリのキャッシュを削除します。 C:\Apache24\htdocs\blog>php artisan cache:clear Application cache cleared! キャッシュコマンドのまとめ記事になります。 WindowsサーバーのIPアドレスをブラウザのURL欄に入れて、アクセスすると、laravelのindex.phpが表示されました。 エラー対応 apacheが再起動できない場合、コマンドでapacheを起動すると、エラー内容を教えてくれます。 C:\Apache24\bin>httpd.exe -k start AH00526: Syntax error on line 236 of C:/Apache24/conf/httpd.conf: Require not allowed here phpmyadminインストール 下記サイトからphpmyadminをダウンロードします。現在の最新は5.1.1バージョンでした。 ダウンロード後、ドキュメントルートであるC:/Apache24/htdocs/blog/public内でphpmyadminディレクトリとして、展開します。 php.iniファイルの修正 php.iniの中の891行目辺りを次のようにコメントが外れているか確認します。 なければ、追記します。 C:\php8\ext配下にphp_mysqli.dllファイルがあることも確認しましょう。 php.ini ;extension=php_mysqli.dll extension=php_mysqli.dll php.iniを保存してApacheを再起動します。 phpmyadminのconfig.inc.phpファイル修正 phpMyAdminフォルダの中にconfig.sample.inc.phpファイルがありますので、それをコピーして名前をconfig.inc.phpに変更します。 config.inc.phpを修正します。 C\Apache24\htdocs\blog\public\phpmyadmin\config.inc.php /* Server parameters */ $cfg['Servers'][$i]['host'] = 'localhost'; ↓ C\Apache24\htdocs\blog\public\phpmyadmin\config.inc.php /* Server parameters */ $cfg['Servers'][$i]['host'] = '【RDSエンドポイント(auroraの場合、ライターインスタンス)】'; http://サーバーIP/phpmyadmin/にアクセスすると、ログイン画面がでます。 RDSのユーザー名とパスワードを入力すると、ログイン成功します! 補足ですが、phpmyadminは、ip制限やBasic認証をかけ、セキュアな状態でアクセスを行えるようにしましょう。 phpmyadminパスフレーズ設定 設定ファイルに、暗号化 (blowfish_secret) 用の非公開パスフレーズの設定を必要とするようになりました。というエラーが出ました。 config.inc.php内に長さは 32 文字以上パスフレーズを設定します。 指定したパスフレーズは内部で使用されるだけです。あとでこのフレーズを入力するような画面が出てくるわけではありませんので、適当で良いです。 C\Apache24\htdocs\blog\public\phpmyadmin\config.inc.php /** * This is needed for cookie based authentication to encrypt password in * cookie. Needs to be 32 chars long. */ $cfg['blowfish_secret'] = ''; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */ ↓ C\Apache24\htdocs\blog\public\phpmyadmin\config.inc.php /** * This is needed for cookie based authentication to encrypt password in * cookie. Needs to be 32 chars long. */ $cfg['blowfish_secret'] = 'hogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge'; phpmyadminページを更新すると、表示されなくなりました。 phpmyadmin環境保管領域設定 また、以下のような表示が出ています。 phpMyAdmin 環境保管領域が完全に設定されていないため、いくつかの拡張機能が無効になっています。理由についてはこちらをご覧ください。 代わりにデータベースの操作タブを使って設定することもできます。 これは、下記の記事通り設定すると、環境保管領域が設定され、表示が消えます。 logファイル関連 apacheのログファイル:C:\Apache24\logs配下 laravelのログファイル:C:\Apache24\htdocs\blog\storage\logs/laravel.log 次回、OpenSSH を使用して ローカルPCからWindowsサーバーにSFTPを用いたファイル転送する設定を行います。 参考記事
- 投稿日:2021-12-05T20:35:05+09:00
Serverless Frameworkでニュースサイトの新着記事をLINEで通知するアプリを作る
アプリケーション構築を学習する一環として、RSSフィードで配信された記事をLINE Messaging API経由で通知するアプリをServerless Frameworkで作りました。 友達追加すると、 新着記事を定期配信したり、手動で取得したりすることができるアプリです。 成果物はGithubにアップロードしていますが、せっかくなのでアプリの概要と、ハマったポイントをこちらにも投稿しておこうと思います。(以下、Github上のREADME.mdのほぼ抜粋です) 概要 RSSFeedで配信された記事を、LINE Messaging API経由で購読する 購読対象の記事は、設定用サイトで追加・削除・有効化・無効化が可能 定期購読のほかに、LINEでメッセージを送ることで記事を手動購読することも可能 システム構成は以下の通り。AWS上にソースをデプロイし、LINE Messaging API・LIFFと連携させる。 環境 種類 バージョン OS Windows10 version 2004 Node 14.17.5 Serverless Framework 2.66.1 開発環境 VSCode & Powershell ソース Githubにアップしています。 使ったサービス・言語・フレームワーク サービス・言語等 詳細 言語・環境 バックエンドのロジックはすべてNode.js v14.17.5で構築。 フレームワーク フレームワークはServerless Framework v2.66.2を用いて、AWS上サービスをデプロイした。 また、いくつかプラグインを導入した(※1)。 LINE Messaging API LINE上でのメッセージを受信し、適切な応答をするためにLINE Messaging APIを導入。無料枠で利用するので、月1,000件のメッセージ送信数制限には要注意・・・。応答はFlex Message(カルーセル型)もしくはテキスト形式で実施。 LIFF LINE Front-end Framework (LIFF)を使って、設定用のWebサイトで、LINEログインを利用しユーザID・名前・プロフィール画像を取得。 データベース AWS DynamoDBにユーザごとの情報(※2)を格納。 UI React + React-Bootstrap + Fontawesomeで設定画面のUIを構築。 ※1 利用したServerless Frameworkのプラグインは以下の通り。 server/serverless.yml抜粋 plugins: - serverless-dynamodb-local #DynamoDB接続部分の開発・テスト用 - serverless-vpc-plugin #Lambda用のVPC作成 - serverless-offline #ローカルでの開発・テスト - serverless-layers #Lambda Layersを利用するためのプラグイン client/serverless.yml抜粋 plugins: - serverless-s3-sync #ビルドしたフロントエンドのS3アップロード - serverless-cloudfront-invalidate #CloudFrontのキャッシュ削除自動化 ※2 DynamoDBレコードの構成は以下の通り。 userId:ユーザID lastSubscribe:RSSフィードの最終配信日時 subscribeFeeds:購読するRSSフィード情報(ここではPublicKeyとDevelopersIOの2つ) name:ユーザ名 DynamoDBのレコード { "userId": "U0000000000000000000000000000000", "lastSubscribe": "2021-11-25T01:00:19.091Z", "subscribeFeeds": [ { "feedUrl": "https://www.publickey1.jp/atom.xml", "addedAt": "2021-11-22T12:23:51.240Z", "siteUrl": "https://www.publickey1.jp/", "lastModifiedAt": "2021-11-21T23:23:51.240Z", "lastAction": "added", "feedId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "title": "Publickey", "enabled": true }, { "feedUrl": "https://dev.classmethod.jp/feed/", "addedAt": "2021-11-22T05:24:35.168Z", "siteUrl": "https://dev.classmethod.jp", "lastModifiedAt": "2021-11-21T23:24:35.168Z", "lastAction": "added", "feedId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "title": "DevelopersIO", "enabled": true } ], "name": "XXX" } ハマったところ Missing Authentication Tokenエラー 開発中、sls offline startでローカル開発環境では問題なくバックエンドAPIが動作するのに、AWSにデプロイするとMissing Authentication Tokenエラーが返されるようになった。 特に認証トークンを求めるような仕様にはしてないはず・・・ということで調べてみると、公式回答曰く認証トークンがない時だけでなく存在しないリソースやメソッドにリクエストを投げた時もこのレスポンスになるとのこと。(だったら、いかにも認証トークンエラーっぽい文言にしないでほしいですが・・・) ただ、メソッドやリソースが存在しないといってもローカル開発環境では問題なく動作するし・・・と色々調べたところ、実は当時serverless.ymlに設定していた下記が誤っていることが判明。 functions: webhook: handler: functions/webhook.handler events: - http: method: ANY path: /webhook/{proxy+} #<=この部分 この設定を書いたとき、https://xxxxxxx/webhook/xxx-xxx-1234{uuid}のように、パスパラメータ付きでリクエストすることも想定していたのですが、どうも{proxy+}は空白はNGのようでした。ただ、serverless-offlineを使った開発環境では空白でも動作してしまうので、混乱してしまいました・・・。 改めて、下記のようにしたら動作することを確認。 functions: webhook: handler: functions/webhook.handler events: - http: method: ANY path: /webhook/{proxy+} - http: #追加 method: ANY #追加 path: /webhook #追加 その後、アプリ構築を進める中でパスパラメータを使うことがないと分かったので、現在の形で決着。 functions: webhook: handler: functions/webhook.handler events: - http: method: ANY path: "/webhook" https化 LIFFが連携するURL(Endpoint URL)が、httpsサイトでないと設定できないことが途中で判明。 本番環境については、S3にホスティングしているURLを直接指定するのではなく、Cloudfrontを追加でデプロイすることで、CloudfrontのURLはhttps化しているためそちらを指定することで解決した。 開発環境については、yarn startではどうしてもhttp://localhost:3000になってしまうと思っていたが、こちらのサイトを参照し.env.development.localでHTTPS = "true"を定義することで簡単にhttps化できることを知り、それで解決できた。 自分でオレオレ証明書を発行して・・・とそれなりに面倒な手順を踏もうかと思っていたので、助かりました。 outbound80の手動穴あけ RSSフィード配信サイトに情報を取りに行く際、LambdaがインターネットアクセスするためにVPC・NAT Gateway等の定義をする必要があったが、それらを簡単に実施するためにserverless-vpc-pluginを使って開発していた。 その後、Lambda上でテストをする中でRSSフィードをうまく取得できるサイトと、取得できないサイトがあることがわかった。 原因を調べていくとserverless-vpc-pluginで構築した中でLambdaに割り当てられるセキュリティグループは、インターネットへのアウトバウンドアクセスが443(https)しか許可されておらず、"http://~"の配信サイトにアクセスできていないことが判明(特に、画像データだけはhttps→httpにリダイレクトして配信しているようなサイトもあり、なかなか検知しづらかったです・・・)。 serverless.yml上に自分でVPC等のリソースを定義しようかとも考えたが、結局deploy.ps1上でLambda実行用のセキュリティグループにOutbound 80ポートの穴あけを追加で定義することで解決しました。 #deploy.ps1抜粋 $TEMP_SG = aws cloudformation describe-stacks --output text --stack-name feed-notify-dev --query 'Stacks[].Outputs[?OutputKey==`AppSecurityGroupId`].[OutputValue]' aws ec2 authorize-security-group-egress --group-id $TEMP_SG --ip-permissions IpProtocol=tcp, FromPort=80, ToPort=80, IpRanges='[{CidrIp=0.0.0.0/0,Description="HTTP ACCESS for RSS Feed Subscribe"}]' Write-Output "Outbound HTTP Access added to Security Group" TypeError: Cannot read property 'pipe' of undefined 開発している途中で、sls deployするとタイトルの通りのエラーが表示されるようになった。 調査した結果、私の場合はserverless-layersとserverless-s3-syncの両方を同一ディレクトリにインストールしていたことが原因と判明。(もともとserver/serverless.ymlでクライアント側のソースも含めて一括デプロイしていました) serverless-layersはserverディレクトリ、serverless-s3-syncはclientディレクトリにインストールし、それぞれのディレクトリに分割してserverless.ymlを定義たうえでdeploy.ps1を用いて一括実行する形に見直すことで解決した。 yarn build時の環境変数読み込み deploy.ps1でバックエンド側のデプロイとクライアント側のソースビルド・デプロイを一括実行するようスクリプトを組む中で、タイトル部分の挙動が手動実行時と違うことを検知した。 もともとスクリプトを組む前はこちらのサイトを参考にproduction環境での環境変数をenv.productionに定義していたが、スクリプト上で.env.productionファイルを作成&yarn buildを実行するとうまくenv.productionファイルを読み込まないことが判明。 以下のように.env.productionファイルを使わず、直接環境変数に設定することで解決しました。おそらく権限周りの問題なのだと思われるが、よくわからず・・・。 #deploy.ps1抜粋 $env:REACT_APP_API_URL_PROD = aws cloudformation describe-stacks --output text --stack-name feed-notify-dev --query 'Stacks[].Outputs[?OutputKey==`ServiceEndpoint`].[OutputValue]' yarn build Write-Output "Client App Built" 終わりに 今回、初めてServerless Frameworkで本格的にアプリ構築をしてみましたが、いろいろとハマってしまって難しいと感じた面もありつつ、Serverless Frameworkそのものやプラグインがとても便利で、非常に勉強になりつつ楽しかったです。 ReactによるUI構築も勉強になったので、今回の経験を踏まえて、また新しいアプリ構築にチャレンジしてみたいと思います。
- 投稿日:2021-12-05T19:47:56+09:00
【AWS】DynamoDBをコンソール上から使ってみる
はじめに どーも、のぶこふです。 re:Inventも終わり、年の瀬が一層近く感じますね。 まだまだアップデートは把握しきれてませんが、毎年こうして大規模アップデートや新サービスの発表などはワクワクします。 あ、この記事はGFAMアドベントカレンダー2021の5日目の記事です。 今回は、DBサービスの一つである「DynamoDB」に焦点を当てていきます。 ソースコードは触らずに、DynamoDBコンソールからの動作確認のみを行います。 今回のサービス一覧 Service名とか 概要 DynamoDB 12 マネージドなNoSQLDB DynamoDB まずは、簡単に概要を抑えておきます。 完全マネージド型のNoSQLデータベースサービス ハイスケーラブル、低レイテンシー 管理不要、高い信頼性 SPOFが存在しない データは3箇所のAZに保存 ストレージは必要に応じて、自動的にパーティショニングされる プロビジョンドスループット デーブルごとにReadとWriteのスループットキャパシティを割り当てることができる。 例えば・・・ 初期設定:Read:1,000、Write:100 書き込みワークロードが上がった:Read:500、Write:1,000 この値は、DB運用中にオンラインで変更可能 ストレージ容量制限無し 使った分だけの従量課金 ディスクやノードの増設作業は不要 整合性モデル Write 少なくとも2つのAZで書き込み完了確認がとれた時点 Read デフォルト 「結果整合性」のある読み込み 最新の書き込み結果が、即時読み取り処理に反映されない可能性がある Consistent Read Option GetItem、Query、Scanでは「強力な整合性」のある読み込みオプションが指定可能 Readリクエストを受け取る前までのWriteが全て反映されたレスポンスを保証 Capacity Unitを2倍消費 Capacity Unit? ユニットと呼ばれる単位 それぞれ25ユニットまで無料 Write 最大1KBのデータを1秒に1回書き込み可能 Read 最大4KBのデータを1秒に1回読み取り可能 強い一貫性を持たないのであれば、1秒に2回読み取り可能 ユースケース KVS ユーザ情報の格納 広告やゲーム等のユーザ行動履歴DB ユーザIDごとに複数の行動履歴を監理 モバイルアプリのバックエンド モバイルアプリから直接参照 その他 バッチ処理のロック監理 フラッシュマーケティング ストレージのインデックス DynamoDBの構成 HTTPベースのAPIが提供されている テーブル設計 テーブル操作(一部 名称 操作 GetItem Partation Keyを条件として指定し、1件のアイテムを取得 PutItem 1件のアイテムを書き込む Update 1件のアイテムを更新 Delete 1件のアイテムを削除 Query Partation KeyとSort Keyの複合条件にマッチするアイテム群を取得※ BatchGet 複数のPRIMARY KEYを指定してマッチするアイテム群を取得 Scan テーブルを総なめ※ ※最大1MBのデータを取得可能 使い方 テーブルの作成 DynamoDBコンソールを開く リージョンを確認しておく テーブルの作成を選択する 「テーブルの作成」を選択する 作成まで、しばし待つ(1分くらい) 項目名 設定値 テーブル名 User パーティションキー UserId:文字列 ソートキー 無し 設定 デフォルト設定 デフォルト設定 特になし タグ Key:Name、Value:Test アイテムの作成 ※SDKを介して作成したり、追加したりのほうが汎用的だと思いますが、まずはマネコンから・・・ 作成したテーブル詳細を開く アクション > Create Item を選択する フォーム、またはJSONで情報を入力して、「項目の作成」を選択する // JSONの例 { "UserId": "0001", "Name": "Nobkovskii" } アイテムの検索 「項目」から、対象のテーブルを選択する 検索条件を入力して、「実行する」を選択する 対象が存在する例 対象が存在しない例 テーブルの削除 対象のテーブルを選択して、「削除」を選択する 「削除」と入力して、「テーブルの削除」を選択する DynamoDB Accelerator(DAX) リアルタイム処理や一時的なアクセス集中への対応など、読み取りが多い場合に爆速になってくれるやつ。 逆に、書き込みが多い・読み取りが少ない場合は、効果は今ひとつ。 フルマネージド型高可用性インメモリキャッシュ3 DynamoDBに特化 DynamoDB APIと互換性があり、アプリケーションのロジックを変更する必要は無し。 ミリセカンド→マイクロセカンドへの、最大10倍のパフォーマンス向上を実現する! キャッシュがあれば使う、なければオリジンから取得してキャッシュする マネジメントコンソールやSDKから簡単に使える VPC環境で動作 おわりに 今回は、DynamoDBの概要調査と、コンソール上から簡単に触ってみました。 本来はSDKを介して、アイテムのCRUD(追加・検索・更新・削除)をしていくのが筋だと思いますが、概要を掴むということで、コンソール上からの操作までとしました。 テーブルの作成や項目追加も、サクッとできて、良い感じでした。 今回の内容だけでは「DynamoDBの良さ」は、全然理解に至らないので、アプリなどに組み込ませて使ってみたいです。 今回はここまでです。 ありがとうございました。 DynamoDB概要 ↩ DynamoDB-BlackBelt ↩ DAX概要 ↩
- 投稿日:2021-12-05T19:45:42+09:00
DataSyncを利用したEFSからS3のデータ転送時の注意点
この記事は何か DataSyncを利用して、EFSとS3のデータ転送を行う際に、つまづきポイントがあったので、簡単にまとめる。 今回DataSyncは初利用だったので、見事にハマったなーという思いと、公式ドキュメントに明記されていなかった部分なので、もしも同じ部分でつまづいた人がいたら、参考になれば嬉しい。 DataSyncとは AWSが提供するオンラインデータ転送のサービス。 昨年からAWSのストレージサービス間ならエージェント不要でデータ転送が可能となった。めでたい。 つまり、EC2やECSなどのリソースは不要で、マネージドサービスだけでデータの転送が可能 何をしようとしたか EFSのデータを定期的にS3転送する 極力マネージドサービスで完結したかったので、DataSync TaskでEFSのデータをS3に定期的に転送しようとした → EFSの設定状況 VPC内に配置されている File System Policyが設定され許可したIAMRoleしかMountやWriteができないように制御している ECSで稼働中のサービスからマウントされている 進め方 初のDataSyncの利用だったので、素直に公式ドキュメントをみてリソースの作成と設定を試みた。 参考にしたドキュメント https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_DataSync.html https://docs.aws.amazon.com/datasync/latest/userguide/create-efs-location.html https://docs.aws.amazon.com/datasync/latest/userguide/create-s3-location.html リソース作成、実行、そして失敗 EFSからS3へのデータ同期となるので、SourceLocationとしてEFS、DestinationLocationとしてS3のlocationをそれぞれ作成し、後はDataSyncのTaskを作成すれば良いと理解。 IAMRoleやSecurityGrouoなどはつまづきがちな部分は公式でもきっちりフォローされているので大きなトラブルはなさそうと思い、作業をスタート。なお、リソースの作成はCloudFormationで行った。 Source Location(EFS)の作成 DataSyncLocationEFS: Type: AWS::DataSync::LocationEFS Properties: Ec2Config: SecurityGroupArns: - !Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/${EC2SecurityGroupDataSyncEFS}' SubnetArn: !Sub - 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:subnet/${SubnetId}' - SubnetId: ${SubnetId} EfsFilesystemArn: !GetAtt EFSFileSystemSessions.Arn Subdirectory: '/dirctory' Destination Location(S3)の作成 DataSyncLocationS3: Type: AWS::DataSync::LocationS3 Properties: S3BucketArn: !GetAtt S3BucketImageData.Arn S3Config: BucketAccessRoleArn: !GetAtt IAMRoleDataSyncLocationS3.Arn S3StorageClass: STANDARD DataSync Taskの作成 DataSyncEFStoS3: Type: AWS::DataSync::Task Properties: DestinationLocationArn: !GetAtt DataSyncLocationS3.LocationArn Name: !Sub 'EFStoS3' Schedule: ScheduleExpression: "cron(55 * * * ? *)" SourceLocationArn: !GetAtt DataSyncLocationEFS.LocationArn IAM Roleの作成 IAMRoleDataSyncLocationS3: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Statement: - Effect: 'Allow' Principal: Service: 'datasync.amazonaws.com' Action: 'sts:AssumeRole' Policies: - PolicyDocument: Statement: - Effect: 'Allow' Action: - 's3:GetBucketLocation' - 's3:ListBucket' - 's3:ListBucketMultipartUploads' Resource: - !GetAtt S3BucketImageData.Arn - Effect: 'Allow' Action: - 's3:AbortMultipartUpload' - 's3:DeleteObject' - 's3:GetObject' - 's3:ListMultipartUploadParts' - 's3:GetObjectTagging' - 's3:PutObjectTagging' - 's3:PutObject' Resource: !Sub '${S3BucketImageData.Arn}/*' PolicyName: 'datasync-location-s3' Security GroupでDataSyncタスクのSubnetからEFSに対して2049のポートアクセスを許可 EFS側のFile System Policyに今回作成したDataSync TaskのIAMRoleを追加 ここまででリソース作成が完了した形....が、いざタスクを実行すると失敗 具体的にはDataSyncのタスクで以下のエラーが発生した。 Task failed to access location loc-XXXXXXXXXXX: x40016: mount.nfs: Connection timed out 原因調査 エラーメッセージを見るとコネクションタイムアウトとあるので、ネットワーク的な部分で遮断されているように見える。 エラーメッセージが表示されるケースも調べたが、やはり所属するSubnetかSecurity Groupの設定ミスが原因とあり、ネットワーク周りの設定ミスが原因に見えた。 ネットワーク的な問題と思いSubnetの指定ミスやSecurity Groupの設定ミスを疑い確認したが、少なくとも設定ミスはなさそう 問題の切り分けのためにSecurity Groupの制限を緩めたりしてみたけれど、エラーは変わらず ネットワークの制限を緩めてもエラーが変わらなかったので、おそらくネットワークではないどこかでつまづいていると思い、サポートに問い合わせを投げた 失敗の原因 サポートからの返答を抜粋。 DataSync のタスクが EFS をマウントする際に Connection timed out にてエラーが発生する事象について調査のご報告をいたします。 お客様の設定状況を拝見いたしましたところ、DataSync ロケーションの設定や、EFS マウントターゲットのセキュリティグループやサブネット等の設定に問題は見受けられませんでした。 一方で、調査の結果、当該 EFS に設定されたファイルシステムポリシーが原因となり、当該エラーが発生している可能性が考えられました。 DataSync では、大変恐縮ではございますが、現時点において EFS のアクセスポリシーでの制限をサポートいたしておりません。 また、こちらの制約に関して現在有効なワークアラウンドはなく、EFS のファイルシステムポリシーを削除いただく、あるいは、DataSync を利用せずにコマンドラインツール等にて EFS からデータを転送いただくことが代替案となります。 つまり、 EFSのファイルシステムポリシーを利用しているとDataSyncが使えない という結論。完全に盲点だった。 検証のため、ファイルシステムポリシーを削除したところ、問題なくDataSyncのTaskが成功したので、まさにこのサポートの回答通りの挙動だった。 代替案 DataSyncを利用した代替案はないので(File System Policyを削除すればできるけれど、それを削除するわけにはいかなかったので)、LambdaでEFSからS3にデータ転送を行うスクリプトを書いて定期的に実行することにした。 今回、この同期のスクリプトは本筋ではないので割愛。 まとめ DataSyncを利用したEFSからのデータ転送やEFSへのデータ転送を行う際、File System Policyを利用している場合は現時点だとできないので、気をつけよう! 反面、今回のようにFile System Policyが利用されているEFSでなければ、S3への定期的なデータ転送が自前のスクリプトなしでできたので、DataSyncがNoOps的な側面で嬉しい機能であることに間違いないなと思えた。
- 投稿日:2021-12-05T17:58:28+09:00
re:invent 2021機械学習系アップデートの中から個人的に気になったものを紹介してみた
今年のre:inventの機械学習系サービスで、いくつか気になるアップデートがあったので、ご紹介していきたいと思います。 SageMaker Studio Lab Google Colabに似た、無料で使えるクラウドのJupyter notebookが登場しました。 Colabは使わないとすぐカーネルがリセットされてしまう感じがあって、そこがすごく使いにくかった。感覚的にはコーヒーを作る5分ほどの休憩でカーネルがリセットしてしまって、泣く泣く最初からセルを動かさないといけないようなことがありましたが、この新しいサービスは使ってみたところかなり安定していて好印象です。 中身はほぼSageMaker Studioで、使用感は悪くないです。 ↓UIはこんな感じ Sage Makerという名前がついていますが、AWSとの連携はゼロです。SageMaker内のJupyter notebookだとデフォルトでboto3やSageMaker SDK、あるいはTensorFlowなどが使えますが、こちらはそういうカーネルの選択肢がないです。 使い方は、まずCPUセッションかGPUセッションを選びます。CPUなら12時間、GPUなら4時間の制限時間があります。いずれにせよ制限時間が終わったらまたセッションを始めればいいのでほぼ無制限に使えると言って良いでしょう。 ↓セッションの残り時間を確認する画面 ただ使うには登録が必要で、以下のURLから申請すると承認のリストに追加され、承認されると登録用のメールが届きます。自分は申請から1日ほどで承認メールが来ました。 https://studiolab.sagemaker.aws/ まとめ Google Colabに負けじとAWSもクラウドの無料のJupyterノートサービスを出してきた。Colabみたいにセッションが勝手に中断されないのが嬉しい。AWS用のカーネル、TensorFlow用のカーネルも用意してくれているともっとよかった。使うには登録が必要なので急いで登録しよう!(登録はこちら) Serverless Inference 今まではAWS上でモデルをデプロイしてHTTPリクエストで推論可能にすると、推論用のEC2インスタンスの料金がかかっていました。しかも推論用のインスタンスは最低でも1時間30円くらいなので、消し忘れて数日経つと数千円かかってしまって結構辛かった。それがこのアップデートでかなり気楽に、言わばLambda感覚でMLモデルをデプロイできるようになりました。 サーバーレスなので、コールドスタート問題(ずっと使ってないとコンテナがkillされて、久々の起動に数十秒かかってしまう問題)はありますが、これはLambdaと同じく「温め機能」のオプションもあるようです(追加料金は必要)。 なんにせよサーバーレスの流れはもっとどんどん推し進めてもらいたいですね。 まとめ AWS上でのMLモデルのデプロイがサーバーレス化。これでAWSにモデルをデプロイするときの推論コストが圧倒的に安くなるはず。 Ground Truth Plus SageMaker Ground Truthは画像やテキストデータのラベリングを支援するサービスでしたが、今回これに機能追加がありました。 と言っても大したアップデートではありません。というのも、このサービスは医療用のデータなどラベル付けに専門性が要求される場合に、シアトルにいるAWSのコンサルタントが電話で相談に乗ってくれるサービスだからです。 流れとしては、電話で相談→適切な人員をアサインという流れですが、当然当分は英語のみなので、ほとんどの方には関係のないアップデートでした。 個人的にはもっとこっちを改善して欲しかった… 個人的にはそれよりGround Truth自体の機能のアップデートを期待していました。具体的には、 ・学習プロセスに抽象化したAPIを提供して欲しい オブジェクトひとつにつき8円に見合う、Ground Truthでラベリングをした際のメリットが欲しいです。例えばモデル学習時に、 estimator.fit(..., label_config=GroundTruthConfig(s3_location="s3://..."), ...) と指定しただけで学習ができたりとか。 ・全体的な細かいところの改善 初心者殺しの理解しにくく、落とし穴が多いUI。適切なエラーメッセージが出ない等の細かいところの改善が望まれます ・ドキュメントの充実 EM法を使った統合ラベルを使うときのワークフローや、自動ラベリング時のワークフローはどうなるの?というのがわかると嬉しい…。 ・デフォルトで使えるアノテーション用のモデルの充実 例えばCVATのようにデフォルトで人や車をラベリングしてくれるサービスがあってもいいと思います。異常検知用の自動ラベリング等もあると嬉しい。 です。これらに関しては今後のアップデートに期待しましょう。 まとめ Ground Truth Plusが発表された。Plusもいいけど本体の機能の充実を望む! その他のアップデート 以下は個人的にはあまりピンと来なかったアップデートです。それぞれ2行程度で簡単にご紹介します。 SageMaker Canvas データサイエンスの現場でよく聞くDataRobotに似た、GUIでできるデータサイエンスサービスです。もともとデータサイエンス系のMLに力を入れてきたAWSなのでなるほどというアップデートでした。 新しい機械学習用インスタンスTrainiumの発表 800Gbpsという高いI/O性能や、GPUよりさらに効率が良いASICを搭載したチップを搭載したり、通常のインスタンスよりMLに最適化されたインスタンスが登場しました。昨年のInferentiaに続くML用インスタンスとしては2つ目ですが、Inferentiaを使う場合と同様、コードをNeuron SDKという専用のSDKでコンパイルしてやる必要があります。Inferentiaが推論用、今回のTrainiumが学習用のインスタンスなのでしょう。機械学習の運用コストを下げたい場合に使うことになるかもしれませんね。 最後に ML関係だけでもたくさんのアップデートがあって、その中でも一部気になったものだけご紹介しました。最後にAWS re:postという機械学習とは関係ないサービスが登場したので紹介して終わりとします。(URLはこちら) 掲示板サービスre:post 今までAWSに関係する掲示板的な役割はGit HubのissueかAWS公式のフォーラムくらいしか実質なかったですが、この公式のフォーラムがくせ者で、Greengrass以外はAWSからの回答がほぼゼロ、という状態でした。しかもUIが20年くらい前の古いUIでAWSを使う際の小さなストレスのひとつでした。例えばSageMakerみたいな決してドキュメントが優れているとは言えないサービスでハマっている人の死屍累々を見るのはあまり気持ちの良いものではありません。しかもAWSコンソールから飛べないのでそもそもフォーラムの存在自体知らない人も多かったはずです。 それが今回コンソールから行けるようになり、UIもモダンになりました(下図参照)。専用のアカウントが必要なのが微妙ですが、これを機にAWSからの回答が増えるのではないかと少しだけ期待しています。 記事は以上になります。それではクラウド技術の発展には時間がかかることを念頭に置いてまた来年のアップデートを待つことにしましょう。ありがとうございました。
- 投稿日:2021-12-05T17:51:26+09:00
Amplify Studioは使いやすいのか
POLアドベントカレンダー2021 6日目、ゲバラです。 先日発表されたAmplify Studioを触ってみます。 5日目のまーさんの記事はこちら Amplify Studioとは Amplify Studioとは、Webアプリのフロントエンドを高速に開発できるツールです。これは昨年すでにリリースされているAmplify Admin UIに統合されており、フロントエンドとバックエンドどちらも運用管理行えるなかなかスーパーなツールに進化しました。 2021/12/06現在 まだパブリックプレビュー中なので本番環境では使わないようにしてください。 特徴1:Figma連携によるコンポーネントエクスポート機能 プロトタイプデザインツールFigmaとの連携することができ、デザインしたUIをReactのコードとしてコンポーネント出力することできます。 特徴2:コンポーネントとデータのバインド機能 出力したコンポーネントとモデリングしてあるデータを管理画面上からバインドすることができます。 レッツチャレンジ 基本ここをなぞってます 名前を入れてConfirm deplayment。すでに作成しているアプリケーションでも開始できます。 セッティング中・・・。 5分ほどで完了。すでにstagingのバックエンド環境ができていますね。 「Studioを起動する」から始めましょう。 左上のAmplify Studioにワクワクする。 UI Libraryを使ってFigma連携してみる 左のUILibararyからGet statredしましょう ①にあるリンクはAmplify側で用意してあるサンプルなのでこれを使う必要はありませんが、当方はあまりFigmaを使いこなせていないので、サンプルをコピーして②に共有用のURLを貼り付けます。権限の許可を求められるので許可します(ここはスクショ撮り損ねました) Figma上でデザインしたコンポーネントを一つ一つ取り込むか選択していきます。Accept Allで一気に取り込んでもOK。 取り込み完了するとコンポーネントが一覧で見れるようになりました。便利。 Configureからコンポーネントのプロパティを設定したり、実際のコードを取得することができます。 UIとデータをバインドしてみる UIとデータをバインドしてみたいのであらかじめデータのモデルを作っておきます。 バインドする設定はコンポーネントのConfigureから行います。 Component propertiesのTypeとして先ほど作成したデータモデルを選択します。 Typeを設定した後、左にある項目からバインドしたいものを選択し、Child propertiesを設定してきます。Propには基本labelを選択します。Valueはデータモデルの項目を選択することができます。 これを選択することでバインド設定完了です。Valueのカスタマイズのすることができ文字列の 便利だと思ったのが左の3点リーダからConcatenateでValueの結合をしたり、Add conditionalを選択すると条件指定することで項目の出し分けをすることができるようです。思ったよりカスタマイズ性があって使えそうです。 実際にデータが入っていなくても上部にあるShuffle preview dataをクリックすると、適当なデータが表示され、デザインを確認することができます。英語だけですが。 感想 不具合あって使い物にならないかなと思っていましたが、意外と便利で使えそうな印象でした。使いこなすにはFigmaをマスターしていないと難しそうですが。こうしてコードを書く量が減り、作りたいプロダクトに集中できるのは嬉しいですね。今年はFigmaからコード生成するツールが増えたので来年はFigmaをマスターしなければいけない年になりそうです。 明日 明日7日目は10月に入社されてバリバリ活躍中のアビスさんです!
- 投稿日:2021-12-05T17:47:52+09:00
(EC2) pushしてもlocalのcredencials.yml.encが反映されない
問題 AWSにデプロイする中でEC2のcredentialsにlocalのDB内容を反映させようとしたが、pullしても反映されない 原因 ローカルでcredentialsを編集してpushした後に、EC2内で git pull origin main を実行するとconflictが起きていたので、解決するためにEC2からgithubにpushしてpullしたのがよくなかった。(EC2からpushせずにcommitは削除するべきだった) 解決方法 githubですでにpushしてしまったEC2からのcommitを git reset --hard HEAD^ で遡り、 git push origin +main でEC2のcommitを消して、消したcommit上にあったlocalからのcommitを復活させるためにlocalのアプリケーションディレクトリで再度push。そして git pull origin main を実行するとcredentialsにはローカルと同じ内容が反映されている。
- 投稿日:2021-12-05T16:57:33+09:00
CloudShellとAWSCLIを利用してAmazon Lightsail のDrupalサーバを最速で立てる
Drupal Advent Calendar 2021 21日目の記事になります。 AWSにはAWS Lightsailという月額$3.5~から利用可能なVPSサービスがあります。今回は Amazon Lightsail でDrupal インスタンスを起動する の「Amazon Lightsail で Drupal インスタンスを作成する」+静的IP追加までをCloudShell+AWSCLIを利用して最速で立ててみます。 ■ 免責事項 本手順は完全性、正確性、有用性、安全性などを保証するものではありません。 本手順に基づき実施した判断および起こした行動によりいかなる問題が発生しても一切責任をおいません。 本手順を利用の際は全て自己責任にてお願いします。 ■ 前提条件 AWSアカウント開設済み ■Lightsailの仕様 インスタンスの AWS リージョンとアベイラビリティーゾーン:Tokyo, Zone A (ap-northeast-1a) プラットフォーム:Linux ブループリント:Drupal インスタンスプラン:nano インスタンス名:drupal-demo-01 静的IP名:StaticIP-drupal-demo-01 ■ 構築手順 (1) AWSマネジメントコンソール へのログイン 今回はRootアカウントでログインします。 (2) 東京リージョンを選択後、CloudShellのアイコンをクリックしてCloudShellを起動 該当リーションを「東京」へ変更後、[>?] の形のアイコンをクリックしてCloudShellを起動します。 東京リージョン選択後、CloudShellアイコンクリック(赤枠) CloudShell起動 (3) aws lightsail create-instancesコマンドを実行してLightsailインスタンスを起動 CloudShell上で以下のコマンドを貼り付けます 実行コマンド aws lightsail create-instances --region ap-northeast1 --instance-names drupal-demo-01 --availability-zone ap-northeast-1a --blueprint-id drupal --bundle-id nano_2_0 コマンド実行後、以下のような出力結果となっていることを確認します。 (4) aws lightsail allocate-static-ipコマンドを実行して静的IPを割り当て。 CloudShell上で以下のコマンドを貼り付けます 実行コマンド aws lightsail allocate-static-ip --static-ip-name StaticIP-drupal-demo-01 --region ap-northeast-1 コマンド実行後、以下のような出力結果となっていることを確認します。 (5) awsaws lightsail attach-static-ipコマンドを実行してLightsail インスタンスに静的 IP アドレスをアタッチ CloudShell上で以下のコマンドを貼り付けます 実行コマンド aws lightsail attach-static-ip --static-ip-name StaticIP-drupal-demo-01 --instance-name drupal-demo-01 --region ap-northeast-1 コマンド実行後、以下のような出力結果となっていることを確認します。 (6) awsaws lightsail get-instances コマンドを実行して、静的IPが Lightsailインスタンスに正しく関連付けられているかどうかを確認 CloudShell上で以下のコマンドを貼り付けます 実行コマンド aws lightsail get-instances --region ap-northeast-1 --query 'instances[].{name:name,createdAt:createdAt,blueprintId:blueprintId,blueprintName:blueprintName,publicIpAddress:publicIpAddress,InstanceID:supportCode}' --output table コマンド実行後、以下のような出力結果となっていることを確認の上、drupal-demo-01 の【publicIPAddress】の値を控えます。 (7) Lightsail ホームページよりLightsail確認 AWSマネジメントコンソールよりLightsail ホームページにアクセスしてdrupal-demo-01インスタンスが存在することを確認します。 (8) Lightsail ホームページよりDrupal確認 ブラウザ上よりhttp://[publicIPaddressの値]でアクセスしてDrupalの画面が表示されているか確認します。 Drupalのログインパスワードは Amazon Lightsail でDrupal インスタンスを起動する の「3.SSH 経由でインスタンスに接続し、Drupal ウェブサイトのパスワードを取得します」の手順で取得してください。
- 投稿日:2021-12-05T16:21:35+09:00
前編:EC2にFabric1.xでデプロイされていたPlayFrameworkのプロジェクトをGitHub Actions+CodeDeployでのデプロイに変えてみた話
この記事は株式会社サイバー・バズ Advent calendar 2021の記事です。 前置き 当社では、現在ほとんどのサービスがAWSのECSで運用されています。 一方で、長いこと(7年近く)使われているPlayFramework2.3系の社内サービスがあり、それは未だに単体のEC2で運用されていました。 そのデプロイ方法がローカル環境からFabricのバージョン1系を利用する前提となっており それぞれの人の環境によってFabricが実行できたりできなかったりする 本番サーバー(EC2)にアクセス可能なSSH秘密鍵がデプロイに必要 という状況があったために、この社内サービスの変更が反映できる人は社内の一部の人だけでした。 今回はせめて環境に依らず、新人含め誰でもデプロイできるように、という目的のもと変更を行うことにしました。 前編では、ビルドした中間生成物をS3にストアするまでを解説し、 後編は「後編:EC2にFabric1.xでデプロイされていたPlayFrameworkのプロジェクトをGitHub Actions+CodeDeployでのデプロイに変えてみた話」で解説します。 変更点 変更に際して Gitが使える人なら環境に依らずデプロイができること デプロイに必要な認証情報はIAMだけにとどめたいこと (SSHキー、ID・パスワード等を用いたくない) を満たすことに焦点を当て、以下のような変更を行うことにしました。 図 従来 変更後 この変更により、 変更後はGitHub上でmasterブランチに変更が加わる=デプロイできる という状況が作れます。 行った作業 中間生成物用のS3バケットの作成 GitHub Actionsのworkflow作成 必要なIAMの作成 CodeDeploy用のappspec.ymlと各スクリプトの作成 CodeDeployのセットアップ 基本的にはこれだけですが、今回は2までを解説します。 中間生成物用のS3バケットの作成 S3バケットを作成します。 S3バケット名はもちろんユニークなものでなければなりませんが、 必要な追加設定はバージョニングの有効化のみです。 バケットの作成後、プロパティタブから変更可能です。 GitHub Actionsのworkflow作成 以下のようなファイルを追加しました。 一部Node.jsによる事前ビルドが必要なコードが含まれるので、npm installおよびnpm run buildを実行 PlayFramework2.3系のため、ビルドは ./activator clean stage ビルド後は必要ファイルをzipに固め、先ほど作成したS3にアップロード github/workflows/build.yml name: Build on: push: branches: [ master ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up JDK 8 uses: actions/setup-java@v2 with: java-version: '8' distribution: 'adopt' - name: Setup Node.js environment uses: actions/setup-node@v2.5.0 - run: npm install - run: npm run build - run: ./activator clean stage - run: zip -r xxxxxx.zip . -i "appspec.yml" "target/*" "scripts/"* - name: Deploy to S3 env: AWS_DEFAULT_REGION: ap-northeast-1 AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: aws s3 cp xxxxxx.zip s3://cyberbuzz-codedeploy-artifacts/ AWSの認証情報であるAWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYは、直に記載するべきではなく、上記の例のようにActions Secretとして作成しておき、そこから参照する方法が好ましいです。Actions Secretは、 https://github.com/org-name/repo-name/settings/secrets/actions から設定可能です。 (org-nameとrepo-nameはそれぞれに置き換える必要があります。) ここで使うAWSの認証情報は、GitHub Actions用にIAMを作って利用しています。 アクセスの種類はプログラムからのアクセスに限定しつつ、S3にアップロードすることができる最低限の権限をつけておくのがおすすめです。 アップロードの確認 アップロード先に設定していたS3バケットを確認し、 想定していた成果物がアップロード完了していたら最初の段階は終了です。 おわりに S3へのアップロードまでは非常に簡単ですね! 後編では、このS3にアップロードされたzipファイルを使い、AWSのCodeDeployを使ったEC2へのデプロイを解説していきます。
- 投稿日:2021-12-05T15:46:35+09:00
ハンズラボで過ごした1年間を振り返る
ご挨拶 この記事は ハンズラボ AdventCalendar2021 5日目の記事です。 今月で入社1年経った中川です! 昨年もAdventCalendarに参加させてもらいましたが、あれから早1年 今回の記事ではハンズラボでの1年間を振り返りたいと思います。 振り返り そもそも1年前の面接でAWS認定色々取りたいです!勉強会したいです!! と言って面接をパスした手前、AWS認定取得と外部の勉強会参加を念頭に頑張ってきました。 結果としては * 入社1年でAWS認定を5つ取得 → ハンズラボ内部でのAWS認定最多資格保持者になった * 外部勉強会で登壇 → 2回登壇 * 自身で主催の社内勉強会開催 でしたので、個人的には割と頑張ったかなと思っております。 因みに9月〜12月まで資格を取れてないのは ハンズメッセ チーム移動 引っ越し の3つが重なり中々落ち着けなかったのが原因です... 業務的な話はあんまり書けないのでアレですが、 東急ハンズファンとしてハンズネットのアーキテクチャ関連に携われたのですごく楽しかったです! AWS認定を色々取ってみて AWS認定を取ってた上での業務上のメリットかなと思った点は AWSの知識の引き出しが増えた 色々なアーキテクチャパターンを覚えられた 多少なりとも自信がついた(AWSナニモワカナラナイ) 辺りかなと思います。 特にサービスとサービスの組み合わせやセキュリティを重視したアーキテクチャ、 AWSの使い方・考え方は仕事でめっちゃ役に立ってます! ただ、同時に資格は持ってるけど経験値が浅い分野も数多くあるので、 知識として知ってはいるけど構築できるか怪しいと思う所もあるので、 これからも天狗にならずに精進が必要とつくづく感じました... AWS認定は取ったらゴールじゃない!取ってからがスタート!! ※一応年内にもう後1~2資格位取りたいとはおもってます 来年の目標 AWS認定11冠を目指す 内部,外部での勉強会の登壇 ラボブログの記事を書きたい ひとまずはAWS認定を制覇した上でLPICやCCNA・CCNPなどメジャーな物は取りたいとも考えております。 継続的なアウトプットが大事なので1ヶ月に1記事位は最低でも書きたいんですがネタが中々... 検証してみた系の記事とかも色々書きたいなとは考えております! 最後に 本当にあっという間の1年間でしたが1年で色々と成長を実感できたので凄く濃くて良い1年間だったと思います! それもこれも社内の皆様や、勉強会で知り合った方々など多くの人の影響があってこそでした!! 今年も残り少ないですが、来年含めて引き続きよろしくお願い致します!! 取得したAWS認定まとめ 2021/01/29 AWS Certified Security Specialty 2021/03/05 AWS Certified SysOps Administrator Associate 2021/04/16 AWS Certified Developer Associate 2021/07/24 AWS Certified DevOps Engineer Professional 2021/08/21 AWS Certified Solutions Architect Professional
- 投稿日:2021-12-05T14:17:23+09:00
AWS Control Towerを実際に使ってみた感想とメリット&注意事項
はじめに 以前AWSでマルチアカウント環境を実装してみたという記事を書いており、この時には「自力で頑張ってAWSの色々なサービスを組み合わせてマルチアカウント環境を作成する」のを前提としていました。 それから間もなく、マルチアカウント環境を全部まるっとカバーしてくれるControl Towerというサービスが東京リージョンに対応しまして、業務で使う機会にも恵まれたのでその感想を共有したいと思います。 Control Towerの構築方法は他の方のブログや記事がたくさんありますので、ここでは業務を通して見えてきたControl Towerのメリットや注意事項などを自分なりに上げ連ねてみます。 ひとことで言うと Control Tower、最高です。自力で構築するとCloudFormationのテンプレート作ったりスタックセットで展開したりAWS Configルールの定義をたくさん作ったり、、、と果てしなく大変&運用も非常に煩雑になるのですが、このサービスを使えばほんとにマウスクリックだけで環境が作れてしまいます。 とはいえ扱いに少々癖があり慣れが必要なのと、Control Towerでカバーされていないリージョンや機能があるので一長一短ではありますが、自分で時間をかけて作るよりはこういったサービスを使う方がストレスも少ないですし、他の事に割ける時間も増えるので個人的には良いのではないかと考えています。 そもそもControl Tower&マルチアカウント環境って何よ?って方はこちらのリンクを参照ください。必要な情報がいい感じに纏められてますので。 メリット 色々あるとは思いますが、ぱっと思いつくところはこんなところです。 環境設定が全て自動で行われる AWS Config、Cloud Trailの設定、ログアーカイブアカウントへのログ集約、監査用アカウント作成等々、マルチアカウント環境に必要な設定が全自動で行われます。自分でやることは何もありません。マウスポチポチのみ。 さらにAccount Factoryという機能を使えば、新規のAWSアカウントを追加する際にも上記色々めんどくさい設定を全部勝手にやってくれた上で払い出してくれます。ステキ。 AWS SSOがついてくる 使ったことがない人にとっては若干敷居が高い(と思われる)AWS SSOですが、Contorl Towerを使えばこれも自動的に構築して提供してくれます。まあこの辺は「いらねえよ」という人もいるかもですが、いざ使ってみるとこれも相当にステキなサービスです。 マルチアカウント環境だと大きなところでは数十~数百のAWSアカウントを管理するケースも出てくると思いまが、AWS SSOを使わずにこういう大規模な環境を維持していくのは相当きついと思われます。 AWS SSOを使えば権限設定を一カ所に集約できますし、Organizations内の他のアカウントにスイッチするのも非常に楽に行えますので、特に中央管理者(マスターアカウントを管理し、メンバーアカウントに統制を効かせる側の人々)にとってメリットが大きいと思います。 規模やユースケースによるとは思いますが、個人的には中央管理者はAWS SSOを使い、メンバアカウント利用者にはIAMユーザを配る(各々勝手にやってもらう)くらいがちょうどいい使い方なのではないかな、と今のところは考えています。必要なガバナンスはガードレールやSecurity Hub、GuardDutyで効かせる感じで。 Control Towerダッシュボードが付いてくる マルチアカウント環境の中身をまるっと可視化できるダッシュボードが付いてきます。 このダッシュボードの中でメンバーアカウント一覧、OU一覧、適用済みのガードレール一覧、ガードレールの準拠状況、、、等々を確認することができます。色んな画面を飛ぶ必要がないので地味に便利です。 デメリット(というか注意点) デメリットというよりは、Control Towerを使うにあたっての注意点を以下列挙していきます。まあまあ癖があるので、この辺りの注意点が受け入れられなければ独自構築を選択した方がよいかもしれません。 GuardDutyやSecurity Hubには対応していない Control Towerを使ったとしても、上記サービスは自動で展開してくれません。なので使いたい場合は自分で手動設定する必要があります。全リージョンに展開する場合はまあまあ手間です。とはいえこちらは独自構築するとしても同じ話なので、そんなデメリットになる話でもないですが。 Control Tower自体がSecuryt Hubのセキュリティ基準に引っかかる これにはまあまあ苦労させられました。Security Hubにはセキュリティ基準という機能があり、AWSの推奨ルールから逸脱するサービスがないか常時チェックしてくれます。で、問題が見つかったらアラートでお知らせしてくれるのですが、これにControl Towerで自動作成されたサービス(Lambda、SNS等々)が引っかかったりするのです。 私の場合は1つずつアラートをチェックしてポチポチ修正していったのですが、結構根気のいる作業でした。スクリプト等を作って修正作業を自動化するなど、工夫が必要な個所かと思います。あと私はSecurity Hubの「AWS 基礎セキュリティのベストプラクティス v1.0.0」をよく使うのですが、Contorl Tower環境下では以下の定義は無効化しても良いのでは、と思っています。 SNS.1:SNS topics should be encrypted at-rest using AWS KMS(SNSトピックは、AWS KMSを使用して保存時に暗号化する必要があります) EC2.10:Amazon EC2 should be configured to use VPC endpoints(Amazon EC2は、VPCエンドポイントを使用するように設定する必要があります) Lambda.4:Lambda functions should have a dead-letter queue configured(Lambda関数には、配信不能キューを構成する必要があります) KMS.2:IAM プリンシパルには、すべての KMS キーで復号アクションを許可する IAM インラインポリシーがあってはなりません OUの取り扱いに制約がある こちらは私が構築作業を行った際の2021年6月頃における内容です。OU関連でこういった制約がありました。 AWS Control Tower コンソールにネストされた OU を表示することができない。 AWS Control Tower コンソールからネストされたOUを作成することができない。 Control Tower配下のOUには、1つあたり最大5個のSCP(ガードレール)までしか適用できない。 Control Tower配下のOUには、1つあたり最大300アカウントまでしか登録できない。 最近OUのネストが可能になったという記事も見た気がしますが、以下のリンクなど参照して制約を確認した上で使用した方がよいと思います。 既存アカウントをControl Towerに追加する際に注意が必要 Control Towerでは自動的にガードレール(AWS Configルール)が作成され、配下のAWSアカウントに適用されます。このため、既存アカウント(既に運用などで使われている単体アカウント)をControl Tower配下に追加する場合、このガードレールの影響を受けないか事前確認する必要があります。 こちらで色々調べた限りでは、通常の使い方をしている限り影響を受けることはなさそうです。ただ実際影響があるかどうかはケースバイケースなので、既存アカウントを追加する場合は一通り確認しておいた方がよいかと思います。この辺りのURLに情報が記載されています。 一部のリージョンがControl Towerに対応していない 各リージョンにおける、2021/12月現在のContorl Towerの対応状況は以下の通りです。 リージョン(英語名) リージョン(日本語名) 対応状況 us-east-2 米国東部 (オハイオ) 〇 us-east-1 米国東部(バージニア北部) 〇 us-west-1 米国西部 (北カリフォルニア) × us-west-2 米国西部 (オレゴン) 〇 af-south-1 アフリカ (ケープタウン) × ap-east-1 アジアパシフィック (香港) × ap-south-1 アジアパシフィック (ムンバイ) 〇 ap-northeast-3 アジアパシフィック (大阪) × ap-northeast-2 アジアパシフィック (ソウル) 〇 ap-southeast-1 アジアパシフィック (シンガポール) 〇 ap-southeast-2 アジアパシフィック (シドニー) 〇 ap-northeast-1 アジアパシフィック (東京) 〇 ca-central-1 カナダ (中部) 〇 eu-central-1 欧州 (フランクフルト) 〇 eu-west-1 欧州 (アイルランド) 〇 eu-west-2 欧州 (ロンドン) 〇 eu-south-1 ヨーロッパ (ミラノ) × eu-west-3 欧州 (パリ) × eu-north-1 欧州 (ストックホルム) 〇 me-south-1 中東 (バーレーン) × sa-east-1 南米 (サンパウロ) × 大阪リージョンが入ってないのは若干悲しいですね。。今後のアップデートに期待です。 なお、非対応リージョンにはAWS Config、CloudTrailが自動展開されません。なので手動で展開するか、運用ルールで当該リージョンを使わないよう縛るなど対応する必要があると思います。 それならSCP(ガードレール)でそのリージョンの利用を禁止すればいいんじゃねえの?という話もありますが、Control Tower環境下にはそのような定義を入れることが推奨されていないようです。ソースはこちらに。赤枠の「重要」欄に注意事項として記載されています。 まとめ メリットよりも注意事項の方が多くなってしまいました。が、それを上回るメリットがContorl Towerにはあると思います。今年4月から東京リージョンにも対応してますので、気になる方は積極的に使ってみてください。きっと想像しているよりいいサービスですよ。 この記事が誰かのお役に立てると幸いです。
- 投稿日:2021-12-05T14:17:23+09:00
AWS Control Towerを実際に使ってみた感想と注意事項
はじめに 以前AWSでマルチアカウント環境を実装してみたという記事を書いており、この時には「自力で頑張ってAWSの色々なサービスを組み合わせてマルチアカウント環境を作成する」のを前提としていました。 それから間もなく、マルチアカウント環境を全部まるっとカバーしてくれるControl Towerというサービスが東京リージョンに対応しまして、業務で使う機会にも恵まれたのでその感想を共有したいと思います。 Control Towerの構築方法は他の方のブログや記事がたくさんありますので、ここでは業務を通して見えてきたControl Towerのメリットや注意事項などを自分なりに上げ連ねてみます。 ひとことで言うと Control Tower、最高です。自力で構築するとCloudFormationのテンプレート作ったりスタックセットで展開したりAWS Configルールの定義をたくさん作ったり、、、と果てしなく大変&運用も非常に煩雑になるのですが、このサービスを使えばほんとにマウスクリックだけで環境が作れてしまいます。 とはいえ扱いに少々癖があり慣れが必要なのと、Control Towerでカバーされていないリージョンや機能があるので一長一短ではありますが、自分で時間をかけて作るよりはこういったサービスを使う方がストレスも少ないですし、他の事に割ける時間も増えるので個人的には良いのではないかと考えています。 そもそもControl Tower&マルチアカウント環境って何よ?って方はこちらのリンクを参照ください。必要な情報がいい感じに纏められてますので。 メリット 色々あるとは思いますが、ぱっと思いつくところはこんなところです。 環境設定が全て自動で行われる AWS Config、Cloud Trailの設定、ログアーカイブアカウントへのログ集約、監査用アカウント作成等々、マルチアカウント環境に必要な設定が全自動で行われます。自分でやることは何もありません。マウスポチポチのみ。 さらにAccount Factoryという機能を使えば、新規のAWSアカウントを追加する際にも上記色々めんどくさい設定を全部勝手にやってくれた上で払い出してくれます。ステキ。 AWS SSOがついてくる 使ったことがない人にとっては若干敷居が高い(と思われる)AWS SSOですが、Contorl Towerを使えばこれも自動的に構築して提供してくれます。まあこの辺は「いらねえよ」という人もいるかもですが、いざ使ってみるとこれも相当にステキなサービスです。 マルチアカウント環境だと大きなところでは数十~数百のAWSアカウントを管理するケースも出てくると思いまが、AWS SSOを使わずにこういう大規模な環境を維持していくのは相当きついと思われます。 AWS SSOを使えば権限設定を一カ所に集約できますし、Organizations内の他のアカウントにスイッチするのも非常に楽に行えますので、特に中央管理者(マスターアカウントを管理し、メンバーアカウントに統制を効かせる側の人々)にとってメリットが大きいと思います。 規模やユースケースによるとは思いますが、個人的には中央管理者はAWS SSOを使い、メンバアカウント利用者にはIAMユーザを配る(各々勝手にやってもらう)くらいがちょうどいい使い方なのではないかな、と今のところは考えています。必要なガバナンスはガードレールやSecurity Hub、GuardDutyで効かせる感じで。 Control Towerダッシュボードが付いてくる マルチアカウント環境の中身をまるっと可視化できるダッシュボードが付いてきます。 このダッシュボードの中でメンバーアカウント一覧、OU一覧、適用済みのガードレール一覧、ガードレールの準拠状況、、、等々を確認することができます。色んな画面を飛ぶ必要がないので地味に便利です。 デメリット(というか注意点) デメリットというよりは、Control Towerを使うにあたっての注意点を以下列挙していきます。まあまあ癖があるので、この辺りの注意点が受け入れられなければ独自構築を選択した方がよいかもしれません。 GuardDutyやSecurity Hubには対応していない Control Towerを使ったとしても、上記サービスは自動で展開してくれません。なので使いたい場合は自分で手動設定する必要があります。全リージョンに展開する場合はまあまあ手間です。とはいえこちらは独自構築するとしても同じ話なので、そんなデメリットになる話でもないですが。 Control Tower自体がSecuryt Hubのセキュリティ基準に引っかかる これにはまあまあ苦労させられました。Security Hubにはセキュリティ基準という機能があり、AWSの推奨ルールから逸脱するサービスがないか常時チェックしてくれます。で、問題が見つかったらアラートでお知らせしてくれるのですが、これにControl Towerで自動作成されたサービス(Lambda、SNS等々)が引っかかったりするのです。 私の場合は1つずつアラートをチェックしてポチポチ修正していったのですが、結構根気のいる作業でした。スクリプト等を作って修正作業を自動化するなど、工夫が必要な個所かと思います。あと私はSecurity Hubの「AWS 基礎セキュリティのベストプラクティス v1.0.0」をよく使うのですが、Contorl Tower環境下では以下の定義は無効化しても良いのでは、と思っています。 SNS.1:SNS topics should be encrypted at-rest using AWS KMS(SNSトピックは、AWS KMSを使用して保存時に暗号化する必要があります) EC2.10:Amazon EC2 should be configured to use VPC endpoints(Amazon EC2は、VPCエンドポイントを使用するように設定する必要があります) Lambda.4:Lambda functions should have a dead-letter queue configured(Lambda関数には、配信不能キューを構成する必要があります) KMS.2:IAM プリンシパルには、すべての KMS キーで復号アクションを許可する IAM インラインポリシーがあってはなりません OUの取り扱いに制約がある こちらは私が構築作業を行った際の2021年6月頃における内容です。OU関連でこういった制約がありました。 AWS Control Tower コンソールにネストされた OU を表示することができない。 AWS Control Tower コンソールからネストされたOUを作成することができない。 Control Tower配下のOUには、1つあたり最大5個のSCP(ガードレール)までしか適用できない。 Control Tower配下のOUには、1つあたり最大300アカウントまでしか登録できない。 最近OUのネストが可能になったという記事も見た気がしますが、以下のリンクなど参照して制約を確認した上で使用した方がよいと思います。 既存アカウントをControl Towerに追加する際に注意が必要 Control Towerでは自動的にガードレール(AWS Configルール)が作成され、配下のAWSアカウントに適用されます。このため、既存アカウント(既に運用などで使われている単体アカウント)をControl Tower配下に追加する場合、このガードレールの影響を受けないか事前確認する必要があります。 こちらで色々調べた限りでは、通常の使い方をしている限り影響を受けることはなさそうです。ただ実際影響があるかどうかはケースバイケースなので、既存アカウントを追加する場合は一通り確認しておいた方がよいかと思います。この辺りのURLに情報が記載されています。 一部のリージョンがControl Towerに対応していない 各リージョンにおける、2021/12月現在のContorl Towerの対応状況は以下の通りです。 リージョン(英語名) リージョン(日本語名) 対応状況 us-east-2 米国東部 (オハイオ) 〇 us-east-1 米国東部(バージニア北部) 〇 us-west-1 米国西部 (北カリフォルニア) × us-west-2 米国西部 (オレゴン) 〇 af-south-1 アフリカ (ケープタウン) × ap-east-1 アジアパシフィック (香港) × ap-south-1 アジアパシフィック (ムンバイ) 〇 ap-northeast-3 アジアパシフィック (大阪) × ap-northeast-2 アジアパシフィック (ソウル) 〇 ap-southeast-1 アジアパシフィック (シンガポール) 〇 ap-southeast-2 アジアパシフィック (シドニー) 〇 ap-northeast-1 アジアパシフィック (東京) 〇 ca-central-1 カナダ (中部) 〇 eu-central-1 欧州 (フランクフルト) 〇 eu-west-1 欧州 (アイルランド) 〇 eu-west-2 欧州 (ロンドン) 〇 eu-south-1 ヨーロッパ (ミラノ) × eu-west-3 欧州 (パリ) × eu-north-1 欧州 (ストックホルム) 〇 me-south-1 中東 (バーレーン) × sa-east-1 南米 (サンパウロ) × 大阪リージョンが入ってないのは若干悲しいですね。。今後のアップデートに期待です。 なお、非対応リージョンにはAWS Config、CloudTrailが自動展開されません。なので手動で展開するか、運用ルールで当該リージョンを使わないよう縛るなど対応する必要があると思います。 それならSCP(ガードレール)でそのリージョンの利用を禁止すればいいんじゃねえの?という話もありますが、Control Tower環境下にはそのような定義を入れることが推奨されていないようです。ソースはこちらに。赤枠の「重要」欄に注意事項として記載されています。 まとめ メリットよりも注意事項の方が多くなってしまいました。が、それを上回るメリットがContorl Towerにはあると思います。今年4月から東京リージョンにも対応してますので、気になる方は積極的に使ってみてください。きっと想像しているよりいいサービスですよ。 この記事が誰かのお役に立てると幸いです。
- 投稿日:2021-12-05T13:36:25+09:00
Fargateだって25番ポートで外部メールサーバーに接続したい!
はじめに みなさん、SMTP接続してますか?メールを受信、送信するために利用されている方が多いかと思います。 SMTP接続といえば25番ポートですが、この25番ポートはユーザー認証といったセキュリティ面で必要な機能がなく過去にスパムメール配信などで悪用されたポートのため、現在殆どのサービスでは利用できないポートとして扱われています。 しかし今現在もメールリレー用のポートとして利用されていることもあり、どうしても接続しないといけないケースもあると思います。 今回、Fargateから25番ポートで外部メールサーバーに接続するために対応した内容をご紹介します。 2021年10月ごろに検討・対応した内容となります。最新の情報ではない可能性がありますのであらかじめご了承ください。 システム構成 アプリはSpringBootを用いたJavaアプリ コンパイルしたjarをDocker Image化してECRに保存 ECS on Fargate上でアプリコンテナを起動 メール配信する際にNAT Gatewayを経由して外部のメールサーバーに25番ポートでリレーする Fargateから25番ポートで接続してみる まずは何もせずFargateから直接外部のメールサーバーに接続してみます。しかし接続できずタイムアウトとなってしまいます。 VPCフローログを確認したところ、セキュリティグループやネットワークALCでは許可済みなのに該当外部メールサーバーへの接続が別の理由でREJECTされていることがわかりました。 なぜ接続できなかったのか AWSではスパムメールの配信を抑制するべく、EC2やLambdaといったサービスではデフォルトで25番ポートのアウトバウンドトラフィックがブロックされており、解除申請を出すことで利用可能となるようです。1 では、EC2やLambdaのように解除申請を出せばいいのかと思ったのですが、AWSサポートに詳細を確認したところFargateからの25番ポートでの接続は2021年10月時点では解除できないとの回答をいただきました。 回避策 現時点ではFargateからの25番ポートでの接続はできないことがわかりました。そのため、回避案として以下のものが考えられました。 FargateではなくEC2上でアプリを動くように変更する 外部メールサーバーの接続を25番ではないポートでの接続に変更する 内部にメールリレー用のEC2インスタンスを準備し、Fargateからメールリレー用EC2サーバーに25番以外でのポート接続→メールリレー用EC2から外部メールサーバーに25番ポートでの接続に変更する それぞれメリット・デメリットがありますが、今回はメールリレー用EC2サーバーを準備することでFargateからの25番ポート接続を実現するようにしました。 また、前述の通りEC2サーバーを準備してもデフォルトでは接続できないため、解除申請も合わせて提出しました。 まとめ 以上、Fargateから25番ポートで外部メールサーバーに接続する方法についてご紹介いたしました。 Fargateから25番ポートで接続したい方に参考になれば幸いです。 https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-port-25-throttle/ ↩
- 投稿日:2021-12-05T13:19:54+09:00
Salesforceの外部サービスを使ってAWSのLambdaを実行してみる
Ateam Brides Inc. Advent Calendar 2021の6日目は 株式会社エイチームブライズ エンジニア 新卒2年目になった@takaHALが担当します! これは何? Lambdaで作ったAPIをSalesforceの外部サービスに登録し SalesforceのフローからLambdaを実行してみます。 使うもの AWS Lambda IAM APIGateway CloudWatch 意識して使うのはこの4つ ServerlessFramework Salesforce 外部サービス 指定ログイン情報 利用するSalesforce環境はtrailheadのplayground環境です。 trailheadに登録すれば誰でも利用できます。 外部サービスとは OpenAPIのJSONファイルを登録することで、フロー内でOpenAPIに書かれた定義でREST APIを実行できます。 ノーコードでAPIを実行するフローアクションが作成できるので非常に便利なものになってます レスポンスも受け取ることができるため複雑なロジックもSalesforceの外部に置けるのもいいポイントです。 先にtrailheadをやっておくとイメージがしやすいと思います。 では早速やっていきましょう AWS側の準備 ServerlessFrameworkを利用します。 詳しい説明はServerless Framework の使い方を初心者にも分かりやすく説明するで書いてくださっているのでお勧めです。 デプロイに必要なIAMやAWSは準備してある前提で進めます あくまでもメインはSalesforceなのでAWSとServerlessFramework部分はサクッと済ませます。 1. プロジェクトを作成 開発環境 $ serverless --version Framework Core: 2.68.0 (local) Plugin: 5.5.1 SDK: 4.3.0 Components: 3.18.1 $ node -v v17.1.0 $ mkdir salesforce-lambda-test $ cd salesforce-lambda-test $ serverless create --template aws-nodejs-typescript --name salesforce-lambda-test 2. AWSにデプロイ $ npm install $ sls deploy service: salesforce-lambda-test stage: dev region: us-east-1 stack: salesforce-lambda-test-dev resources: 13 api keys: None endpoints: POST - https://{hoge}.us-east-1.amazonaws.com/dev/hello functions: hello: salesforce-lambda-test-dev-hello layers: None 3. 外部サービスに利用する openapiのjsonファイルを用意する 今回はサクッと検証するためにtrailheadのサンプルを少しいじって利用させていただきます。 実際はAPIGatewayの画面からエクスポートしたりdocumentationとして登録するといいと思います。 { "swagger": "2.0", "basePath": "/", "info": { "version": "1.0", "title": "External Service for demo bank", "description": "### External Service for demo bank", "x-vcap-service-name": "DemoBankRestServices" }, "securityDefinitions": { "basicAuth": { "type": "basic" } }, "security": [{ "basicAuth": [] }], "tags": [{ "name": "DemoBankRestServices" }], "paths": { "/hello": { "post": { "operationId": "postHello", "summary": "Add an account", "description": "Add an account to the database", "consumes": ["text/plain"], "produces": ["application/json"], "parameters": [ { "name": "accountName", "in": "path", "required": true, "type": "string", "description": "Name of the account" }, { "name": "accountType", "in": "query", "required": true, "type": "string", "description": "The type of account" } ], "responses": { "201": { "description": "The response when the account does not already exist and we can create one", "schema": { "$ref": "#/definitions/accountDetails" } }, "409": { "description": "The response when the account already exists and we cannot create one", "schema": { "$ref": "#/definitions/accountDetails" } }, "400": { "description": "Error response if the account name parameter is less than minimum characters", "schema": { "$ref": "#/definitions/errorModel" } }, "404": { "description": "Error response if the account is not supported by service or account is not found", "schema": { "$ref": "#/definitions/errorModel" } } } } } }, "definitions": { "accountDetails": { "required": ["id", "name", "type", "availableBal"], "properties": { "id": { "type": "string", "description": "id" }, "name": { "type": "string", "description": "name" }, "type": { "type": "string", "description": "type" }, "availableBal": { "type": "string", "description": "availableBal" } } }, "errorModel": { "required": ["errorCode", "errorMessage"], "properties": { "errorCode": { "type": "string", "description": "A service-specific error code." }, "errorMessage": { "type": "string", "description": "A service-specific error code." } } } } } 4. IAMを作成する SalesforceからAPIGatewayを通じでLambdaを実行するために使用するIAMを作成します。 AmazonAPIGatewayInvokeFullAccessを今回はとりあえず付与しました。 作成したらアクセスキーとシークレットアクセスキーをメモしておきましょうあとで使います。 これでAWS側の設定等の操作は終了です。 Salesforceで外部サービスを登録する 1. 指定ログイン情報の作成 項目 内容 URL デプロイしたAPIのエンドポイントを記入 ID種別 AWS 署名バージョン4 を選択 AWSアクセスキーID 作成したIAMのアクセスID AWSシークレットキー 作成したIAMのシークレットキー AWSリージョン デプロイしたAPIのリージョン 例) us-east-1 AWS サービス 今回はAPIGatewayにアクセスするので apigatewayと記載します コールアウトオプション 全部オフです そのまま好きな名前で保存でOKです。 しかし、リージョンとサービスにそのまま 文字列入れるの微妙にいけてないですね。。。。 そもそもここら辺は早くHyperforceでデフォルトでLambdaとかと繋げれるようにしてくれると楽なので今後に期待ですね。 2. 外部サービスの登録 外部サービスを新規作成でAPI仕様からを選択 外部サービスを設定 指定ログイン情報に先程登録したものを選択し、JSON形式の完全なサービススキーマを選択 AWS側の準備で準備したものを使います そのまま登録でOK フローで外部サービスを使ってみる 1. フローを新規作成 今回はデバッグ実行で動作確認するのみなのでどれでもいいです。今回はスケジュールトリガーフローにしてみます。 2. アクションを追加 外部サービスとして登録したものがフローのアクションとして選択できるので選択します。 入力値で選択できるのはparametersに記載したものになってます。 "parameters": [ { "name": "accountName", "in": "path", "required": true, "type": "string", "description": "Name of the account" }, { "name": "accountType", "in": "query", "required": true, "type": "string", "description": "The type of account" } ], ちなみに詳細の部分ではresponsesに記載した内容が取得できることがわかります。これでフローを200の時の値を使用したりエラーハンドリングもできますね "responses": { "201": { "description": "The response when the account does not already exist and we can create one", "schema": { "$ref": "#/definitions/accountDetails" } }, "409": { "description": "The response when the account already exists and we cannot create one", "schema": { "$ref": "#/definitions/accountDetails" } }, "400": { "description": "Error response if the account name parameter is less than minimum characters", "schema": { "$ref": "#/definitions/errorModel" } }, "404": { "description": "Error response if the account is not supported by service or account is not found", "schema": { "$ref": "#/definitions/errorModel" } } } 3. デバッグして確認してみる 実行できていますね CloudWatch側でも確認が取れました。 実行はできましたが、content-typeが`application/json`として送信されていないのでLambda側で処理するには向いていません。今回はそこまで対応できませんでしたが追加で対応出来次第記事を更新します。 リクエストボディパラメータがメソッド POST、PUT、PATCH について定義されていない場合、フォームデータリクエストパラメータがリクエストボディで application/x-www-form-urlencoded として送信されます テストで作成したAWSのリソースを削除 削除する場合は以下のコマンドです $ sls remove 参考にさせてもらった記事 最後に Salesforce関係の開発を触り始めて日が浅いですが、フローを使って外部APIと連携してみたりデータ連携をコードをほぼ書かなくてもいいようにできないかな?と思っていたところ外部サービスというものを見つけたので試してみました。 通常のopenapiの記述よりも癖はありますが、使いこなすと非常に便利な機能だと思いますので自分でもマスターしようと思います。 外部サービスをうまく使えば以下のようなことがSalesforce内でApexを書くことなく実現できます。 複雑な計算ロジックをSalesforceに持ち込むことなく利用できる Salesforce外の自社サービスのデータとコラボレーションしやすい などいろいろできそうです。 外部サービスとは違いますが、Apexで@InvocableMethodを使うとフローアクションを作成できるのでそちらもお勧めです。 sObject型を受け取ることができるので、レコードの更新をトリガーにしてBigQueryにオブジェクトのデータを送るとかさまざまな用途で使えると思います。 もう少し記事を更新していくつもりではいますが、質問やこっちの方がいいよ!みたいな意見があれば是非コメントにていただきたいです。 Ateam Brides Inc. Advent Calendar 2021の7日目は、@rf_pがお送りします!!どんなネタを用意してくるのか楽しみです!!
- 投稿日:2021-12-05T12:23:13+09:00
SageMakerで利用するCLIコマンドについてまとめていく(順次更新)
はじめに 実践AWSデータサイエンスという本を勉強しはじめて、AWSのデータリソースの削除を手作業で行っていました。 そんな中でネットで調べているとCLIで削除していることが多く、毎度するたびに調べるのも大変だったので、まとめることにしました。お金かかってしまうのですが、手作業大変なので調べてまとめていきたいです。 SageMaker sagemaker.py # エンドポイントの削除 import sagemaker sess = sagemaker.Session() sess.delete_endpoint(endpoint_name='エンドポイント名') S3 s3.py # S3へのアップロード(保存先表示) prefix = 'data' sess = sagemaker.Session() uri = sess.upload_data(path="./ファイル名.csv", key_prefix=prefix) print(uri) おわりに 削除できるリソースだけど、CLIコマンドはよくわからないというものも多くあるので徐々に更新になっていくかと思います。 一回とちって多額の請求をされているので気を付けたいです。
- 投稿日:2021-12-05T11:23:53+09:00
インフラ初心者が AWS の話がふわっと(本当にふわっと)わかるようになるまでにやったことまとめ
5日の記事は @polidog さんでしたありがとうございました。 最近の若いエンジニアも Xdebug は知ってましたw でも設定めんどくさくなって使わなくなっちゃてたんですよね、、、ただ改めて見るとやっぱり便利そうですね! 設定も思ったより簡単そう?なので今度使ってみようかな はじめに 自分は普段、サーバーサイドの開発をメインで行っているのですが、 インフラの環境は出来上がっている段階で作業することが多く AWS を直接触る機会はほとんどありませんでした。 なので、 今回は EC2 じゃなくて、Fargate を使っています。コンテナのイメージは ECR にアップします。 マルチ AZ で冗長構成にしています。スティッキーセッションになってます。 private subnet なので NAT gateway とか必要です。 なんて会話を聞いても、なるほどわからん。という状態でした。 流石に何を言ってるのかわからないような状態ではまずいと思い最近 AWS を勉強して、上記のような話になんとなくついていける程度にはなって、かなり簡単な環境なら自分でも構築できるようにはなったので、そのためにやったことを記事にしました。 同じように何言っているかわからんと思った人の参考になれば嬉しいです。 勉強する上で参考にさせてもらったもの 書籍 後程紹介します。 クラスメソッド発「やってみた」系技術メディア | DevelopersIO クラスメソッドさんの記事は勉強していて気になったことを調べる時によく使わせてもらいました。 1つ1つの記事のクオリティが高いのでとても参考になりました。 ハンズオン資料 | AWS クラウドサービス活用資料集 AWS の公式ハンズオンは毎回最初に申し込みフォームを入力する必要があるので初めは若干抵抗がありましたが、動画形式で好きな時間に何回でも見ることができ、わかりやすく、しかも無料なので、自分は公式ハンズオンをメインに勉強しました。 各ハンズオンの終わりに、ハンズオンで構築したリソースの削除方法まで教えてくれるので安心です。 Step1. AWS のアカウントを作る AWS のアカウントを作ってください。 AWS は有料のサービスなので、自分も初めはアカウントを作成するのに抵抗があったのですが、AWS の勉強したいなら AWS のアカウントは必須です。 AWS の環境を触っていたら料金がかかりますが、アカウント作成から1年以内なら使用できる無料枠を使っていれば、月々数百円から、かかっても数千円くらいです。(使い方さえ間違えなければ...) AWSアカウントを作成してみた(2021年7月) | DevelopersIO AWS Hands-on for Beginners ハンズオンはじめの一歩: AWS アカウントの作り方 & IAM 基本のキ これができれば後はできたも同然です。 Step2. 初期設定 必ず必要なわけではないですが、料金が心配な人はかかった料金に応じてアラートをあげてくれる機能などもあるので設定しておくといいかもです。 自分は毎日メールで使用料金が通知されるように設定しています。 後は支払い通過を日本円にしていたら、外貨取扱手数料がかからないので若干お安くなるのだとか Step3. 実際に触ってみる 書籍と AWS 公式ハンズオンを見ながら実際に触ってみました 書籍 書籍で最初に読むならこれがいいと思います。 基礎知識がなくても読むことができ、ハンズオン形式なのでとてもわかりやすかったです。 AWS 公式ハンズオン はじめにも記載しましたが、AWS の公式ハンズオンです。 気になるタイトルをやってみるのがいいと思います。 ちなみに自分は、 ハンズオンはじめの一歩: AWS アカウントの作り方 & IAM 基本のキ ecurity #1 アカウント作成後すぐやるセキュリティ対策 Network編#1 AWS上にセキュアなプライベートネットワーク空間を作成する Network編#2 Amazon VPC間およびAmazon VPCとオンプレミスのプライベートネットワーク接続 スケーラブルウェブサイト構築編 Amazon EC2 Auto Scaling スケーリング基礎編 AWS 上で静的な Web サイトを公開しよう! Amazon CloudFrontおよびAWS WAFを用いて エッジサービスの活用方法を学ぼう AWS Code サービス群を活用して、CI/CD のための構成を構築しよう! 監視編 サーバーのモニタリングの基本を学ぼう AWS 環境のコード管理 AWS CloudFormationで Web システムを構築する あたりをやらせていただきました。 Terraform 「 AWS の話をふわっと理解するようになる」という目的とは少し違うので、 Terraform を触る予定がない人は飛ばしても問題ないかもしれませんが、自分は Terraform を少しだけ触る機会があったので勉強しました。 Terraform をざっくり説明すると、インフラ構成をコードで管理できるツールです。 コードで書かれた構成をコマンド一発で AWS 上で(Terraform は AWS のみには限らず GCP などにも対応していますが)構築、削除することができます。 コードなのでバージョン管理もできます。 自分は下記の書籍で勉強させてもらいました。写経するだけでもかな勉強になりました。 Terraform に興味がある人は先に AWS の勉強をしてから、 Terraform を触る方が入りやすいと思います。 終わり AWS は有料のサービスです。 RDS なんかを立てっぱなしにしていると思ったより料金がかかってびっくりするかもしてません。 また、Github に AWS のキーペアをあげると 13 分で不正利用されるらしいので十分に気をつけてください。 ただ、普通に使っていれば急に高額な請求がくるといったことはまずありません。 興味がある人はビビらずにアカウントを作成するのが一番いいと思います。(責任は取れませんが?) 明日の記事 明日はほげさんが M1 Mac の Docker についての記事を書いてくれえるそうです。 Docker のイメージの中にはまだ M1 に対応されておらず、素直に動いてくれないものもあるようなので、M1 Mac を使っている人は参考になると思います!
- 投稿日:2021-12-05T10:38:51+09:00
JSONの内容を使って環境変数を設定する(AWS ElasticBeanstalk)
TL;DR elasticbeanstalk環境がeb sshしたときに環境変数を定義済みにしてくれなくなったので、そうしてくれるワンライナーを書いた。(qiita上で見やすくするために \ とかを入れています。) /opt/elasticbeanstalk/bin/get-config environment | \ jq -r 'to_entries|map("export \(.key)=\(.value|tostring)")|.[]' > ~/ebenv && \ source ~/ebenv 参考ページ 変換については、StackOverflowにほぼそのままの答があったので参照。bashではexportを入れないとグローバルに環境変数が設定されないのでその部分だけ少し修正。 elasticbeanstalkで環境変数を取得する方法は下記を参照。以前はどこかにあるファイルを参照すればよかった気がしているのだが、最近だとこちらが正なのかな。
- 投稿日:2021-12-05T09:29:02+09:00
RDS Custom for Oracle, RDS for Oracle, Oracle On EC2 の比較 [JPOUG Advent Calendar 2021]
JPOUG Advent Calendar 2021 の5日目のエントリーです。 前の記事は yoshikaw さんのOracle Database Express Edition(XE)で21c新機能を試してみるでした。 はじめに Amazon RDS Custom for Oracleは、10/26に発表されたRDSの新しい形態であり、RDSにもかかわらずOSレイヤへのrootアクセスが可能になります。 また、12/2のre:Inventにおいて、Amazon RDS Custom for SQL Serverが発表されており、力を入れているのが分かります。 Amazon RDSはフルマネージド型のサービスで使い勝手がよかった一方、メンテナンスタイミングや個別パッチの適用においては柔軟性に欠ける点もあり、エンタープライズ・プロジェクトでの利用には二の足を踏んでしまう事も多かったように思います。 RDS Customという形態は、個別パッチ等の適用が可能となることがメリットとなると思われますが、一方でrootアクセスを行えるという事はOS環境もユーザが管理していく必要があり、フルマネージドのメリットが損なわれると考えてます。 どのようなメリット・デメリットがあるのかをそれぞれ比較することで、今後のAWS上のOracle Databaseの選定の一助になればと考えてます。 なお、文中では単にRDSと記載した場合にはCustomではないRDS、RDS Customと記載した場合にはRDS Customを指してます(基本的には両方ともfor Oracleになります)。 RDS Custom for Oracleの概要 今までのRDSは基本的にAWSのフルマネージド型でOSレイヤへアクセスができなかったのに対し、Custom for OracleではOSレイヤへのrootアクセスも可能となっています。 RDS Customではフルではないがマネージドを実現するために、提供されるOSにはSSM Agentがインストールされており、基本的にはSSM Agentを経由してマネージドな機能が提供されます。 Oracle on EC2との違いとしては、公式では以下のように説明されています。 責任分担モデル 特徴 Oracle OnAmazon EC2 Amazon RDS for Oracle Amazon RDSCustom for Oracle アプリケーションの最適化 Customer Customer Customer スケーリング Customer AWS Shared 高可用性 Customer AWS Shared DBのバックアップ Customer AWS Shared DBのパッチ適用 Customer AWS Shared DBのインストール Customer AWS Shared OSのパッチ適用 Customer AWS Shared OSのインストール Customer AWS Shared サーバのメンテナンス AWS AWS AWS ハードウェアのライフサイクル AWS AWS AWS 電力、ネットワーク、および冷却 AWS AWS AWS RDS for OracleとOracle On EC2の比較は Classmethodさんの [2018年版] RDS for Oracle と Oracle on EC2 の比較 で実施されてますので、同じ切り口でRDS Custom for Oracleも比較してみます。 比較ポイント エディションとバージョン 利用料金 利用できるリソース 機能差 構築/運用 RDSで利用できるエディションとバージョン RDS Custom、RDSで利用できるエディションとバージョンは以下のような組み合わせになります。 現時点(2021/12/5)ではRDSとしてはOracleの12.1.0.2(~2022/7/31)や12.2.0.1(~2022/3/31)も利用できますが、サポート切れまで一年もないので割愛します。基本的には19cのみが利用可能となります。19c のRDSとしてのサポート期限は明示されてませんが、Oracle Databaseとしての期限は現時点では 2027/4/30 となります。 Oracleのエディション、バージョン Oracle OnAmazon EC2 Amazon RDS for Oracle Amazon RDSCustom for Oracle Enterprise Edition(BYOL) 19c 〇 〇 〇 Standard Edition2(BYOL) 19c 〇 〇 × Standard Edition2(ライセンス込み) 19c 〇 〇 × 利用料金 2021年12月のインスタンス利用料金になります。 料金は以下の条件 東京リージョンの1時間あたりのオンデマンド利用料金 EC2はRHEL(Red Hat Enterprise Linux)を対象とします(参考記事同様&やはり利用が多いと思うので) EC2はほかのインスタンスタイプも利用可能です RDSはシングルAZ(マルチAZの場合には概ね2倍です、RDS CustomはマルチAZには現時点では非対応です1) RDS単価(SE2)はライセンス込みの価格です 利用料「-」のインスタンスタイプは提供されてません 同じBYOLでもRDSに比べるとRDS Customの方が1-2割程度、高額で設定されてます。 インスタンスタイプ コアカウント VCPU メモリ(GiB) Oracle OnAmazon EC2EC2単価 RHEL Amazon RDS for Oracle単価(BYOL) Amazon RDS for Oracle単価(SE2ライセンス込み) Amazon RDSCustom for Oracle単価(BYOL) t3.micro 1 2 1 0.0736$ 0.026$ 0.044$ - t3.small 1 2 2 0.0872$ 0.052$ 0.088$ - t3.medium 1 2 4 0.1144$ 0.104$ 0.176$ - t3.large 1 2 8 0.1688$ 0.104$ 0.352$ - t3.xlarge 2 4 16 0.2776$ 0.416$ 0.704$ - t3.2xlarge 4 8 32 0.5652$ 0.832$ 1.408$ - m5.large 1 2 8 0.184$ 0.235$ 0.514$ 0.282$ m5.xlarge 2 4 16 0.308$ 0.47$ 1.028$ 0.564$ m5.2xlarge 4 8 32 0.626$ 0.94$ 2.056$ 1.128$ m5.4xlarge 8 16 64 1.122$ 1.88$ 4.112$ 2.256$ m5.8xlarge 16 32 128 2.114$ 3.76$ - 4.512$ m5.12xlarge 24 48 192 3.106$ 5.64$ - 6.768$ m5.16xlarge 32 64 256 4.098$ 7.52$ - 9.024$ m5.24xlarge 48 96 384 6.082$ 11.28$ - 13.536$ r5.large 1 2 16 0.212$ 0.277$ 0.556$ 0.332$ r5.xlarge 2 4 32 0.364$ 0.554$ 1.112$ 0.665$ r5.2xlarge 4 8 64 0.738$ 1.108$ 2.224$ 1.33$ r5.4xlarge 8 16 128 1.346$ 2.216$ 4.448$ 2.659$ r5.8xlarge 16 32 256 2.562$ 4.432$ - 5.318$ r5.12xlarge 24 48 384 3.778$ 6.648$ - 7.978$ r5.16xlarge 32 64 512 4.994$ 8.864$ - 10.637$ r5.24xlarge 48 96 768 7.426$ 13.296$ - 15.955$ r5b.large 1 2 16 0.241$ 0.335$ - - r5b.xlarge 2 4 32 0.422$ 0.67$ - - r5b.2xlarge 4 8 64 0.854$ 1.339$ - - r5b.4xlarge 8 16 128 1.578$ 2.679$ - - r5b.8xlarge 16 32 256 3.026$ 5.358$ - - r5b.12xlarge 24 48 384 4.474$ 8.037$ - - r5b.16xlarge 32 64 512 5.922$ 10.715$ - - r5b.24xlarge 48 96 768 8.818$ 16.073$ - - z1d.large 1 2 16 0.287$ 0.417$ - - z1d.xlarge 2 4 32 0.514$ 0.834$ - - z1d.2xlarge 4 8 6 1.038$ 1.668$ - - z1d.3xlarge 6 12 96 1.492$ 2.502$ - - z1d.6xlarge 12 24 192 2.854$ 5.004$ - - z1d.12xlarge 24 48 384 5.578$ 10.008$ - - x1.16xlarge 32 64 976 9.801$ 16.256$ - - x1.32xlarge 64 128 1952 19.471$ 32.512$ - - x1e.xlarge 2 4 122 1.269$ 1.9261$ - - x1e.2xlarge 4 8 244 2.548$ 3.8522$ - - x1e.4xlarge 8 16 488 4.966$ 7.7045$ - - x1e.8xlarge 16 32 976 9.802$ 15.409$ - - x1e.16xlarge 32 64 1952 19.474$ 30.8179$ - - x1e.32xlarge 64 128 3904 38.818$ 61.6358$ - - 利用できるリソース インスタンスタイプ 上記の利用料金表通りですが、RDS Custom for Oracleで利用可能なインスタンスタイプは m5シリーズもしくはr5シリーズのみとなり、z1d や x1e は利用できません。 RDSやEC2はコア数制限をかけることも可能です。 詳しくは Amazon RDS for Oracle に R5 インスタンスクラスでの新しいメモリ構成が追加されましたでご確認ください。 Customについても、CustomのイメージはAMIとなるので、該当のAMIに対して vCPUの指定 を行いコア数やHyperThreadingの設定(CPU最適化オプション)をする事は可能ですが、RDSと紐づけられないので現時点では利用できないと思われます。(←前提にサポートされていない機能、と記載がありました) 現時点ではEC2や従来型のRDSに比較しても選択できるインスタンスタイプは少ない状況です。 また、RDS Customの制限にあるとおり、Customでは動的なインスタンスタイプの変更が行えませんが、Snapshotを利用しての変更は可能です。 ストレージ 各構成にアタッチできるストレージは以下のような違いがあります。 RDSとRDS Customは同じ制限となります。 EC2の場合には複数ボリュームをアタッチすることで帯域を拡張することが可能ですが、インスタンス側の制限が上限となります。 また、RDS Customもボリュームタイプの変更(gp2 → io1 のような)が可能なはずなのですが、試した限りではメッセージが出て変更できませんでした(Snapshotを利用しての変更は可能でした)。 特徴 Oracle OnAmazon EC2 Amazon RDS for Oracle Amazon RDSCustom for Oracle ストレージタイプ gp2io1gp3io2io2 Block Expresssc1st1 gp2io1Magnetic gp2io1 最大サイズ 複数EBSの利用により64TB以上可能 64TB 64TB 最大IOPS 256,000io2 Block Expressの利用r5bインスタンスのみ 40,000 io1の利用 40,000io1の利用 オートスケーリング × 〇 ×ユーザガイド なお、CustomにおいてはOS部分、DB HOME部分(/rdsdbbin)は gp3 で自動的に作成され、それぞれ初期値は 26GB、25GB となってました(作成時に指定はできない)。ファイルシステムは ext4 です。 また、DB領域(/rdsdbdata)は指定したサイズのデバイスがマウントされます。中身をみると、指定したサイズの 1/4 のPVが 4本作製され、vgとしてまとめられてます(40GBで指定すると、10GBずつ4本のボリュームが作成されます)。 参考までにvgdisplay -vの結果を張り付けておきます(UUIDは削除してます) --- Volume group --- VG Name dbn0 System ID Format lvm2 Metadata Areas 4 Metadata Sequence No 2 VG Access read/write VG Status resizable MAX LV 0 Cur LV 1 Open LV 1 Max PV 0 Cur PV 4 Act PV 4 VG Size 39.98 GiB PE Size 4.00 MiB Total PE 10236 Alloc PE / Size 10236 / 39.98 GiB Free PE / Size 0 / 0 --- Logical volume --- LV Path /dev/dbn0/lvdbn0 LV Name lvdbn0 VG Name dbn0 LV Write Access read/write LV Creation host, time ip-xx-xx-xx-xx, 2021-11-18 14:48:17 +0900 LV Status available # open 1 LV Size 39.98 GiB Current LE 10236 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 252:0 --- Physical volumes --- PV Name /dev/nvme5n1 PV Status allocatable Total PE / Free PE 2559 / 0 PV Name /dev/nvme3n1 PV Status allocatable Total PE / Free PE 2559 / 0 PV Name /dev/nvme1n1 PV Status allocatable Total PE / Free PE 2559 / 0 PV Name /dev/nvme4n1 PV Status allocatable Total PE / Free PE 2559 / 0 --- Volume group --- VG Name dbdata01 System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 2 VG Access read/write VG Status resizable MAX LV 0 Cur LV 1 Open LV 1 Max PV 0 Cur PV 1 Act PV 1 VG Size 39.98 GiB PE Size 4.00 MiB Total PE 10235 Alloc PE / Size 10235 / 39.98 GiB Free PE / Size 0 / 0 --- Logical volume --- LV Path /dev/dbdata01/lvdbdata01 LV Name lvdbdata01 VG Name dbdata01 LV Write Access read/write LV Creation host, time ip-xx-xx-xx-xx, 2021-11-18 14:48:17 +0900 LV Status available # open 1 LV Size 39.98 GiB Current LE 10235 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 252:1 --- Physical volumes --- PV Name /dev/dbn0/lvdbn0 PV Status allocatable Total PE / Free PE 10235 / 0 機能差 本節ではOracle Databaseとしての機能差に絞って記載します。 RDS Custom for Oracle RDS Custom for OracleでFALSEになっているオプションはRACやASM等、以下の8個の機能になります。(v$optionで確認) Real Application Clusters Automatic Storage Management Oracle Label Security Oracle Database Vault Unified Auditing Management Database I/O Server ASM Proxy Instance また、とても重要な点として、RDS Custom for Oracleでは文字コードが固定で US7ASCII となります。現時点では変更することはできません。 RDS for Oracle RDS for Oracle でサポートされていない機能 RDS for Oracle(EE)でFALSEになっているオプション機能も、Customと同様に以下の8個です。 Real Application Clusters Automatic Storage Management Oracle Label Security Oracle Database Vault Unified Auditing Management Database I/O Server ASM Proxy Instance 構築/運用 構築 クラウド環境上でOracle Databaseの構築に必要な作業は、大きく以下のような順序で実施されると想定してます。 OS設定(OSパッチ適用、環境設定) Oracle DBソフトのインストール Oracle DB作成 Oracle DB環境設定(初期化パラメータや表領域、スキーマの設定等) Oracle DB HA構成設定(クラスタソフトのインストール・設定) Oracle DB運用設定(ジョブ実行環境の設定・監視設定・バックアップ設定) 以下の図の通り、RDSを利用することで、OS設定(必要なパッチ・カーネルの設定)やソフトウェアのインストール、DBの作成等は不要となります。 そのため、DB環境設定等、DB管理者として必要な作業に集中することができるようになります。 また、運用設定においても、OSへログイン・ファイル配置等が行える事で、オンプレ環境で利用していた運用シェル等や、エクスポート・インポートの機能をそのまま利用することが可能となり、単純移行・クラウドリフトを行いたい場合にはメリットがあると考えてます。 構築作業 Oracle OnAmazon EC2 Amazon RDS for Oracle Amazon RDSCustom for Oracle 1. OS設定 必要 不要 不要(カスタマイズする場合には必要) 2. Oracle DBソフトのインストール 必要 不要 不要事前のCEV(Custom Engine Version)の作成が必要 3. Oracle DB作成 必要 不要 不要 4. Oracle DB環境設定 必要 必要 必要 5. Oracle DB HA構成設定 要件によるData Guard設定等を想定 マルチAZ構成のため不要クロスリージョン自動バックアップも可能 要件によるData Guardの設定が可能 6. Oracle DB運用設定 必要エージェントインストール・設定を想定 必要他のサーバでジョブ実行を想定監視はCloud Watchへのログエクスポートによるフィルタリングが可能 必要エージェントインストール・設定を想定 運用 Oracle Database環境の運用としては、以下のような作業があると想定してます。 システムメンテナンス運用 データベースバージョン管理(パッチ適用) データベースのバックアップ・リカバリ 監視運用(パフォーマンス・リソース監視、死活監視、ログ監視) RDS、RDS Customを利用した時の運用における違いは以下になります。 RDS Customではバージョン管理やメンテナンスタイミングをユーザの管理下に置けます。 監視機能については、DB部分はRDSイベント通知、OS部分は自動的にインストールされるSSM Agentで監視が可能です。 ただ、SSM Agentでの監視については、デフォルトでアラートログがCloudWatchに連携されたりはしないため、実施するためには作りこみが必要になります。(Oracle On EC2 でもSSM Agentを入れれば同じことは可能となります) 運用作業 Oracle OnAmazon EC2 Amazon RDS for Oracle Amazon RDSCustom for Oracle システムメンテナンス運用 ユーザ管理 AWS管理週次のメンテナンスウィンドウが必要 ユーザ管理メンテナンスウィンドウは設定される データベースバージョン管理(パッチ適用) ユーザ管理適用タイミングは選択可能個別パッチ等も適用可能 パッチ選定・適用作業はAWS管理RU(Release Update)もしくはRUR(Release Update Revision)ベースでの適用個別パッチの適用は不可 パッチ適用作業のみAWS管理パッチ選定・適用タイミングはユーザ管理個別パッチ等も適用可能 データベースのバックアップ・リカバリ ユーザ管理 AWS管理 AWS管理ユーザでの管理も可能 パフォーマンス監視 ユーザ管理 AWS管理パフォーマンスインサイト利用可能 AWS管理が可能SSM Agentの機能が利用可能 リソース監視 ユーザ管理 AWS管理CloudWatch利用可能 AWS管理が可能SSM Agentの機能が利用可能 死活監視 ユーザ管理 AWS管理RDSイベント通知利用可能 AWS管理が可能RDSイベント通知利用可能ユーザ管理での監視も可能 ログ監視 ユーザ管理 AWS管理CloudWatch利用可能 AWS管理が可能SSM Agentの機能が利用可能 まとめ 現時点で RDS Custom for Oracle のユースケースとしては、以下のような場合かと考えてます。 オンプレ環境からAWS環境へOracle Databaseの単純移行を行いたいが、バックアップ等はクラウドの機能を利用したい 単純移行なのでOS上の環境構成等はなるべくそのままにしたい Oracle環境へのパッチ適用はシステム影響を鑑みて細かく調整したいが、マネージドな機能は利用したい どちらかというと、新規にAWS上でOracle Databaseを利用したい、というよりもオンプレからの移行の際の選択肢の一つになってくるのかな、と思いました。 一方で、現時点では利用にあたって文字コードが US7ASCII しか利用できない点は、日本での利用においては大きな障害となると考えており、機能改善が待たれるところです。 話はそれますが、Oracle CloudのDBCS(Database Cloud Service)も同じような仕組み(OSへrootログイン可能)なマネージドデータベースとして構成されており、今回はできませんでしたがDBCSとの比較等も別途実施したいと考えてます。 DataGuardを利用したRead Replica 構成でのマルチAZは可能です Working with read replicas for RDS Custom for Oracle ↩
- 投稿日:2021-12-05T05:38:54+09:00
初めて触るAWS
はじめに この記事は ・とりあえずVirtualBoxでLinuxサーバーを構築したことがある ・フロントやってるけどインフラ触ったこと無い ・クラウドってよくわからないけどとりあえず触ってみたい ・AWSでサーバー(EC2)を立ててみたい こういった方向けの記事になります。AWSに限らずサーバー構築初学者向けです。 各リソースの作成方法などはggればいくらでも出てきますので、本記事では初めてAWSを触る上での大まかな方針を提示していきます。 記事中で触れるサービスについては基本的に費用をなるべくかけない構成を心がけて作成していますが、完全に無料ではない点をご了承いただければと思います。 また、AWS用語についても極力解説していくようにしますが、知らない単語が出てきたら極力ggって意味をなんとなくでも良いので理解しながら進めることを推奨します。 VPCを作成してみよう ざっくりとした説明ですが、AWSアカウント内に構築できる仮想ネットワークを指します。このネットワークの中で色々なサービスを動かします。 VirtualBoxさんがよしなにやってくれている部分も自分で作るようなイメージですね。 とりあえずサーバー(EC2)立てたいだけなんだけど...という方はいきなり躓いてしまうかもしれませんが、VPCが無いとそもそもEC2は作成出来ないので、 ここは頑張って作りましょう。 VPCを作成するにはsubnet、NAT Gateway、Internet Gateway、Route table等々、結構たくさんの作成する必要があります...... EC2を立てたいだけなのにいきなりハードル高いです。 特に今回想定している層にとっては初手でネットワーク構築をしろと言われても難しいかもしれません。 しかしそこはAWS先輩、最初から各regionに「デフォルトVPC」なる物を予め用意してくれています!!やったぜ、さすがAWSパイセン。 ということで上に書いたことは(本記事では)やらなくても良いのです。 では何故書いたかというと、基本的にAWSサービスを使用する上でVPCはほぼ必須だからです。 今回はデフォルトVPCを使用する前提で進めていきますが、AWSを使用する上でVPCの理解は必要なので書きました。 サーバーを立てるためにはその土台を作ることが必要ということです。 このあたりはネットワークの知識になってきますので気になった方は各自調べてみましょう。 ちなみに各regionにデフォルトVPCが作成されますので、いきなりアメリカやヨーロッパにサーバー立てちゃったり出来ます。何だかすごいことやってる気になれます!! デフォルトVPCについて EC2を立ててみよう AWSにおけるサーバーと言えばまずEC2ですね。 microサイズのEC2インスタンスには無料利用枠があるので、まずはmicroで立ててみましょう。 ※EC2インスタンスについては無料枠がありますが、EBSボリュームについては一定のサイズ以上は課金対象なので注意してくださいね。 EC2の無料利用枠についてはこちら。 EBSの無料利用枠についてはこちら 作成方法については公式サイトに手順が載っていますのでこれに沿って作成しましょう。 OSはUbuntuだったりRHEL等を選べますが、せっかくAWSなのでAmazon Linux2を選択しましょう。 RedHat系のディストリビューションなので、基本的にはRHELやCentOSみたいなもの考えてもらってOKです(詳細は割愛します)。 パッケージ管理はyumですね。 余談ですが、一部のパッケージやバージョンはamazon-linux-extrasを叩かないと入らなかったりすることに注意が必要です。 RedHat系ではyumで入るのにAmazon Linux2では入らない、なんて時はこいつの可能性が高いです。 yumで入らなかったときのエラー分の中に、たまにこんな感じでAWSさんが優しく教えてくれることがあります。 To use, run $ sudo amazon-linux-extras install :topic: Learn more at https://aws.amazon.com/amazon-linux-2/faqs/#Amazon_Linux_Extras 作成手順に沿って進めていくと、セキュリティグループを設定する項目に当たります。 ssh接続をしたことが無い方はココで悩むかもしれませんが、 EC2は作成時にパスワード認証での接続は出来ないようになっているので、設定が必要ということです。 次にキーペアの設定項目が出てきます。 新しいキーを作成しましょう。 ココまで来たらいざ起動ですね。 起動が完了したら早速ログインしてみましょう。 こんな感じでsshコマンドを実行すれば接続できます。 $ ssh -i "キーペア名" ec2-user@"IPアドレス" ssh出来ない場合、セキュリティグループやpermissionを確認しましょう。 EC2は起動出来たんだけどssh出来ない......っていうのは初めてAWSを触る上で結構あるあるなので安心してください。 トラブルシューティングの記事が山程出てきますので諦めずに根気よく調べましょう! 一応公式のトラブルシューティングのリンクを貼っておきます。 ssh出来たら色々遊んでみましょう!! timezoneがUTCなのでJSTに変更してみたりhostnameを変更してわかりやすくしてみてください。 EC2を複製する EC2が作成出来たら今度は複製してみましょう。 作ったものをそのまま複製したところで違いがわからないかもしれないので、適当にhttpdあたりをyumでインストールしておきましょう。 AWSのサービスの中にAmazon Machine Image (AMI)を言うものがあります。 とてもざっくりですが、これは既存のEC2の状態を保存するサービスになります。 手順に沿ってAMIを作成し、AMIからインスタンスを起動してみましょう。 作成できたら互いにpingコマンド等で疎通が取れるようにしてみてください。 まとめ 今回はEC2を作成する事に主眼をおいて記事を作成しました。 RDSやS3についても最初に触れるサービスとして書こうかと考えましたが、EC2にsshする段で躓くかなぁ...と感じココまでとします。 EC2を立てたら今度はRDSを作成して疎通を取ってみたり、S3バケットを作成してファイルをEC2からS3へputしたり等で遊んでみると面白いかもしれません。 特にS3へputすることに関してはIAM関連の知識をつけることに役立ちますのでオススメです。
- 投稿日:2021-12-05T03:16:11+09:00
Amazon SESへqmailからSMTPリレーする
こんにちは。株式会社シーズの原口と申します。 この記事は、Japan APN Ambassadors Advent Calendar 2021 の 7日目のエントリです。 APN Ambassadorって何?と言う方は、APN Ambassadorsってなんだ?2021年度版をご参照ください。 今年は弊社はデータセンタ閉鎖を行い、100台弱の既存オンプレミスサーバをAWSへ移行しました。私的にはMigration of the yearです。 そんな大きなプロジェクトに関するお話もしたかったのですが、AWS移行の大きなカテゴリーであるメール、、、その中でもとりわけqmailについてフォーカスしたニッチな技術記事になります。 今回のAWS移行においてはqmailからSES利用がうまくできなかったのでPostfixへ変更していたのですが、どうしても敗北感がありもやもやしてたので、こちらを再トライしてみました。 Amazon SES使ってますかー! AWSでメールを送信するならAmazon SESですよね。 アカウントレベルのサプレッションリストがデフォルトで有効となりバウンスレートや苦情レートの上昇による利用停止措置も受けにくくなり、ますます使いやすくなりました。 Amazon SESはAPIによるメール送信も行えるためサーバレスやコンテナのような環境ではアプリケーションから直接利用する事も一般的となってきているのではないかと思います。 しかしながら、既存システムからのSES利用にあたってはアプリケーションの修正なく、EC2の既存MTAから気軽にメールを送りたいという需要は意外と多いのではないでしょうか。 Amazon SES を既存のMTA(メール転送エージェント)と統合する すでにMTAを利用した既存メールサーバーがある場合、Amazon SESのSMTPエンドポイントを利用したメール送信を行う事ができます。 既存MTAを使ってSESから送信する最大のメリットは、Linuxコマンドであるmailコマンドやsendmailコマンドを使ったメール送信が行える事です。これによって既存アプリケーションの改修なくAmazon SESを利用する事ができます。お手軽ですね。 これはMTAからSESへSMTPリレー設定を行う事で実現します。 主要なMTAであるPostfixなどは設定ファイルをちょちょっと設定するだけでSESからのメール送信が可能となります。 (参考)Amazon SES を既存の E メールサーバーと統合する https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/send-email-smtp-existing-server.html AWS公式ドキュメントでは主要なMTAにおけるSESへのSMTPリレー手順が記載されていますね。 Postfix、Sendmail、IIS SMTP、Exim、、、、あれ!qmailがない!! かつては主要なMTAの一つであったqmail。。qmailからSESを使いたいという需要は少なからずあるのではないでしょうか? という事で古きMTAであるqmailからのSESへのSMTPリレーを試してみました。 qmailからのAmazon SESへのSMTPリレー 要はAmazon SESをqmailからのスマートホスト(smarthost)として利用したいという形となります。 Amazon SESのSMTPエンドポイントの利用にあたっては以下の3つの要件を満たすMTAである必要があります。 ・SMTPリレーを介した送信をサポートしている事 ・SMTPリレー時にSMTP認証(AUTH LOGIN)ができる事 ・接続がTLSで暗号化されている事 こちらの後半2点においてqmailは対応していません! これらの課題をqmailの伝統芸であるパッチによって解決していきます。 それぞれ解決していく 前提としてqmailがインストールされているものとします。 SMTPリレーを介した送信をサポートしている事 こちらはqmailはデフォルトで対応しています。 /var/qmail/control/smtproutes にリレー先を以下のように記述する事でqmailが全てのメール送信をSESへリレーしてくれます。 :email-smtp.ap-northeast-1.amazonaws.com:587 もちろんこれだけでは認証情報がないのでリレーできません SMTPリレー時にSMTP認証(AUTH LOGIN)ができる事 こちらはqmailはデフォルトでは対応していないため、以下の2点のパッチを導入します。 ・qmail-smtpd-auth ・qmail-remote-auth qmail-smtpd-auth qmailをSMTP-AUTHに対応するパッチです。qmail側への接続へのSMTP-AUTHを行うものなので本来は不要なのですが、後述の qmail-remote-authパッチがこちらの導入が前提となっているため導入します。 cd /path/to/qmail-1.03/ wget http://tomclegg.net/qmail/qmail-smtpd-auth-0.31.tar.gz tar xvfz qmail-smtpd-auth-0.31.tar.gz cd qmail-smtpd-auth-0.31 cp *.* ../ cd ../ patch < auth.patch qmail-remote-auth こちらがお目当てのパッチです。SMTP認証をqmail-remoteに追加して、認証がリレーサーバを介してメール送信を可能とします。 cd /path/to/qmail-1.03/ wget http://tomclegg.net/qmail/qmail-remote-auth.patch patch < qmail-remote-auth.patch こちらの2点のパッチを導入しましたらqmailを再コンパイルします make make setup make check この状態で/var/qmail/control/smtproutesへ以下のように記述する事で、認証を行なってSMTPリレーが可能となります :email-smtp.ap-northeast-1.amazonaws.com:587 アクセスキー シークレットキー 接続がTLSで暗号化されている事 こちらを対応するようなqmailパッチは存在しません。 qmail本体では対応できないとするとどうするか、、、そう思った時に思いつきました。 Amazon EFSや昔のSESではTLS接続するのにstunnelを使ってたな、、、と。 SESに対するTLSの処理はstunnelで行い、stunnnelにはTLS無しで接続させるという形でやってみます。 以下のコマンドでインストール (* Amazon Linux 2を想定しています) yum install stunnel 設定ファイルを作成します vi /etc/stunnel/stunnel.conf pid = /var/run/stunnel.pid output = /var/log/stunnel.log CAfile = /etc/pki/tls/certs/ca-bundle.crt [smtps] accept = 10465 client = yes connect = email-smtp.ap-northeast-1.amazonaws.com:465 起動 stunnel /etc/stunnel/stunnel.conf ローカルの10465ポートへ非暗号化通信であるtelnetで接続するとSESが返答してくれている事がわかります。 [root@ip-172-30-1-72 ~]# telnet localhost 10465 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 email-smtp.amazonaws.com ESMTP SimpleEmailService-d-1ZCC87W6E mzCQQsfuXhBCUdqrKvHK 451 4.4.2 Timeout waiting for data from client. ここまでくれば/var/qmail/control/smtproutesを以下のようにstunnelへ向ける事でqmailからSESのSMTPエンドポイントへのリレーが可能となります! :127.0.0.1:10465 アクセスキー シークレットキー 実際にqmailでメール送信を行なってみてログを確認します。 @4000000061aa3a480a3fae1c info msg 2689857: bytes 374 from <root@seeds-std.co.jp> qp 7246 uid 0 @4000000061aa3a480a676de4 starting delivery 31: msg 2689857 to remote haraguchi@seeds-std.co.jp @4000000061aa3a480a67816c status: local 0/60 remote 1/60 @4000000061aa3a481b1f9c74 delivery 31: success: 127.0.0.1_accepted_message./Remote_host_said:_250_Ok_0106017d80f38322-fdd0c104-4c96-461f-a479-135c3bb4034d-000000/ @4000000061aa3a481b20ec64 status: local 0/60 remote 0/60 @4000000061aa3a481b214e0c end msg 2689857 ばっちりですね。 まとめ 今回はとりあえずできるかどうかという検証でしたので、実際のプロダクション環境では負荷試験や運用実績が欲しいところですが、ひとまずの足掛かりとしていかがでしょうか? もし既存環境がqmailでそこからのSES利用ができずお困りの方は是非ご参考いただければ幸いです。 久しぶりにqmailへのパッチ当てたりとか楽しかったです
- 投稿日:2021-12-05T01:53:23+09:00
AWS CLIで Web サイトを構築、管理、運用する(5日目)
4日目では、ライフサイクルポリシーを設定してアクセスログが無尽蔵に増え続けるのを防ぎました。 5日目は、コンテンツ配信ネットワークの設定を入れます。 5日目の要約 コンテンツ配信ネットワークの設定を入れる! AWS CLI の準備 このあたりをみて、好きなバージョンとお使いのOSにあった環境設定をしてくださいね。 なんなら、 AWS CloudShell で実行するのも楽でよいと思います。 この記事シリーズは、AWS CloudShell で実行し、実行例を載せています。 バージョン1 https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv1.html バージョン2 https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2.html 概要 CloudFront の設定をしてコンテンツ配信ネットワークを使えるようにする。 さあ、やってみよう! CloudFront では「ディストリビューション」というもので、どこからコンテンツを得るのか(オリジン)といった設定を行います。 コマンドは cloudfront create-distribution を使用します。 そして、このコマンドに投入する json ファイルを事前に作成します。 少し長めですが、ご参考まで。。。適宜変更を加えてください。 distribution.json { "DistributionConfig": { "CallerReference": "<任意の値>", "Aliases": { "Quantity": 0 }, "DefaultRootObject": "", "Origins": { "Quantity": 1, "Items": [ { "Id":"<S3 Web サイトのFQDN>", "DomainName": "<S3 Web サイトのFQDN>", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "CustomOriginConfig": { "HTTPPort": 80, "HTTPSPort": 443, "OriginProtocolPolicy": "http-only", "OriginSslProtocols": { "Quantity": 3, "Items": [ "TLSv1", "TLSv1.1", "TLSv1.2" ] }, "OriginReadTimeout": 30, "OriginKeepaliveTimeout": 5 }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false } } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "<S3 Web サイトのFQDN>", "TrustedSigners": { "Enabled": false, "Quantity": 0 }, "TrustedKeyGroups": { "Enabled": false, "Quantity": 0 }, "ViewerProtocolPolicy": "allow-all", "AllowedMethods": { "Quantity": 2, "Items": [ "HEAD", "GET" ], "CachedMethods": { "Quantity": 2, "Items": [ "HEAD", "GET" ] } }, "SmoothStreaming": false, "Compress": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6" }, "CacheBehaviors": { "Quantity": 0 }, "CustomErrorResponses": { "Quantity": 0 }, "Comment": "", "Logging": { "Enabled": false, "IncludeCookies": false, "Bucket": "", "Prefix": "" }, "PriceClass": "PriceClass_All", "Enabled": true, "ViewerCertificate": { "CloudFrontDefaultCertificate": true, "MinimumProtocolVersion": "TLSv1", "CertificateSource": "cloudfront" }, "Restrictions": { "GeoRestriction": { "RestrictionType": "none", "Quantity": 0 } }, "WebACLId": "", "HttpVersion": "http2", "IsIPV6Enabled": true } } json ファイルが作成できたら、ディストリビューションを作成していきます。 aws cloudfront create-distribution --cli-input-json file://distribution.json コマンド実行が正常に完了すると、作成されたディストリビューションの情報が入った json が出力されます。 今回は流石に長いので割愛します。 出力された json のうち、 DomainName の値を確認します。 これが、CloudFront 経由でアクセスする際のFQDNです。 動作確認しよう さきほど確認した DomainName の値を用いて curl コマンドを実行します。 curl https://<CloudFront の DomainName の値> 問題がなければ、3日目で作成した HTML が表示されるはずです。 もし、以下のような内容が返された場合は、 CloudFront のディストリビューションの設定を AWS のエッジロケーションに配布中の可能性が高いです。少し待ってから再実行してみてください。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <TITLE>ERROR: The request could not be satisfied</TITLE> </HEAD><BODY> <H1>403 ERROR</H1> <H2>The request could not be satisfied.</H2> <HR noshade size="1px"> Bad request. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner. <BR clear="all"> If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation. <BR clear="all"> <HR noshade size="1px"> <PRE> Generated by cloudfront (CloudFront) Request ID: gXOtvEVz_s7_8655aVFU9LPaf1bH33nv1txEtFuIA4KNEuYSLwXBbg== </PRE> <ADDRESS> </ADDRESS> </BODY></HTML> まとめ S3 で配信している Web サイトをコンテンツ配信ネットワークである CloudFront に載せることができました。 また、副次的な効能として https でアクセスできるようになりました。 実は、 S3 の Web サイトホスティング機能は http のみのアクセスだったのです。。。! 今回使ったコマンド cloudfront create-distribution
- 投稿日:2021-12-05T00:27:52+09:00
EC2のWindowsサーバーで、PHP (Laravel ) + Apache + RDS(MySQL) + SFTP の環境構築 ①
はじめに AWS EC2のWindowsサーバーでlaravelを使用したアプリ開発の案件があり、Windowsの環境構築をしましたので、その方法をまとめます。 今まで、Amazon Linuxしか使っていなかったため、windowsサーバーの癖に苦戦しながらも構築しましたので、参考になればと思います。 例えば、サーバーへの接続は、SSH接続ではなくリモートデスクトップ(以後、RDP)からアクセスするなどなど。。 環境構築 windows version windows server 2022 インストール情報 apache:2.4.51 php:8.1.0 phpmyadmin composer: 2.1.14 laravel ルートディレクトリ C:\Apache24\htdocs RDS aurora MYSQL:8.0.23 IDE Visual Studio Code SFTP OpenSSH 簡易環境構築図 ゴール SFTPでローカルのPCからWindowsサーバーにファイル転送が容易にできる。 外部公開し、WindowsサーバーのIPアドレスをブラウザのURL欄に入れて、Laravelのindex.phpが表示される。 流れ EC2を起動設定 Windowsサーバーにリモートデスクトップで接続する 日本語設定と時計合わせ Visual Studio Codeをインストール ApacheとVisual C++ ランタイムのインストール Apacheのhttpd.confファイル修正 Apacheの起動↑①ではここまで PHPインストール phpmyadminインストール composerインストール laravelインストール OpenSSH を使用して Windows に SFTP サーバーをセットアップ EC2を起動設定 EC2は、Windows Server 2022の最新のサーバーを選択しました。 スペックは、nanoだとwindows内での作業に支障をきたすほど動きが遅いです。 microもしくは、smallにしましょう。 自動割り当てパブリック IPは、有効にしています。 ストレージは30GBだと足りませんので、60GBにします。 一応、後でEBSのボリューム変更は可能です。 コンソール上でEBSのボリュームを変更し、Windowサーバーに接続後、Power Shellで以下の記事通りに進めると、変更できます。 セキュリティーグループは、SFTP接続でローカルから簡単にファイル転送したいため、SSHを開けています。 RDPは、Windowsであればデフォルトで設定されており、リモートデスクトップで接続する際に必要です。 他の設定は、特にありません。EC2を起動しましょう。 Windowsサーバーにリモートデスクトップで接続する EC2に対してリモートデスクトップで接続します。 以下のaws記事(RDP を使用した Windows インスタンスへの接続)通り行うと、うまくいきます。 こちらでもよいですね aws記事の前提条件に記載してありますが、ご自身のPCに、RDPクライアントをインストールする必要があります。 Macであれば、Microsoft Remote Desktopですね。 このwindows画面が出ると接続成功です。 今後は、rdpファイルを起動するとwindowsサーバーに入れます。 日本語設定と時計合わせ windowを日本語設定にしましょう。 こちらの記事通りするとよいです。 追加の作業として、keyboardのlayoutも日本語設定にしてもよいですね。 設定が完了したら再起動しましょう。RDP接続が切れますが、rdpファイルから起動できます。 また、ファイル名の拡張子と隠しファイルの表示方法はこちらを参考にするとできます。 Visual Studio Codeをインストール 下記の記事通り行うとよいです。 VSCダウンロードページからダウンロードができない場合 Internet Explorerを使用している場合、下記の記事通りにすると、VSCをダウンロードできるかもしれません。 ダウンロードできない時、私の場合chromeはダウンロードできましたので、ブラウザはchromeを使用し、VSCをダウンロードしましょう。 記事内容を図を合わせて説明しますと、サーバーマネージャーのローカルサーバーから、セキュリティー強化の構成の有効をクリックします。 両方のグループをオフにすると、VSCがダウンロードできる記事では説明がありました。 私の場合、できませんでしたが、chromeはインストールできましたので、chromeからVSCをダウンロードしました。 ApacheとVisual C++ ランタイムのインストール Apacheのインストール 以下のページから最新版のApache 2.4.51 Win64のZipファイルをインストールします。 解凍したフォルダ(Apache24)を任意の場所に移動します。 今回は C ドライブ直下に配置します。 ApacheのVisual C++ ランタイムのインストール Windows 用 Apache のバイナリは Visual C++ でビルドされているので、VC のランタイムが必要になります。 ※すでにインストールされている場合は必要ありません。 以下の URL よりダウンロードします。 64bit の場合は vc_redist.x64.exe になります。 ダウンロードしたファイルを実行することでランタイムがインストールされます。 Apacheのhttpd.confファイル修正 C:\Apache24\conf\httpd.confの設定ファイルを変更します。 ServerRoot (確認は必須) Apache サーバーが存在するディレクトリを設定します。 すでに設定されておりましたので、特に変更しません。 Apache24\conf\httpd.conf Define SRVROOT "c:/Apache24" ServerRoot "${SRVROOT}" 上記の設定によって、 httpd.conf内で${SRVROOT}と記載するとc:/Apache24という意味に置き換えられます。 Listen (必要に応じて設定) サーバが listen するIP アドレスとポート番号を設定します。 httpとhttpsを受け入れます Apache24\conf\httpd.conf Listen 80 Listen 443 #追加 LoadModule (必須) ロードするモジュールを設定します。 使用可能なものは概ねすでに記述されていますので、必要となるモジュールのコメントを外します。 laravelを使うに当たり、LaravelProject/public/.htaccessファイルをApacheに認識させるため、rewrite_moduleが必要です。 Apache24\conf\httpd.conf LoadModule rewrite_module modules/mod_rewrite.so # コメント外す ServerName (必要に応じて設定) アクセスされるドメイン名があれば設定します。 ポート番号との組み合わせも可能です。 今回は、サーバーのIPアドレスでアクセスしますので、変えません。 Apache24\conf\httpd.conf #ServerName www.example.com:80 ServerName mydomain.com DocumentRoot (確認は必須) 公開ディレクトリを設定します。 デフォルトは、C:\Apache24\htdocs配下に設定されていますので、変更しません。 後で、laravelインストール時に、laravelのパスに合わせて、変更します。 Apache24\conf\httpd.conf DocumentRoot "${SRVROOT}/htdocs" ちなみに${SRVROOT}/htdocsというのは、c:/Apache24/htdocsと同義です。 ドキュメントルートのディレクトリ設定 (修正必須) ドキュメントルートのディレクトリ内で適用するディレクティブを以下のように設定します。 Apache24\conf\httpd.conf #<Directory "${SRVROOT}/htdocs"> <Directory "c:/web/public"> #Options Indexes FollowSymLinks Options FollowSymLinks #AllowOverride None AllowOverride All Require all granted </Directory> 以下、各詳細説明です。 ・Directory ディレクティブの適用をディレクトリ単位に指定できます。 ・Options 特定のディレクトリに対してどの機能が使用可能かを制御します。 デフォルトでは以下の2つがOptionsで設定されています。 ・Indexes ディレクトリ配下の構造がweb上で確認できてしまいます。 ディレクトリの中身が見えてしまう可能性があり、セキュリティの観点から通常設定しませんので、コメントアウトします。 ・FollowSymLinks サーバがこのディレクトリ内でシンボリックリンクをたどれるようにします。 ・AllowOverride Noneが指定された場合、.htaccessは完全に無視されます。 .htaccessを有効にしたい場合はAllを指定します。 LaravelProject/public/.htaccessをApacheに認識させるため、修正必須です。 ・Require アクセスの許可を設定します all grantedではすべてのアクセスを許可します。 ディレクティブやディレクティブ内で使用できます。 ちなみに以下のような指定が可能です。 Apache24\conf\httpd.conf Require all granted # すべて許可 Require all denied # すべて拒否 Require ip 192.168.10.1 # 指定のIPアドレスからのアクセスのみ許可 Require ip 192.168.10.1/24 # 指定のIPアドレスの範囲からのアクセスのみ許可 Require host example.com # 指定のドメインからのアクセスのみ許可 .htaccess の有効の有無 (必要に応じて修正) デフォルトでは、.htaccessは<Files>ディレクティブを用いて使用禁止にされています。 .htaccessを利用したい場合は、これを編集します。 Apache24\conf\httpd.conf <Files ".ht*"> #Require all denied Require all granted </Files> Location (必要に応じて設定) .htaccessを使用せず、Basic認証したい場合に設定します。 <Location> ディレクティブは、 URL により中に書かれたディレクティブの適用範囲を制限します。 こちらを参考通りにするとBasic認証できます。 httpd.confファイルの詳細を知りたい方はこちら Apacheの起動 apacheを起動します。 コマンドプロンプトを起動後、2つのコマンドを実行し、 The 'Apache2.4' service is successfully installed.と表示されていれば、インストール完了と判断してよいです。 cd \Apache24\bin httpd.exe -k install C:\Users\Administrator>cd \Apache24\bin C:\Apache24\bin>httpd.exe -k install Installing the 'Apache2.4' service The 'Apache2.4' service is successfully installed. Testing httpd.conf.... Errors reported here must be corrected before the service can be started. Port must be specified C:\Apache24\bin> apahceの起動停止等のコマンドはこちらです。 >cd \Apache24\bin >httpd.exe -k start # Apacheの起動 >httpd.exe -k stop # Apacheの停止 >httpd.exe -k restart # Apacheの再起動 >httpd.exe -k uninstall # サービス解除 コマンド以外からのapacheの起動方法 C:\Apache24\binのApache Monitorを起動すると、右下の常駐アイコンに表示されます。 下記のapacheのアイコンをクリックすると、startが表示されますので、クリックすると、起動できます。 赤は停止、緑は起動中です。 apacheのindex.htmlをweb上で表示させる Windowsサーバーのセキュリティーグループは、httpを開けておりますが、Windowsサーバー内で、ポートの開放をが必要なのでやっていきましょう。 以下の参考記事の外部のWEB公開を参考にするとうまくいきます。 これで、外部に公開できましたので、WindowsサーバーのIPアドレスをブラウザのURL欄に入れて、アクセスしましょう。 It works!と表示されればOKです。 次回、PHPをインストールします。
- 投稿日:2021-12-05T00:00:05+09:00
Lambda サブスクリプションフィルター + AWS WAF で実現する「フルリモートワーク時代のお手軽社内サイト」
本記事は AWS LambdaとServerless Advent Calendar 2021 の4日目です。 たまたま空きがあることに気付いたため、せっかくでしたらと急遽参加させていただきます! よろしくお願いいたします ? こんにちは。Togetter を運営しているトゥギャッター株式会社でエンジニアをしている @MintoAoyama です。 Togetter はツイートを始めとした様々な情報を組み合わせてコンテンツを作り出すキュレーションサービスです。 2009年に誕生してから今年で13年目に突入し、現在も月間PV約1億、月間UU約1500万という規模感で成長を続けています。 そんなトゥギャッター社もコロナ禍に入り、全従業員がフルリモートワーク体制に移行しました。 もっとも、以前からリモートワークは実施されていました。オフィスは東京ですが地方からフルリモートで出勤されているメンバーも多く、エンジニアは基本週に一度リモートワークを実施する試みが行われていました。 コロナ禍でもトゥギャッター社のリモートワーク、うまくいってます|Togetter(トゥギャッター )|note(2020年5月の記事) コロナ禍以前から実施してきた弊社の"リモートワーク遍歴"を振り返る|Togetter(トゥギャッター )|note(2020年11月の記事) しかし、全ての従業員・全ての職種で完全なフルリモートワークに移行し始めたところ(2020年2月 - )、想定が及んでいない課題が出てきました。社内サイト・ドキュメントへのアクセス権限です。 意外にも色々あった "社内限定リソース" 弊社ではグループウェアとして Google Workspace (旧 G Suite) を活用しています。また、ソースコードやチケット管理ツールとして GitHub 、コミュニケーションツールとして Slack も活用しています。 これらについては以前から2FA(2段階認証)設定も義務化しているくらいで、フルリモートワークにあたって特別障壁になるものはありませんでした。 ただし、それ以外の手段で社内ネットワーク向けに限定公開しているリソースも存在していました。 社内向けドキュメント(Webサイト) 静的サイトジェネレーターで生成される 開発者向けとして別サイトもある "CloudFront" すごい便利な社内ツール(Webアプリケーション) "ALB" 検証環境・ステージング環境(Webアプリケーション) "ALB" 開発用データベースのためのデータ(MySQL の Docker DataVolume / sqldump) "CloudFront" 各種環境へのssh踏み台サーバ "EC2" (ざっと思い出した限りこのあたりです。他にもあるかもしれません。) 上記に関してはすべてIPアドレス制限を行っていました。 まず「オフィスネットワークのIPアドレスを許可」し、「社外からのアクセスを必要とする際は都度申請してもらい、私の方で手動で許可」していました。 ただ、「申請の際には自身でIPアドレスを調べて貰う」必要がありましたし、「プロバイダなど通信環境によってはIPアドレスが頻繁に変わる」可能性もあり、お互いの負担になっていました。また、「退社などを想定した定期的な棚卸し」も課題になります。 …それらが全従業員のフルリモートワーク移行により、ほぼキャパオーバーになったというわけです ? 普通に考えてこれらを個別申請・手動で管理すること自体が非合理的ですよね…。 何らかの形で仕組みを見直す必要がありました。 様々な従業員の環境からスムーズにアクセスしてもらうために 皆さんならどうするでしょうか…。 ドキュメントであれば Google Drive や GitHub Wiki に移行するという手もありそうです。 しかし、それだけでは賄えないリソースもあります。Webサイト(Webアプリ)でないと満たせない要件もありました。IPアドレス認証が必要なリソースもあります。 Digest認証も一瞬検討しましたし、GoogleアカウントやIAMなどを利用した認証手段がないかなども考えました。しかしいずれにせよ課題があり(全ての従業員・関係者が対象のアカウントを持っているわけではなかったり)、あまり明解ではありませんでした。 ※ SSO / OIDC / VPN など、よりベターな認証手段があることは把握していますが、今回は従来のIPアドレス認証を "拡張" しようという "お手軽" な手段を取っています ? と、ここで、そもそも 本番プロダクト(Togetter)のための管理画面 があることを思い出しました。記事情報の閲覧やフラグ管理、本番バッチの実行状況の確認など、本番データの参照・操作に利用されている仕組みです。当然Webアプリ内で認証しており、全従業員が日々ログインしています。 つまり、「認証後であれば正常にアクセスできるパスがある」ということです。 Lambda サブスクリプションフィルター で実現できるIPアドレスによるアクセス制御 Webサーバ(nginx)のアクセスログは json 形式で CloudWatch Logs に送っています。 特定のパス(認証を必要とするパス)に status=200 でアクセスしているIPアドレスが分かれば、それをホワイトリストとして扱えそうです。 CloudWatch Logs には「サブスクリプションフィルター」という機能があり、るログデータを Kinesis / Lambda / Kinesis Data Firehose に送信できます。 CloudWatch Logs サブスクリプションフィルターの使用 - Amazon CloudWatch Logs Lambda であれば、対象のIPアドレスをWAFに登録する処理を実装できそうです。 なお、サブスクリプションフィルタにはフィルターパターンを設定して、特定の条件に当てはまるログのみを送信対象として絞り込めます。 Lambda を実行する場合、その 実行回数 = 利用料金 にも影響するため、極力条件を付けることをオススメします。 フィルターとパターンの構文 - Amazon CloudWatch Logs 以下の例は、GETリクエストで status=200 で 管理画面配下(例: /adm/*) にアクセスできたリクエスト、みたいな感じです。 { $.request_method = "GET" && $.status = "200" && ( $.request_uri = "/adm/*" } WAFを定期更新できれば CloudFront や ALB に関連付けしてアクセス制御できますし、セキュリティグループを更新すれば ssh など他のポートも制御の対象になります。 今回、個人的にとっつきやすいRubyで実装してみました ✋ 以下、受け取ったログデータを取り出す簡単な実装例です。 require 'base64' require 'json' require 'zlib' def lambda_handler(event:, context:) # base64エンコードされているデータをデコードする decoded_data = Base64.decode64(event['awslogs']['data']) # バイナリ圧縮されているログデータを展開する json_data = Zlib::Inflate.new(Zlib::MAX_WBITS + 16).inflate(decoded_data) data = JSON.parse(json_data) # ログデータを1件ずつループ処理 # ここではとりあえずIPアドレスとリクエストパスを出力している for log in data['logEvents'] do access_log = JSON.parse(log['message']) remote_addr = access_log['remote_addr'] p "remote_addr = #{remote_addr}" request_uri = access_log['request_uri'] p "request_uri = #{request_uri}" end end CloudWatch Logs から送信されてくるログデータは base64エンコード + gzip圧縮 されているためそれらに対する処理が最初に必要になりますが、後は配列上になっているので1件ずつ処理します。 WAFのIPアドレスリスト(IP addresses)の更新には AWS SDK 、Ruby であれば Aws::WAF::Client クラス を使います。なお、 WAFv2 であればこれで良いですが、 旧バージョンの WAF(AWS WAF Classic)を対象としたい場合は Aws::WAFRegional::Client クラスを使う必要があります。地味な罠になっていますのでご注意ください…。 Class: Aws::WAF::Client — AWS SDK for Ruby V3 Class: Aws::WAFRegional::Client — AWS SDK for Ruby V3 以下、複数の対象IPアドレスを追加する簡単な実装例です。 require 'aws-sdk-waf' def update_ip_sets(ip_set_id, ipaddresses) waf_client = Aws::WAF::Client.new( region: region_name ) # 対象IPアドレスのリストから更新リクエスト内容を生成 # (今回は "IPv4" の "追加" としています) updates = [] ipaddresses.each do |ipaddress| updates.push({ action: 'INSERT', ip_set_descriptor: { type: 'IPV4', value: "#{ipaddress}/32" } }) end # 更新処理に必要なトークンを取得する waf_responce = waf_client.get_change_token({}) change_token = waf_responce.change_token # 更新 response = waf_client.update_ip_set({ change_token: change_token, ip_set_id: ip_set_id, updates: updates }) end なお、実装にあたっては考慮すべきポイントが色々出てきます。 WAFのIPアドレスリスト(IP addresses)にはサイズ制限がありますし、先ほど書いたように登録されたIPアドレスはその性質上永続的に保存するものではなく、定期的な棚卸しが必要になります。 そこで、「それぞれのIPアドレスの登録日時を記録し、一定期間が経過したものを削除する」などの処理を入れたりします。 記録用のデータストアとしては通常 DynamoDB などを使うかと思いますが、今回は規模感なども踏まえ、お手軽に Parameter Store (AWS Systems Manager) を利用してみます。 AWS Systems Manager Parameter Store - AWS Systems Manager Parameter Store は 階層型のパラメータに対して値を格納できるKVSのようなサービスです。「スタンダード」の条件を満たせば無料(大体の場合はこれで必要十分なはずです)。 バージョニングにも対応している上、Lambdaからの読み書きが可能。1秒間に最大1,000件のアクセスにも耐えられるスケーラビリティを備えているため、簡易的なデータストアとして重宝する仕組みでもあります。用途次第ですが、使わないと損?かもしれません。 Class: Aws::SSM::Client — AWS SDK for Ruby V3 以下は Parameter Store の読み書きをする簡単な実装例です。 require 'aws-sdk-ssm' def ssm_sample() ssm_client = Aws::SSM::Client.new # 追加(更新) res = ssm_client.put_parameter({ name: 'test', value: 'aaa', type: 'String', overwrite: true }) # 取得 res = ssm_client.get_parameter({ name: 'test', with_decryption: false }) p res.parameter.value end 詳細は割愛しますが、例えば json で「"IPアドレス" と "登録日時" の組み合わせ配列」を定義・保存するよう実装してみたりします。 スタンダードの場合は保存できるデータサイズの上限が 4,096 byte なので、超えないように注意する必要もあります。 ということで、ひとまず合理的な形で制御できるようになりました。 今回は少し特殊なケースかも知れませんが、サブスクリプションフィルターはログ1行1行に対してほぼリアルタイムで処理できるため、様々な用途が考えられると思います。 ご存じなかった方は是非ご活用ください ???