- 投稿日:2019-07-10T23:05:09+09:00
TerraformerのためのTerraformer
Terraformerというツールを最近見つけて、
「えぇ!!めちゃ便利やん!!」と少々感動したのでご紹介します。Terraformer
現存しているリソースの
.tf
ファイルとtfstate
を自動作成してくれるCLIツールです1。
レポジトリはこちら。インストール
Homebrewでインストールできます。
brew install terraformer
その他のインストール方法はこちら。利用する前にディレクトリ(
~/.terraform.d/plugins/{darwin,linux}_amd64/
)を作成し、ここにプロバイダをインストールしておく必要があります。$ pwd /Users/<user-name>/.terraform.d/plugins/darwin_amd64 $ wget https://releases.hashicorp.com/terraform-provider-google/2.10.0/terraform-provider-google_2.10.0_darwin_amd64.zip $ unzip terraform-provider-google_2.10.0_darwin_amd64.zip使い方
以下プロバイダとしてGCPを利用した例です。
AWSなど他のプロバイダについても似たような感じだと思います(未検証)。指定したリソースのファイルを作る
コマンド一つで楽ちん。
--resources
オプションで、.tf
ファイルとtfstate
を作成したいリソースの指定します。terraformer import google --resources=cloudFunctions --zone=asia-northeast1-a --projects=<your-project-id>複数選択することで、一気に作れます。プロジェクトも複数選択できます。
terraformer import google --resources=cloudFunctions,gke,gcs,instances --zone=asia-northeast1-a --projects=<project-A>,<project-B>作成された
.tf
ファイルとtfstate
は./generated/<provider>/<project-name>/<resources>
にあります。ローカルにファイルを作成する前に確認したい
import
の代わりにplan
を使います。terraformer plan google --resources=cloudFunctions --zone=asia-northeast1-a --projects=<your-project-id>すると
./generated/<provider>/<project-name>/terraformer
にplan.json
というJSONファイルが作成されるので、ここから確認ができます。必要であればJSONファイルを変更して、
.tf
ファイルを作成します。terraformer import plan ./generated/<provider>/<project-name>/terraformer/plan.jsonメリット/デメリット
個人の感想です。ツッコミがあればコメントをいただきたいです。
メリット
コードを書かなくていい
自動作成されるので、無論書く必要がないです。
フォーマットが一定なので見やすい
人が書くコードでは、デフォルトの設定として書かれないような設定も書いてくれるので、
リソース単位でコードを読む分には読みやすいと感じました。デメリット
生成されるコードが0.12に対応していない
terraform 0.12upgrade
でほとんど対応できると思いますし、これから置き換えられるような気がします(issue)。リソースごとなので、依存を意識してリソースを立てる必要がある
.tf
ファイルが作成された後の話です。ここでようやく頭を使うので、許容範囲かとも思います。終わりに
issueを見てみると、IAMやAWSのリソースについても開発が進んでいるようで、これからもっと便利になりそうです。
参考
reverse Terraformというらしい。この言葉、使っていきたい。 ↩
- 投稿日:2019-07-10T21:35:41+09:00
ほとんどアクセスのない個人開発サービスがAWSに月額いくら払っているか全て公開します
はじめに
「AWSって結局いくらかかるの?」
これが結構見積もりが難しい問題で、ざっくりAWSのようにざっくり見積もれるサービスが登場したのはその見積もりの難しさから来ていると思う。個人的に開発しているwebサービスをAWSで公開してからしばらくたって、月の料金が安定しているので、ここで公開してみる。
しょっぼいwebサービスを公開したいけど、AWSだといくら掛かるのかなー?という方に向けて書いているので、「herokuなら無料だぜ!もしくは7ドルだぜ!」とかいう話ではないです。
サービス概要
公開したサービスはこちら。
https://uwaoe.nethtml5のcanvas機能を利用してブラウザ上でお絵かきすることができて、他の人が描いた絵にうわがき(というか落書き)することができる。
サーバはRuby on Rails、フロントはVue.jsで作った。利用ユーザは2人。
たった2人!!
これはストレージ的にもアクセス数的にも安上がり!!!料金内訳
AWSコンソールのコストエクスプローラから、半年間の支払い金額を取得した。
EC2 ELB EC2 インスタンス EC2 その他 税金 Route 53 S3 CloudFront 合計 2019-01-01 18.08 11.31 3.60 2.68 0.50 0.02 0.01 36.20 2019-02-01 16.33 10.21 3.60 2.46 0.50 0.02 0.02 33.14 2019-03-01 18.08 11.31 3.60 2.68 0.50 0.02 0.01 36.20 2019-04-01 17.50 10.92 3.60 2.60 0.50 0.02 0.01 35.15 2019-05-01 18.08 11.31 3.60 2.68 0.50 0.02 0.01 36.20 2019-06-01 17.50 10.94 3.60 2.61 0.50 0.02 0.01 35.18 ※ 単位は$
※ 見易さのために少数第3位を四捨五入していますEC2 ELB
平均 $17.595(ドル円108円として約1900円)
EC2インスタンスは1台しか使ってないのだけど、ELBで簡単にhttpsを使いたかったので導入。
結構する。httpsにしたいだけなので、Let's Encryptとか使ってEC2に直接証明書をインストールしたほうが安上がりだったかな。
初回12ヶ月間は1台分無料だけど、無料期間は切れているため課金。EC2 インスタンス
平均 $11.000(ドル円108円として約1188円)
インスタンスはt2.microが1台。t3ではない。
microインスタンスには、初回12ヶ月は1台分が無料というキャンペーンがあるんだけど、12ヶ月間の無料期間は過ぎているためお金がかかっている。EC2 その他
平均 $3.600(ドル円108円として約389円)
EBSの料金ぽい。
SSD30Gを使っているので計算は$0.12 * 30
。
空きがめっちゃあるのでもっと少なくてもいけそう。Route 53
平均 $0.500(ドル円108円として約54円)
uwaoe.net
のドメインを登録している。
リクエスト数で料金が上がるらしいが、現状やっすいので、金額的には気にならないレベル。S3
平均 $0.020(ドル円108円として約2円)
おえかきされた絵やアップロードされたユーザのアバターを保存している。
put系の書き込みリクエストが1000件、get系の取得リクエストが45000件、データ送料が 50MB程度なので大したことがない。
rails側で画像のサムネイルを何種類か作成してS3に上げたり、画像アップロード用のgemのshrineがキャッシュをS3に作りまくったりしているけど、軽い。
現状やっすいので、誤差レベル。関係ないけど、gem shrineはBase64エンコードされた画像を簡単に扱えるので、canvasの画像を扱いたい場合におすすめ。
Coundfront
平均 $0.012(ドル円108円として約1円)
t2.microサーバから画像配信するのは不安があったので、画像の配信にはCloudfrontを使用するようにした。
現状やっすいね。RDS
使ってない。
節約のためにEC2インスタンスにmysql-serverを入れちゃったのだけど、メモリが足りなくて辛い。
t2.microってメモリ0.5Gじゃん? mysqldがメモリを160MB使っていて、railsを動かしているpumaサーバが180MB使っている。その他サービスで使われているメモリもありで、デプロイを実行するメモリが足りない。デプロイする時、assets:precompile
のたびにメモリが足りなくてアプリケーションサーバが死ぬというカッコいい状態になっている。CloudWatch
使ってない。
別にサービスが何時間止まろうが困らないし・・。SES
使ってるけど0円。
月62,000件までは0円らしい。合計
平均 $35.345(ドル円108円として約3817円)
おわりに
月3800円。上で書いたようにALBが無駄っぽいので月2000円ぐらいまで節約できると思う。
今の所、広告や課金要素は全く無いので完全赤字になっているが、趣味として見たら安い。AWSには初回12ヶ月無料なことがいっぱいあって、1年間であれば次の構成が無料にできそう。
* EC2 microインスタンス1つ
* ALB 1つ
* RDS microインスタンス1つ新規に個人開発のサービス公開を目論んでいる方は、AWSもインフラの候補にしてみてはどうだろうか。
- 投稿日:2019-07-10T21:25:09+09:00
AWS Developer Associate 合格しました(2019/6)
AWS 3冠になりました
![]()
この度晴れて、アソシエイトの資格全てに合格することができました!
受験期間としては3月末〜6月末の約3ヶ月間です。
間で業務のためRailsにはまっていた時期もあったので実質3ヶ月かからないくらいだと思っています。AWS Developerアソシエイト試験に関して
その中でも今回はSysopsの反省を生かして一発で合格できたDeveloperアソシエイトに関してまとめようと思います。
一言でまとめると、、、
めっちゃ難しかった!!!
につきます。
Sysopsもかなり理解を問われる問題もありますが、問題改定を終えて肌感覚的な意見ですが3つで一番難しかったです。。
最後の最後まで不安なまま試験を終える形になってしまいました
アソシエイトの新試験の難易度は
Developer > Sysops > Solution Architect
の順になっているといっても過言ではありません。
得意分野は人それぞれなので一概には言えませんが、参考にしていただけたらと思います。
その中でDeveloperの勉強で行ったこと
今回も前回を踏襲して問題集を解きながら、Black Beltを三回づつくらい読みました。
問題集は自分に合うものでいいかと思いますが、私は英語の同じものを5回分を最低三回ずつは解いて95%以上取れるようになるまでやりました。
BlackBeltで特に読んだ方が良い資料
やはり開発者向けなので、基本こちらになります。他二つの知識はある前提です。
・ Codebuild ←特に重要
・ CodePipeline
・ CodeDeploy ←特に重要
・ CodeCommit
・ ElasticBeanstalk
・ Lambda ←特に重要
・ API Gateway ←特に重要
・ ElastiCache
・ DynamoDB ←特に重要
・ SQS
・ KMS
・ ECS
・ X-Ray ←特に重要
・ Step Functions上記は必須の知識になるかと思いますが、
これに加えて基本的なサービスの理解は必ず必要になります。基本的にほとんどの問題が複合された問題なので、丸覚えだと当たり前ですがほとんど模試の問題も出ないので理解しておくことが大切です。
わからない用語は調べて理解する
なぜそうなるのがAWSのベストプラクティスに則っているのか、常に自分に問いかけながら学習する
これを忘れなければきっとみなさまも合格できると思います!!
次はプロフェッショナルの取得(8月,9月)に向けて頑張ります
- 投稿日:2019-07-10T19:24:14+09:00
s3オブジェクト一覧取得(Go)
はじめに
S3バケットのオブジェクト一覧を取得する場合は通常awscliを使用して
aws --profile {profile} s3 ls --recursive s3://{bucket}/{prefix}
のような感じで実行すると思います。
オブジェクトが少なければこれで問題ないですが、大量にあると時間がかかります。
実際に特定prefix配下の(1億ほど)オブジェクト一覧を取得する必要があり、awscliだと
数日かかることが見えていたので、Goで実装してどれだけ速くなるか試してみました。コード
main.gopackage main import ( "flag" "fmt" "os" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" ) var ( argRegion = flag.String("region", "ap-northeast-1", "specify region name") argProfile = flag.String("profile", "", "specify credential profile name") argBucket = flag.String("bucket", "", "specify bucket name") argPrefix = flag.String("prefix", "", "specify object key prefix") ) func main() { flag.Parse() defer func() { if r := recover(); r != nil { flag.Usage() fmt.Println(r) os.Exit(1) } }() config := aws.Config{Region: argRegion, MaxRetries: aws.Int(10)} if *argProfile != "" { creds := credentials.NewSharedCredentials("", *argProfile) config.Credentials = creds } sess := session.New(&config) svc := s3.New(sess) params := &s3.ListObjectsV2Input{Bucket: argBucket, Prefix: argPrefix} jst, _ := time.LoadLocation("Asia/Tokyo") svc.ListObjectsV2Pages(params, func(page *s3.ListObjectsV2Output, lastPage bool) bool { for _, obj := range page.Contents { fmt.Printf("%s %10d %s\n", obj.LastModified.In(jst).Format("2006-01-02 15:04:05"), *obj.Size, *obj.Key) } return *page.IsTruncated }) }実行方法
# コンパイル go build -o s3lsall main.go # 実行 ./s3lsall -profile {profile} -bucket {bucket} -prefix {prefix}結果表示は、awscli(
aws s3 ls
)と同じフォーマットで出力されます例2019-01-22 11:46:39 8023 hoge/197352643.json 2019-01-23 11:16:28 5000 hoge/197512582.json 2019-01-23 19:46:02 4995 hoge/197512839.json
性能比較(参考)
t3.smallインスタンスで実行し、10万オブジェクトの一覧取得で比較
使用ツール 所要時間 CPU使用率 awscli 65秒 30% s3lsall(go実装) 15秒 10% まとめ
awscliで時間がかかりそうな大量リソースに対する処理などは、必要な処理に特化した
プログラムをGoでサクッと実装するとよさそうですね(速度/負荷的にも)Go以外の言語でsdkを使ってプログラムを書いてもいいですが、そのランタイム環境を用意
しないといけないので、ワンバイナリ配布で実行できる、というのもGoのいいところですね!
- 投稿日:2019-07-10T19:06:31+09:00
.envのCredentialsでboto3を使う
動機
.env
にAWSのCredentialsを記述してs3からファイルをダウンロードしたい。前提
pipenvをつかってpython環境を構築する。
手順
準備
.env
を作成してアクセストークンなどを入力する。AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=yyy読み込み
.env
を作成したら仮想環境を作成、立ち上げる。$ pipenv install boto3 $ pipenv shell仮想環境を立ち上げると
.env
を自動で読み込み環境変数に設定できる。
スクリプト中ではos
モジュールから環境変数にアクセスする。# REPLを立ち上げ >>> import os >>> os.environ['AWS_ACCESS_KEY_ID'] 'xxx'ファイルダウンロード
client = boto3.client( 's3', aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'], aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'] ) client.download_file(AWS_S3_BUCKET_NAME, s3_key, file_path)管理
.env
はgitで管理せずに.gitignore
に追加する。
かわりに値を空白にした.env.sample
をgitで管理しておく。
- 投稿日:2019-07-10T15:23:11+09:00
Session ManagerでSCPとかSSH Portforwardもできる!
何の話?
以前、うちのエンジニアの人たちに、EC2に接続するときはSSHやめて、セッションマネージャーすすめてみたんですが、SSHでのターミナルだけでなく、SCPでのファイルコピーとか、インスタンス内でサービス立ち上げてアクセスするためにPortforwardとか頻繁に使うってことであまりセッションマネージャーは使っていなかったんですが・・・
こんなアナウンスが。
Session Manager launches tunneling support for SSH and SCPこれはもしや!
セットアップ
クライアント側
セッションマネージャープラグイン
1.1.22.0
が必要なのでアップデートしましょう。
https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html$ session-manager-plugin --version 1.1.23.0SSH Config
~/.ssh/config
に下記を追加します。~/.ssh/config# SSH over Session Manager host i-* mi-* ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
i-*
はインスタンスIDを指定したとき、mi-*
はオンプレのサーバをSSMで管理している場合に使うIDです。
つまり、インスタンスIDに対してSSHアクセスしたときには、ssmでトンネル張って、その中をSSH接続するということですね。EC2インスタンス側
SSMエージェント
2.3.672.0
以上が必要ですのでRunCommandでアップデートしてください。EIP
SSM使うので不要です。
セキュリティグループ
もちろん外部からのSSHへのアクセス許可は不要です。
SSH Key
前述のとおり、セッションマネージャーのトンネル内でSSH接続するので、keyの付与は必要になります。
ない場合、SSHの鍵が違う場合はこんな感じ。Permission denied (publickey,gssapi-keyex,gssapi-with-mic).なので、EC2にsshdは必要ってことですね。
接続
普通にSSH
普通にSSHコマンドでインスタンスID指定して接続できました。
$ ssh ec2-user@i-xxxxxxxxxxxxxxx -i ~/.ssh/id_rsa ast login: Wed Jul 10 03:23:25 2019 from localhost __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/ No packages needed for security; 6 packages available Run "sudo yum update" to apply all updates. [ec2-user@ip-10-0-1-104 ~]$おお!
普通にOSのユーザーで使えますね。トンネル張ってるので、ログ的にはlocalhostから接続されていることになってます。
/var/log/secureJul 10 03:08:19 ip-10-0-1-104 sshd[4173]: Accepted publickey for ec2-user from 127.0.0.1 port 49148 ssh2: RSA SHA256:aHEcVcQEixW0amxNSFVjabsst2Jglm7KDbYr+Tyb3Zjko Jul 10 03:08:19 ip-10-0-1-104 sshd[4173]: pam_unix(sshd:session): session opened for user ec2-user by (uid=0) Jul 10 03:08:38 ip-10-0-1-104 sshd[4207]: Received disconnect from 127.0.0.1 port 49148:11: disconnected by user Jul 10 03:08:38 ip-10-0-1-104 sshd[4207]: Disconnected from 127.0.0.1 port 49148 Jul 10 03:08:38 ip-10-0-1-104 sshd[4173]: pam_unix(sshd:session): session closed for user ec2-user Jul 10 03:14:29 ip-10-0-1-104 sshd[4253]: Accepted publickey for ec2-user from 127.0.0.1 port 49216 ssh2: RSA SHA256:aHEcVcQEixW0amxNSFVjJyt2Jglm7KDbYr+Tyb3Zjko Jul 10 03:14:29 ip-10-0-1-104 sshd[4253]: pam_unix(sshd:session): session opened for user ec2-user by (uid=0) Jul 10 03:14:35 ip-10-0-1-104 sudo: ec2-user : TTY=pts/0 ; PWD=/home/ec2-user ; USER=root ; COMMAND=/bin/tail /var/log/secureSCPしてみる
$ scp test.txt ec2-user@i-xxxxxxxxxxxxxxx:test.txt test.txt 100% 191 11.2KB/s 00:00 $ ssh ec2-user@i-xxxxxxxxxxxxxxx ls test.txtおおお!
SSH PortForwardしてみる
$ ssh ec2-user@i-xxxxxxxxxxxxxxx sudo yum -y install httpd $ ssh ec2-user@i-xxxxxxxxxxxxxxx sudo systemctl start httpd $ ssh -fNL 8080:localhost:80 ec2-user@i-xxxxxxxxxxxxxxx $ curl -I localhost:8080 HTTP/1.1 403 Forbidden Date: Wed, 10 Jul 2019 03:24:08 GMT Server: Apache/2.4.39 () Upgrade: h2,h2c Connection: Upgrade Last-Modified: Thu, 04 Apr 2019 18:08:00 GMT Accept-Ranges: bytes Content-Length: 3630 Content-Type: text/html; charset=UTF-8おおおお!!!
残念ながら・・・
セッションマネージャーには出力をS3や、CloudWatch Logsに送信する機能がありますが、この接続の場合は出力されないようです。
出力はSSHになるので当然かもしれないですが・・・まとめ
今度こそSSHするためのアクセス許可は考えなくていいことになりそう!
- 投稿日:2019-07-10T13:59:51+09:00
Amazon Personalizeを導入してわかった12のこと
はじめに
私の所属しているエイチームグループでは「サイマ」という自転車のECサイトを運営しているのですが、先日レコメンデーションエンジンとしてAmazon Personalizeを導入しました。サービスに導入しようとすると少し触っただけではわからなかったことが見えてきたので、Amazon Personalizeを導入する過程でわかったことをつらつらと書きだしてみました。
この記事を読む前提知識として、Amazon Personalizeの全体像を把握していたほうが良いです。Amazon Web Servicesブログの以下の記事が図解もあって個人的にはわかりやすいと思います。
- Amazon Personalize を使用してレコメンドエンジンを作成する
https://aws.amazon.com/jp/blogs/news/creating-a-recommendation-engine-using-amazon-personalize/Amazon Personalizeを導入してわかった12のこと
ソリューションとキャンペーンに関して
1. 良いデータの持ち方は試行錯誤して探る必要がある
- トレーニングに使うデータの持ち方(スキーマ)を任意に決められるのですが、どういう持ち方をすれば良い結果になるかわかりません。
- Amazon Personalizeがどういう学習をしているかわからないこともあり、良い結果を出すためには下記のような手順を繰り返す必要があります。
- データの持ち方を変更する
- キャンペーンを作成する
- メトリクスを確認する
- データ量が多ければ良いというものではなくて、1年分の履歴を使った時より3か月分の履歴を使ったときのほうが良いメトリクスになるなんてことも発生しました。
2. 商品情報のスキーマのcategorizeは設定したほうが良い
商品情報のスキーマには「categorical」というオプションがあって、カテゴリ分けに使う項目に設定しておくと同一カテゴリの商品がレコメンドに出やすくなります。
{ "name": "GENRE", "type": "string", "categorical": true }3. 個人別レコメンドを使ったほうが良い結果になる
商品別レコメンド(レシピはSIMS)と個人別レコメンド(レシピはHRNN-METADATA)で下記のようにレコメンドのメトリクスに差がつきました。なお、下記のメトリクスの指標は2種類とも1に近いほど良好なものです。
レシピ Normalized discounted cumulative at 25 Mean reciprocal rank at 25 SIMS 0.3665 0.2306 HRNN-METADATA 0.5559 0.3725 サイトへの導入成果ではクリック率・コンバージョン率ともにHRNN-METADATAがSIMSの1.8倍近くになりました。
4. Auto MLを使える場合は使ったほうが良い
同じレシピでAuto MLを使ったソリューションとそうでないソリューションを比較すると下記のようにAuto MLのほうが良いメトリクスになりました。
レシピ Normalized discounted cumulative at 25 Mean reciprocal rank at 25 HRNN-METADATA(Auto MLあり) 0.5559 0.3725 HRNN-METADATA(Auto MLなし) 0.5149 0.3432 Auto MLを使わない場合は学習に使うパラメータを手動で設定して良い結果になるように調整する必要があります。
ただ、現状ではAuto MLはHRNNとHRNN-METADATAの2つのレシピしか選択できません。
5. キャンペーンのMinimum provisioned TPSは重要
- キャンペーンにMinimum provisioned TPSという設定項目がありますが、これは料金とスピードにかかわる重要な設定です。
- TPSはtransaction per secondの略で、Minimum provisioned TPSは1秒間に何回レコメンドを取得できるようにするのかという設定です。
- ここに設定した値が1時間あたりの最低料金になります。
- 1 TPSあたり0.2USDが基本料金で、Minimum provisioned TPSを5にすると1時間1USD、10にすると1時間2USDが最低料金としてかかるといった具合です。
- 1時間あたりの金額なので、「1時間あたりの金額×24時間×1か月の日数」が1ヶ月分の料金としてかかります。
- 1秒間にこの数値を超えるアクセスがあった場合、レコメンド情報の取得に遅延が発生します。
- 同じような状況が継続すると1時間あたりの料金もその分増えます。
- つまり、この数値が高ければ余分な料金、低ければ表示の遅延が発生します。
サイトへの組み込みに関して
6. 最低限必要なAPIは3つだけ
- APIリファレンスを見るとたくさんのAPIが並んでいますが、通常の利用で必要なものは以下の3つだけです。
- GetRecommendations
- レシピタイプがRELATED_ITEMSもしくはUSER_PERSONALIZATIONのキャンペーンでレコメンド情報を取得する
- GetPersonalizedRanking
- レシピタイプがSEARCH_PERSONALIZATIONのキャンペーンでレコメンド情報を取得する
- PutEvents
- ユーザーの行動をレコメンドに反映する(イベントトラッカー)
- 他のAPIはAWSコンソールから行うレコメンドの設定をプログラムから実行したい場合に使います。
7. 個人別レコメンドの引数に商品IDを渡しても結果が変わらない
- 個人別レコメンドはユーザーIDだけに基づいてレコメンドを行っているようで、レコメンド情報を取得するAPIに商品IDを渡しても結果が変わりません。
- そのため、商品ページに個人別レコメンドを表示する場合はユーザーの行動履歴に閲覧した商品を反映した後にレコメンド情報を取得するようにしないと、ひとつ前の商品を見たときのレコメンド結果が商品ページに出てしまいます。
- 上記の問題を回避するために、レコメンドの表示は遅延ロードするようにしました。
- 商品ページを表示した段階でイベントトラッカーを呼び出し、行動履歴に商品ページの閲覧を反映する
- レコメンドの表示する場所までスクロールしたときにAjaxでレコメンド情報を取得して表示する
8. レコメンドの効果を確認できる仕組みを作ったほうが良い
- Amazon PersonalizeにはASPのレコメンデーションエンジンのようなレコメンドの効果測定機能がありません。
- そのため、レコメンドのクリック率やコンバージョン率が把握できるように効果測定の仕組みは作っておいたほうが良いです。
9. 型の違いに注意が必要
- スキーマの設定でデータ型を指定できるのですが、Amazon PersonalizeのAPIは型を区別します。
- APIを呼び出すときはintで定義したスキーマには数値型の値、stringで定義したスキーマには文字列型の値を渡すことが必要です。
10. レコメンド情報をまとめて取得すると料金が高くなる
- 料金体系上、短時間にレコメンド情報の取得が集中するとその時間の料金が高くなります。
- そういった状況としてはメールマガジンの送信時に多数のユーザーのレコメンド情報をまとめて取得するケースなどが考えられます。
- レコメンド情報を取得するAPIの所要時間は私の環境だと1回あたり50〜100ミリ秒くらいでしたので、秒間10回以上APIを呼べそうでした。
- Amazon PersonalizeでAPIの実行回数の上限は設定できないため、料金が気になるようであればAPIの実行回数が多くなりすぎないようにする仕組みを入れたほうが良いです。
導入後の運用に関して
11. 最新の情報に基づいてレコメンドをするためには再トレーニングが必要
- Amazon Personalizeには商品情報や会員情報をリアルタイムでソリューションに反映する仕組みがありません。
- そのため、最新の情報に基づいてレコメンドするためにはトレーニングに使うCSVを改めてアップロードして、ソリューションの新しいバージョンを作成する必要があります。バージョンの作成はソリューションの画面から実行できます。
![]()
- トレーニング時間に料金がかかるるため、料金の見積もりではこの点も計算に反映したほうが良いです。
12. アクセス数に合わせてキャンペーンのMinimum provisioned TPSを調整したほうが良い
- 4で挙げたようにMinimum provisioned TPSは高くても低くても良くないので、アクセス数に合わせて調整したほうが良いです。
- Minimum provisioned TPSはキャンペーン情報を更新するAPIから変更できるため、アクセスログに基づいて自動で調整するようなことも可能です。
最後に
Amazon Personalizeは世の中に導入事例やノウハウがまだ少ないのですが、ポイントを押さえれば導入は難しくありません。手探りだった私達のケースでも30人日程度の工数で導入できました。
また、Amazonのレコメンドと同じアルゴリズムを使っているだけのことはあって導入効果もしっかりと出ています。
この記事が導入を考えている人の参考になればうれしいです。参考資料
サイト URL Amazon Personalize https://aws.amazon.com/jp/personalize/ Amazon Personalize 開発者ガイド https://docs.aws.amazon.com/ja_jp/personalize/latest/dg/what-is-personalize.html Amazon Personalize を使用してレコメンドエンジンを作成する https://aws.amazon.com/jp/blogs/news/creating-a-recommendation-engine-using-amazon-personalize/
- 投稿日:2019-07-10T13:58:41+09:00
Session Manager で SSH/SCPをトンネリングしてEC2に接続する
はじめに
2019/7/9 に AWS Systems Manager Session Manager が SSHおよびSCP接続の
トンネリングをサポートしました。
これにより、踏み台サーバー等を使用せずに、Session Manager を介して対象のEC2や
マネージドインスタンスに接続することが可能になります。Session Manager launches tunneling support for SSH and SCP
https://aws.amazon.com/about-aws/whats-new/2019/07/session-manager-launches-tunneling-support-for-ssh-and-scp/やってみる
AWS Systems Manager 自体の説明は割愛させていただきます。
サーバー側の要件
SSM Agentのバージョンが 2.3.672.0 以上である必要があります。
バージョンが古い場合は、Systems Managerの Run Command を使用して
最新版にアップデートします。コマンドの履歴でアップデートが正常終了していることを確認します。
クライアント側の要件
AWS CLI のバージョンが 1.16.12 以上である必要があります
その他に Session Manager Plugin のバージョンが 1.1.22.0 以上である必要があります$ aws --version aws-cli/1.16.195 Python/3.6.0 Windows/10 botocore/1.12.185 $ session-manager-plugin --version 1.1.23.0バージョンが古い場合は以下のドキュメントに沿って最新版をインストールします。
(Optional) Install the Session Manager Plugin for the AWS CLI
https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.htmlまた使用するSSHクライアントが ProxyCommand をサポートしている必要があります。
私の環境はWindowsでしたので、OpenSSH + Git Bash を使用しました。
SSH の設定ファイル(~/.ssh/config)に以下の内容を追記します。
SSHコマンドで接続先ホスト名が i-(EC2インスタンス) または mi-(マネージドインスタンス)で
はじまる場合は aws ssm start-session コマンドを実行するという内容になっています。# SSH over Session Manager host i-* mi-* ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"IAM ユーザーの要件
最低限、以下のドキュメントで紹介されているポリシーに記載された権限が必要となります。
Quickstart Default IAM Policies for Session Manager
https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-restrict-access-quickstart.html接続する
SSHコマンドを実行する際にホスト名にインスタンスIDを指定すると以下のようにSSHで接続できます。
$ ssh -i ./my-key.pem ec2-user@i-0123456789abcdefg Last login: Wed Jul 10 02:56:56 2019 from localhost __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/ [ec2-user@ip-172-31-20-75 ~]$Session Manger と SSM Agent を介して接続しているためだと思われますが、
接続元はlocalhost(127.0.0.1)になっています。[ec2-user@ip-172-31-20-75 ~]$ sudo tail -3 /var/log/secure Jul 10 04:26:20 ip-172-31-20-75 sshd[9269]: Accepted publickey for ec2-user from 127.0.0.1 port 41360 ssh2: RSA SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxx Jul 10 04:26:20 ip-172-31-20-75 sshd[9269]: pam_unix(sshd:session): session opened for user ec2-user by (uid=0) Jul 10 04:31:50 ip-172-31-20-75 sudo: ec2-user : TTY=pts/0 ; PWD=/home/ec2-user ; USER=root ; COMMAND=/bin/tail -3 /var/log/secureメリット
セキュリティグループでSSHを許可する必要がない
SSM Agent を介して通信するため、EC2としてはアウトバウンド通信でSSMのエンドポイントと
通信できればよいです。そのためセキュリティグループのインバウンドルールで
SSHのポートを開けておく必要がありません。
最近利用可能になった EC2 Instance Connect では EC2 Instance Connect が利用する
IPアドレス範囲 をセキュリティグループに明示的に追加する必要があります。SCPも利用できる
Systems Manager のシェルセッションでは仕組み上、SCPの転送には対応できていませんでした。
この機能を使うとSCPによるファイル転送を行うことができます。$ scp -i ./my-key.pem ./test.txt ec2-user@i-0123456789abcdefg:/tmp/test.txt test.txt 100% 769 38.0KB/s 00:00対応OSの幅が広い
EC2 Instance Connect は 2019/7/9 時点 で対応OSが限られています。
- Amazon Linux 2(任意のバージョン)
- Ubuntu 16.04以降
Session Managerを使用したSSH接続の場合、SSM Agent をインストール可能な
以下のLinux環境であれば利用することができます。
- Amazon Linux and Amazon Linux 2
- Ubuntu Server
- Red Hat Enterprise Linux (RHEL)
- CentOS
- SUSE Linux Enterprise Server (SLES) 12
- Raspbian
Manually Install SSM Agent on Amazon EC2 Linux Instances
https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-manual-agent-install.htmlまたSystems Managerを利用して管理されているオンプレミスの
マネージドインスタンスに対しても利用可能です。
ただしAdvanced-Instances Tierで登録されている必要があります。Step 7: (Optional) Enable the Advanced-Instances Tier
https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-managedinstances.html参考
Step 7: (Optional) Enable SSH Session Manager Sessions
https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.htmlStarting a Session (SSH)
https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-sessions-start.html#sessions-start-sshEC2 Instance Connect の特徴や注意点についてまとめてみる
https://qiita.com/hayao_k/items/7b44ed1cd11651272985以上です。
参考になれば幸いです。
- 投稿日:2019-07-10T13:32:48+09:00
サーバレスで静的Webサイトをホスティング&自動デプロイする(CloudFront+ACM+Route53+S3+CodePipeline+Github)
やりたいこと
AWSのCloudFront+ACM+Route53+S3を利用し、サーバレスで静的Webサイトをホスティングする。
※WebサイトのソースはS3に配置する。
※AWS以外のサービスで取得した独自ドメインをRoute53に設定する。
※S3単体だとHTTPSは利用できないため、CloudFront&ACMを利用する。
※以下のURLでのアクセスを想定。HTTPはHTTPSにリダイレクトさせる。
https://xxxx.com
https://www.xxxx.com
AWSのS3+CodePipelineとGithubを利用し、自動デプロイ環境を構築する。
構成イメージ
手順(サマリー)
- S3のバケットを作成する
- CodePipelineを利用し、S3とGithubを連携する(自動デプロイ)
- S3で静的Webサイトをホスティングする(外部公開する)
- Route53に独自ドメインを登録する
- ACMで証明書を作成する
- CloudFrontのDistributionを作成する
- CloudFront向けに独自ドメインを設定する
- 動作確認(全体)
手順(詳細)
1. S3のバケットを作成する
静的WebサイトをホスティングするためのS3のバケットを作成する。
名前とリージョン
バケット名:
www.xxxx.com
※バケット名=FQDNとして設定すること。
リージョン:お好みで。
オプションの設定
アクセス許可の設定
確認画面
2. CodePipelineを利用し、S3とGithubを連携する(自動デプロイ)
CodePipelineを利用し、GitHub上のソースをS3に自動的にデプロイする。
パイプラインを作成する
パイプラインの基本設定
基本的にデフォルトでOK。パイプライン名はわかりやすいものなら何でもOK。
ソースステージを追加する
GitHubを選択すると設定項目が現れるので、「GitHubに連携する」ボタンを押下する。
GitHubの認証ポップアップが表示されるので、指示に従い認証する。
認証に成功したら、連携対象のリポジトリとブランチを選択し、次へ。
※この例の場合、対象リポジトリのmasterブランチにPushすると、最新ソースがS3に自動的にデプロイされる。
ビルドステージを追加する
デプロイステージを追加する
前工程で作成したS3のバケットを参照するよう各項目を入力する。
「デプロイする前にファイルを抽出する」にチェックを付ける。
確認画面
動作確認
パイプラインの作成が完了すると自動的にデプロイが開始する。
以後、対象リポジトリの対象ブランチにPushされるたびにCodePipelineが自動的にソースをS3にデプロイしてくれる。
デプロイが完了したら、作成したS3にGitHub上のソースが反映されていることを確認する。
パイプライン作成後はGitHubのリポジトリにWebhookが登録されているか念のため確認しておく。
3. S3で静的Webサイトをホスティングする(外部公開する)
Static website hosting
を有効にするS3のバケットを開き、「プロパティ」タブの「Static website hosting」を選択する。
「このパケットを使用してウェブサイトをホストする」を選択し、
インデックスドキュメントに「index.html」を入力し、保存する。
紫チェックボックスと「パケットホスティング」が表示されていればOKです。
公開設定
「アクセス権限」タブの「ブロックパブリックアクセス」を選択し、編集を選択する。
「アクセス権限」タブの「パケットポリシー」を選択し、パケットポリシーエディタにポリシー設定のテキストを入力し、保存。
※以下テキストの【S3バケット名を入力】
を作成済みのS3バケット名に置き換え、パケットポリシーエディタに貼り付ければOK。
{ "Version":"2012-10-17", "Statement":[{ "Sid":"PublicReadForGetBucketObjects", "Effect":"Allow", "Principal": "*", "Action":["s3:GetObject"], "Resource":["arn:aws:s3:::【S3バケット名を入力】/*" ] } ] }保存すると以下のようにパブリックの表示が出る。
※Webサイトとしてどこからでも誰からでも見られるようにするため、警告は無視してOK。
動作確認
先ほど操作した「Static website hosting」の以下の赤枠にサイトのURLが記載されているので、そのURLにアクセスし、問題なくWebサイトが表示されることを確認する。
※この時点ではまだHTTPでアクセスする。
4. Route53に独自ドメインを登録する
ホストゾーンを作成
Route53のメニューから「ホストゾーン」をクリックする。
「ホストゾーンの作成」ボタンを押下すると右ペインに入力欄が表示されるので、利用するドメインを入力し、タイプは「パブリックホストゾーン」を選択し、「作成」ボタンを押下する。
5. ACMで証明書を作成する
HTTPSを利用する際に参照する証明書をACMで作成する。
パブリック証明書のリクエスト
リージョン「バージニア北部」を選択した上で、「証明書のリクエスト」ボタンを押下する。
※CloudFrontでACMの証明書を利用する場合、証明書はリージョン「バージニア北部(us-east-1)
」で取得する必要がある。
※ハマりポイント。「パブリック証明書のリクエスト」を選択し、「証明書のリクエスト」ボタンを押下する。
以下の通り、ドメイン名を入力する。
1つ目:*.xxxx.com
※ワイルドカードで指定。2つ目:
xxxx.com
※「この証明書に別の名前を追加」ボタン押下で入力欄が表示される。「DNSの検証」を選択し、「確認」ボタンを押下する。
※これはお好みで。
確認画面で、入力内容が正しいか確認する。問題なければ、「確認とリクエスト」ボタンを押下する。
証明書の検証
検証画面で検証用レコード(CNAME)が表示されるので、それをRoute53に登録する。
※独自ドメインをRoute53で管理する場合、「Route53でのレコードを作成」ボタンを押下することで、検証用レコード(CNAME)を自動的にRoute53に登録することができる。らくらく。
検証状況は証明書一覧から確認することができる。状況が「発行済み」に変わったら証明書の作成は完了。
6. CloudFrontのDistributionを作成する
Distributionを作成する
CloudFrontの設定画面を開き、「Create Distribution」ボタンを押下する。
「Origin Domain Name」の入力欄をクリックし、前工程で作成したS3バケット名を選択する。
「OriginID」が自動的に割り当てられる。それ以外は基本的にデフォルトでOK。
「Viewer Protocol Policy」では「Redirect HTTP to HTTPS」を選択する。
TTLはお好みで設定。
それ以外は基本的にデフォルトでOK。
「Alternate Domain Names(CNAMEs)」に以下の通りドメインを入力する。
xxxx.com,www.xxxx.com
※カンマ区切り
「SSL Certificate」は「Custom SSL Certificate」を選択し、前工程で作成したACMの証明書を選択する。
「Default Root Object」には「index.html」を入力する。
それ以外は基本的にデフォルトでOK。
動作確認
Distributionが作成されるまで少々時間がかかる。
「Status」が「Deployed」、「State」が「Enabled」になるまで待つ。
↑の状態になったら、「Domain Name」の「xxxx.cloudfront.net」のドメインにアクセスし、Webサイトが正常に表示されることを確認する。
7. CloudFront向けに独自ドメインを設定する
レコードセットを作成
前工程で操作したRoute53の設定画面を開き、「レコードセットの作成」を押下し、以下の通りAレコードのエイリアスを設定する。
名前:独自ドメイン(xxxx.com)
タイプ:A - IPv4 Address
エイリアス:はい
エイリアス先:前工程で作成したCloudFrontのDistribution(xxxx.cloudfront.net)
※それ以外は基本的にデフォルトでOK。
※「www.xxxx.com」などサブドメインやMXレコードなどもこのタイミングで作成してOK。
8. 動作確認(全体)
- 以下のURLにアクセスし、SSLが正常に動作すること、Webサイトが正常に表示されることを確認する。
https://xxxx.com
https://www.xxxx.com
- HTTPでアクセスした場合、HTTPSにリダイレクトされることを確認する。
http://xxxx.com
http://www.xxxx.com
- GitHubの対象リポジトリ、対象ブランチにPushしたら自動デプロイが動作し、変更内容がCloudFront側に正しく反映されることを確認する。
以上、全行程おわり。
その他
- 実運用する場合、要求仕様にあわせて設定などを諸々最適化すること。
- CloudFrontのキャッシュにより、自動デプロイを実行しても最新の変更内容を即座に確認できないため注意。 早めに確認したい場合は以下の記事を参考にキャッシュを削除するとよい。
[AWS] Amazon CloudFrontのキャッシュ削除(Invalidation)参考
- 投稿日:2019-07-10T12:29:22+09:00
AWS ECS向けCloudWatch Container Insightsのパブリックプレビューが開始したので、使用開始方法をまとめてみた
はじめに
こんにちわ。Wano株式会社エンジニアのnarikawaと申します。
/
— ポジティブな Tori (@toricls) July 10, 2019
Amazon ECS 向けの CloudWatch Container Insights のパブリックプレビューを開始しました!!
\
/ "Introducing Amazon CloudWatch Container Insights for Amazon ECS and AWS Fargate - Now in Preview" https://t.co/b1jaSGtg3x
個人的にはこっちの手順が分かり易かったです!https://t.co/UXiIwErG5B
— nari@エンタメ系エンジニア (@fukubaka0825) July 10, 2019ということで、以下の手順書を参考に試しに設定してみました。
Amazon ECS CloudWatch Container Insights - Amazon Elastic Container Service
ところどころわかりづらいところがあったり、日本語訳が提供されていないこともあったので、整理して発信しようと思い、この記事を書いています。
全てを訳せているわけではないので、詳細は大元の手順書を参考にしていただけると幸いです。対象読者
- CloudWatch Container Insightsの設定が、プレビュー時に使っていなくてよくわからない方
- 手順書が英語しか対応していないため嫌厭してまだ試せていない方
- CloudWatch Container Insightsでどんなことができるか知りたい方
導入手順
1.まずは設定いじる
GUI(console)で設定する
※この際、ルートユーザーまたはコンテナーインスタンスのIAMロールを使用していることが前提
※この際、実行しようとしているIAM usersとIAM role はecs:PutAccountSetting permissionがこのアクションに必要
CUIで設定する
- 自分のアカウント全てのIAM usersとIAM roleのdefaultの設定をcontainer insightsをenabledにしたい
put-account-setting-default (AWS CLI)の場合
aws ecs put-account-setting-default --name containerInsights --value enabled --region us-east-1Write-ECSAccountSettingDefault (AWS Tools for Windows PowerShell)の場合
Write-ECSAccountSettingDefault -Name containerInsights -Value enabled -Region us-east-1 -Force
- 自分のアカウントのあるIAM usersとIAM roleのdefaultの設定をcontainer insightsをenabledにしたい(root userのみ)
put-account-setting (AWS CLI)の場合(特定のuser設定変更)
aws ecs put-account-setting --name containerInsights --value enabled --principal-arn arn:aws:iam::aws_account_id:user/userName --region us-east-1Write-ECSAccountSetting (AWS Tools for Windows PowerShell)の場合(特定のuser設定変更)
Write-ECSAccountSetting -Name containerInsights -Value enabled -PrincipalArn arn:aws:iam::aws_account_id:user/userName -Region us-east-1 -Force2.クラスターを作る
3.いつも通りサービスかタスクを立ち上げる
4.誘導に従って、cloudwatchのcontainer insightsを見る
- クラスタのメトリクスのタブに移動すると、見慣れない青枠の誘導があるので、View Container Insightsのボタンをクリックする
- そうすると以下のような、docker stats相当の情報が観れる
container insightsのいいところ
- コンテナインスタンスにsshして、docker statsしなくてもコンテナの状態を監視できる
疑問点
- まだterraformでは対応していない?
- public previewだから多分対応していない
- clusterのパラメタで早く切り替えれると嬉しい。。
- 既存のクラスタをいじって設定を足せないのか
- terraformで建ててから手動で切り替えようと思ったらできなかった(そもそもクラスターの設定修正画面がない)
- CLIならいけるのか??
- ecs — AWS CLI 1.16.195 Command Reference 見当たらない、、
わかる方ぜひ教えて欲しいです、、わりと切実- [追記 2019/7/10]以下の回答いただけました!、正式なリリースでの対応が待ち遠しい
ありがとうございます!
— ポジティブな Tori (@toricls) July 10, 2019
既存クラスタでの有効化は現時点ではできないので新規クラスタでお試しいただく感じになります?終わりに
- 週1投稿に関して、これは先週分ってことで許してください(遅れてすみません。。)
- 投稿日:2019-07-10T11:25:37+09:00
goofys で sftp ユーザの chroot を s3 バケット配下のディレクトリにできなかった備忘
goofys でマウントした s3bucket
#df -h Filesystem Size Used Avail Use% Mounted on [bucket name] 1.0P 0 1.0P 0% /data/s3bucketgoofys でマウントした s3bucket と
sftp ユーザが接続直後にアクセスするディレクトリ# pwd /data # tree . |-- chroot ← sftp ログインユーザ用のオーナーにしたシンボリックリンクを用意 | `-- SFTP_USER -> /data/s3bucket/SFTP_USER `-- s3bucket ← goofys で s3Bucket をマウントする先 `-- SFTP_USER # ls -la chroot/ lrwxrwxrwx 1 SFTP_USER SFTP_USER 24 Jul 10 10:44 SFTP_USER -> /data/s3bucket/SFTP_USERSFTP のユーザと chroot 先の設定
# cat /etc/ssh/sshd_config 〜省略〜 AllowUsers SFTP_USER 〜省略〜 Match Group supplier ChrootDirectory /data/chroot/%u 〜省略〜sftp 鍵認証用に Linux ユーザ home 配下 .ssh/authorized_keys へ公開鍵を追加
ローカルから SFTP サーバへ接続
# sftp -oIdentityFile=~/.ssh/[id_rsa秘密鍵] [SFTP_USER]@[SFTPサーバ] packet_write_wait: Connection to [SFTPサーバ] port 22: Broken pipe Connection closedこのときの sftp サーバの message と secure ログ
# tail -f /var/log/messages systemd: Created slice User Slice of [SFTP_USER]. systemd: Starting User Slice of [SFTP_USER]. systemd-logind: New session 18 of user [SFTP_USER]. systemd: Started Session 18 of user [SFTP_USER]. systemd: Starting Session 18 of user [SFTP_USER]. systemd-logind: Removed session 18. systemd: Removed slice User Slice of [SFTP_USER]. systemd: Stopping User Slice of [SFTP_USER]. # tail -f /var/log/secure Accepted publickey for [SFTP_USER] from [SFTP SERVER] port <省略> ssh2: RSA <省略> pam_unix(sshd:session): session opened for user [SFTP_USER] by (uid=0) fatal: bad ownership or modes for chroot directory "/data/chroot/[SFTP_USER]" [postauth] pam_unix(sshd:session): session closed for user [SFTP_USER]bad ownership or modes for chroot directory
シンボリックリンクの権限では sftp を騙せないんですね。。。
その後わかったこと
Cent os 6 では uid gid ともに 500 番台から 7 では 1000 番台から。 そのため s3fs でも 7 では usermod grpmod で id を 6 に合わせる必要がある。 sftp の chroot 先は root:root の 755 の必要あり。 これが制限となり共通グループがあっても 775 ではないため、書き込みと削除が出来ない。
- 投稿日:2019-07-10T11:06:12+09:00
AWSで利用するSSL証明書管理をIAMからACMに変更するべき理由
はじめに
自分が担当しているシステムでELBに登録しているSSL証明書をIAM管理からACM管理に変更しました。
AWS機能を利用してSSL証明書を管理する方法は2つあります。
IAMを利用する方法とACMを利用する方法です。
なぜ今までIAMで管理していたのか、ACMにすると何が良いのかを纏めておきます。基本知識まとめ
まず基本情報についてざっと纏めます。
SSL証明書の種類
DV証明書:ドメイン証明書。ドメイン名が正しいかどうかを認証。
OV証明書:ドメイン名に加え、会社名も証明。
EV証明書:DV、OVよりも厳格な審査がある。セキュリティレベルの高さはEV→OV→DVの順です。DVがセキュリティレベルが一番低く簡単に認証を受けられます。
参考 今さら聞けないSSL証明書とは、DV、OV、EVとは、常時SSLについて
https://shared-blog.kddi-web.com/network/244/IAMの基本情報
正式名称:AWS Identity and Access Management
ローンチ日:2010/9/2
機能概要:AWS リソースへのアクセスを安全にコンソールするためのウェブサービス参考 AWS Identity and Access Management ユーザーガイド
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/introduction.htmlACMの基本情報
正式名称:AWS Certificate Manager
ローンチ日:2016/1/21(東京リージョンローンチ日は2016/5/16)
機能概要:AWS ベースのウェブサイトとアプリケーション用のパブリック SSL/TLS 証明書の複雑な作成と管理を処理
証明書のインポート機能ローンチ日:2016年10月あたり参考 AWS Certificate Manager ユーザーガイド
https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/import-certificate.html今までIAMで管理していた理由
ローンチ日を見るとACMは2016年と比較的最近リリースされています。
システム構築時はIAM一択であったことがわかりました。
さらに2016年10月にACMで外部の証明書インポート機能がリリースされたことにより、
IAMを選択する理由はほぼなくなりました。ELB作成時のSSL証明書選択画面からもACM推奨であることが明記されています。
ACMのすごいところ
自分が感じたACMのメリットを並べてみます。(もっとあった気が。。)
・無料でDV証明書を作成できる(これは驚きました)
・ACMで作成したDV証明書は自動更新されるまとめ
外部に公開しているシステムだとOV証明書必須の場合が多いかと思いますが、
社内利用のみのシステムであればDV証明書でも問題ないのではないでしょうか。
IAM管理されているDV証明書があったらぜひACMへの移行を検討してみてください。
※2015年以前に構築され、SSL証明書を利用しているシステムは同様の状況になっていることがあるのでは
- 投稿日:2019-07-10T10:12:33+09:00
AWSLambda + Python3 でLINEに通知してくれるToDoリストを作った話
作り始めた経緯
一か月前ほどからJavaを使ってandroidアプリ開発の勉強を始めたのですが、ToDoリストを作っている途中で
「よく考えたら普段使いはPCとiPhoneだった」
ということに気づき、このまま使いもしないandroidアプリを作るくらいだったらとりあえずPCからタスク管理ができるものを作ろうということで作り始めました。AWSを使う
AWS(Amazon Web Service)はクラウドで様々なことを行えるサービスです
登録後12か月は無料枠がありますし、個人で使う分には利用料金もそこまでしないので安心です。AWS登録はこちら
https://aws.amazon.com/jp/
今回は様々なサービスがある中でLambdaとS3とCloudWatchEventsを使っていきます。
Lambda:関数を作って何かのトリガーで実行する機能
S3:ファイルを保存するストレージ
CloudWatchEvents:指定した時間に関数を叩いてくれるくらいの認識で大丈夫だと思います。
システム概要
Lambda関数を作る
まずはLambdaの関数を作らなければ何も始まりませんので作っていきます。
すぐ下にこのような画面が出るので関数名と使う言語を入力し関数の作成を押します。
ロールの設定
ロールにポリシーをアタッチしておかないと許可がなく実行できなかったりするのでロールの設定をしていきます。
先ほどのページを下がっていくと実行ロールの欄に既存のロールというというところがあります。そこのhogehogeロールを表示しますというところをクリックしてください。
すると、このようなページが出てくると思うのでポリシーをアタッチしますをクリックしてください。
その先のページで下記3つのポリシーをアタッチしてください。
これでポリシーの設定は完了です。PythonでAWSを扱う
PythonでAWSを扱うためにはboto3というライブラリを使用します。
初期設定などは少し難しいので偉大なる先人様の記事を参考にしました。
ココミテ
boto3を使ってS3をごにょごにょするS3にタスクをアップロードする
まずはクライアント側のプログラムを作ります。
細かいプログラムは人に見せられるような代物ではないので、ここでは僕が作っていて詰まった点とその解決法を書いていきます。受け渡しデータ
CSVファイルに渡すデータはタスク名、日付、時間の三つのデータです。
年のデータを渡していないので一年以内のタスクしか扱えません。ClientErrorが出る
これはtry-exceptで例外処理できるのですが、素の状態だとエラー名が見つからないので
from botocore.exceptions import ClientErrorしてから
try: hogehoge except(ClientError): hugahugaしてください。
データの受取型
with open した後に
reader = csv.reader(f)するのですが、readerにはreaderオブジェクトとして帰るのでそのままは使えません。
僕はfor文を使って二重ループで内容を回収しました。通知時間に到達しているかチェックする関数
ここからはLambda側で作っていきます。
なおLambdaにライブラリとコードをまとめたZIP形式でアップロードするためコーディングは自分側で行います。プログラム概要
データを保存するディレクトリ
Lambdaにデータを受け渡すためにS3にいったんCSV形式でタスクのデータを送っているため、それを受け取らなければいけません。
その際ダウンロードをする場所を/tmp/hogehoge.csvとしなければなりません。s3 = boto3.resource('s3') bucket = s3.Bucket('hoge') bucket.download_file('hogehoge.csv','/tmp/hogehoge.csv')のようにします。
handleについて
Lambdaは呼び出されたときhandle設定した関数にeventとcontextを渡して実行します。
今回はS3からデータを持ってきて利用するのでこの受け取った内容は使用しませんが、受け取らないとエラーを吐くのでしっかりとdef handle(event, context):と記述する必要があります。
また、handle名は自由につけることができ
上記のようにハンドラの欄から プログラム名.ハンドル名 の形式で設定します。Lambda上でのタイムゾーン
Lambda上では(多分)リージョンにかかわらずtimeモジュールで持ってくる時間がグリニッジ標準時(GMT)になっています。当然僕は日本でこのプログラムを利用するため日本時間(JST)になおす必要があります。
そのために環境変数の欄にキーをTZ、値をAsia/Tokyoと設定します。
するとtimeモジュールで持ってくる値が日本時間に変更されます。LambdaからLambdaを叩く
Lambda関数から別のLambda関数を叩くには
import boto3 import json clientLambda = boto3.client("lambda") clientLambda.invoke( FunctionName="send_line", #送る先の関数名 InvocationType="Event", #EventかRequestResponseどちらを受け取るか選ぶ Payload=json.dumps(event) )ここも少し難しかったので下記の先人様の記事を参考にさせていただきました。
AWS LambdaからLambda呼んでハマった話。
AWSのLambdaからLambdaを呼んで、Slackにメッセージを送信するLambdaにZIP形式でアップロードする
ライブラリをインポートして使用している場合Lambdaで扱うためにはライブラリとプログラム本体をまとめたZIP形式のファイルでアップロードする必要があります。
C:\Users\user\programfile> pip install hogehoge -t ./とかでプログラムと同階層に利用したライブラリを入れてください。
その後ZIP圧縮するのですが、この際ファイルの置いてあるディレクトリを圧縮すると階層が一つ深くなってhandleを掴めなくなってしまうようなので、ファイル自体を全選択して圧縮します。
あとはここに投げて保存して終了です。
一応、ハンドルがつかめているか確認するためにテストイベントを実行します。
テストイベントの設定を押して
空のテストイベントを作成します。
その後テストから実行します。handleを掴めていてほかのエラーが出ていればとりあえずOKです。CloudWatchEventsのcron式
cron式の記法は[分 時間 日 月 曜日 年]の形式で書きます。
cron式の日フィールドと曜日フィールドは同時に指定することができないとCloudWatchEventsのガイドに書いてあるので、どちらか一方でワイルドカード?(疑問符)を使用する必要があります。ルールのスケジュール式 - Amazon CloudWatch Events
このプログラムは一時間に一回、00分に叩かれる必要があるので
[0 * * * ? *]
のように記述しました。LINE Notifyの設定をする
設定はこちらから
LINE Notify
ラインに通知を行うためにLINEのAPIサービスのLINE Notifyの登録を行います。
ページを見ればわかるとは思いますが詰まった場合は
[超簡単]LINE notify を使ってみる
のページを参考にすることをお勧めします。LINE送信部
アクセストークンが発行出来たら、先ほどのLambda関数でメッセージが生成されたときに叩かれるsend_line関数を作成していきます。
権限
ロールにアタッチする権限はS3のreadonly権限のみでOKです。
初期設定
url = "https://notify-api.line.me/api/notify" token ="accesstoken" #各個取得したアクセストークン headers = {"Authorization" : "Bearer "+ token}これをスクリプト内に記述します。
プログラム概要
メッセージのCSVファイルを受け取って読み取って各メッセージごとにラインに送るだけ。
メッセージ複数送信
for mess in mess_lis: message = mess payload = {"message" : message} r = requests.post(url ,headers = headers ,params=payload)こうしておけば複数送信も可能です。
最後に
今回はAWSのさわりとしてこのようなToDoリストを作ってみました。
初めての投稿で読みずらい箇所多々あったとは思いますが、また何か作った際にはもっと改善して読みやすい記事を書けるようになってきますのでよろしくお願いします。余談なのですが、最近「ほんとに使える「ユーザービリティ」(エリック・L.ライス著)」という本を読みました。振り返ってみるとこの記事は写真が多すぎた気がします。
- 投稿日:2019-07-10T09:00:15+09:00
AWS CloudFormationのLambda-Backedカスタムリソースでリソース作成を待ち受けできるようにする
AWS CloudFormation(CFn)のLambda-Backedカスタムリソースを利用するとCFnが対応していないリソースでもAWS Lambdaを利用して管理できます。
AWS Lambda-backed カスタムリソース - AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.htmlその際に、リソース作成するとレスポンスはすぐに返ってくるけど、リソースが利用できるまでに時間がかかるものを取り扱えるようにしてみました。
テンプレート
CFnでリソース作成を待ってから関連するリソース作成などができるようにするテンプレートです。
Resources: CreateResource: Type: Custom::CustomResource Properties: ServiceToken: !GetAtt CreateResourceFunction.Arn CustomResource: Type: Custom::CustomResource Properties: ServiceToken: !GetAtt CustomResourceFunction.Arn ResourceId: !GetAtt CreateResource.Id DependsOn: CreateResource CreateResourceFunction: Type: AWS::Lambda::Function Properties: Handler: index.handler Role: !GetAtt FunctionExecutionRole.Arn Code: ZipFile: !Sub | import cfnresponse def handler(event, context): response = {} if event['RequestType'] == 'Create': try: # ほんとはここでリソース作成 response = { "Id": "hoge" } except Exception as e: response = {'error': str(e)} cfnresponse.send(event, context, cfnresponse.FAILED, response) return cfnresponse.send(event, context, cfnresponse.SUCCESS, response) Runtime: python3.7 CustomResourceFunction: Type: AWS::Lambda::Function Properties: Handler: index.handler Role: !GetAtt FunctionExecutionRole.Arn Code: ZipFile: !Sub | import cfnresponse import time def handler(event, context): Id = event['ResourceProperties']['ResourceId'] # リソース作成完了を待ち受ける response = {} while True: # ホントはここでリソース取得 response = { "Id": Id, "Status": "AVAILABLE" } # 特定のステータスになったら抜ける if response['Status'] == 'AVAILABLE': break print('create wait...') time.sleep(60) cfnresponse.send(event, context, cfnresponse.SUCCESS, response) Runtime: python3.7 Timeout: 900 FunctionExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: root PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: "arn:aws:logs:*:*:*"ポイント
カスタムリソースを2つ用意する
リソースを作成する
CreateResource
とリソース情報を取得するCustomResource
のカスタムリソースを定義することで、リソース作成を待ち受けできるようにしています。Lambda関数のタイムタウト x 3回まで待ち受けできる
AWS Lambdaの関数は最大15分のタイムタウト設定ができます。またLambda-Backedカスタムリソースで関数実行に失敗すると3回までリトライしてくれるのでそれを利用して最大45分間待ち受けできるようになります。
AWS Lambda の制限 - AWS Lambda
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/limits.html※Lambda-Backedカスタムリソースでのリトライ回数について必ず3回実行されるのかはドキュメントが見当たらず不明確となります。
AWS Lambda 再試行動作 - AWS Lambda
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/retries-on-errors.html
DependsOn
属性を利用してリソース作成順を制御するCFnの
DependsOn
属性を利用することで、リソース作成CreateResource
後、リソース情報取得CustomResource
が実行されるようにします。
後続するリソースはCustomResource
をDependsOn
属性に指定することでリソース作成完了してから実行されるようにできます。DependsOn 属性 - AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.htmlカスタムリソースの更新・削除と絡めて利用する
下記記事の内容と組み合わせることで、カスタムリソースの更新・削除が実現できます。
AWS CloudFormationのLambda-backedカスタムリソースでリソースの更新・削除をする方法 - Qiita
https://qiita.com/kai_kou/items/7be2eb9a36611bb5da12参考
AWS Lambda-backed カスタムリソース - AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.htmlAWS Lambda の制限 - AWS Lambda
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/limits.htmlAWS Lambda 再試行動作 - AWS Lambda
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/retries-on-errors.htmlDependsOn 属性 - AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.htmlAWS CloudFormationのLambda-backedカスタムリソースでリソースの更新・削除をする方法 - Qiita
https://qiita.com/kai_kou/items/7be2eb9a36611bb5da12
- 投稿日:2019-07-10T08:21:59+09:00
shields.ioを使って技術系アイコンを量産した
概要
shields.ioを用いて技術系アイコンを量産しました。
とりあえず完成したのがこちらです。
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
これでスキルマップを作ってみたらいい感じになりました。
shields.ioについて
GitHubのREADMEでよく見かけるアレです。
shields.ioはSVG形式のバッジサービスです。カスタムバッジを作る
特徴的な機能の1つとして
URLのパターンでカスタムバッジを作ることができます。https://img.shields.io/badge/${subject}-${status}-${color}.svgsubject : バッジの左側に入る文言
status : バッジの右側に入る文言
color : 色Color
以下のようなものが用意されています。
16進数形式で指定することも可能です。
カスタムスタイル
いくつかのスタイルが用意されています。
?style=plastic&logo=nginx
?style=flat&logo=java
?style=flat-square&logo=adobe
?style=for-the-badge&logo=gitlab
?style=popout&logo=kotlin
?style=popout-square&logo=google
?style=social&logo=qiita
simpleicons
バッジではいくつかのアイコンが使えます。
これについてはsimpleiconsを参考にします。そして、使えるアイコンの一例がこちらです。
全部で数えたら648ありました。
Qiitaのアイコンもありました。カラーコードとロゴがセットになっているのでコレを使ってアイコンを作っていきます。
おすすめアイコンを作った
おすすめしたいアイコンを作りました。
言語系
ライブラリ・フレームワーク
OS
ミドルウェア
エディタ・IDE
クラウド・他
参考
付録 : アイコンのURL
各アイコンのURLです。1
### 言語系 <img src="https://img.shields.io/badge/PHP-ccc.svg?logo=php&style=flat"> <img src="https://img.shields.io/badge/Javascript-276DC3.svg?logo=javascript&style=flat"> <img src="https://img.shields.io/badge/-TypeScript-007ACC.svg?logo=typescript&style=flat"> <img src="https://img.shields.io/badge/-Python-F9DC3E.svg?logo=python&style=flat"> <img src="https://img.shields.io/badge/-CSS3-1572B6.svg?logo=css3&style=flat"> <img src="https://img.shields.io/badge/-HTML5-333.svg?logo=html5&style=flat"> ### ライブラリ・フレームワーク <img src="https://img.shields.io/badge/-CakePHP-D3DC43.svg?logo=cakephp&style=flat"> <img src="https://img.shields.io/badge/-Rails-CC0000.svg?logo=rails&style=flat"> <img src="https://img.shields.io/badge/-Django-092E20.svg?logo=django&style=flat"> <img src="https://img.shields.io/badge/-Flask-000000.svg?logo=flask&style=flat"> <img src="https://img.shields.io/badge/-Bootstrap-563D7C.svg?logo=bootstrap&style=flat"> <img src="https://img.shields.io/badge/-React-555.svg?logo=react&style=flat"> <img src="https://img.shields.io/badge/-jQuery-0769AD.svg?logo=jquery&style=flat"> ### OS <img src="https://img.shields.io/badge/-Linux-6C6694.svg?logo=linux&style=flat"> <img src="https://img.shields.io/badge/-Ubuntu-6F52B5.svg?logo=ubuntu&style=flat"> <img src="https://img.shields.io/badge/-Windows-0078D6.svg?logo=windows&style=flat"> <img src="https://img.shields.io/badge/-RedHat-EE0000.svg?logo=red-hat&style=flat"> <img src="https://img.shields.io/badge/-Debian-A81D33.svg?logo=debian&style=flat"> <img src="https://img.shields.io/badge/-Raspberry%20Pi-C51A4A.svg?logo=raspberry-pi&style=flat"> <img src="https://img.shields.io/badge/-Arch%20Linux-EEE.svg?logo=arch-linux&style=flat"> ### ミドルウェア <img src="https://img.shields.io/badge/-Apache-D22128.svg?logo=apache&style=flat"> <img src="https://img.shields.io/badge/-Nginx-bfcfcf.svg?logo=nginx&style=flat"> <img src="https://img.shields.io/badge/-Oracle-f80000.svg?logo=oracle&style=flat"> <img src="https://img.shields.io/badge/-Redis-D82C20.svg?logo=redis&style=flat"> <img src="https://img.shields.io/badge/-Elasticsearch-005571.svg?logo=elasticsearch&style=flat"> <img src="https://img.shields.io/badge/-PostgreSQL-336791.svg?logo=postgresql&style=flat"> ### エディタ・IDE <img src="https://img.shields.io/badge/-Visual%20Studio%20Code-007ACC.svg?logo=visual-studio-code&style=flat"> <img src="https://img.shields.io/badge/-Vim-019733.svg?logo=vim&style=flat"> <img src="https://img.shields.io/badge/-Emacs-EEE.svg?logo=spacemacs&style=flat"> <img src="https://img.shields.io/badge/-Atom-66595C.svg?logo=atom&style=flat"> <img src="https://img.shields.io/badge/-Xcode-EEE.svg?logo=xcode&style=flat"> <img src="https://img.shields.io/badge/-intellij%20IDEA-000.svg?logo=intellij-idea&style=flat"> ### クラウド・他 <img src="https://img.shields.io/badge/-Amazon%20AWS-232F3E.svg?logo=amazon-aws&style=flat"> <img src="https://img.shields.io/badge/-Google%20Cloud-EEE.svg?logo=google-cloud&style=flat"> <img src="https://img.shields.io/badge/-Ansible-EE0000.svg?logo=ansible&style=flat"> <img src="https://img.shields.io/badge/-GitHub-181717.svg?logo=github&style=flat"> <img src="https://img.shields.io/badge/-Docker-EEE.svg?logo=docker&style=flat">