Aws

lambrollデプロイに必要なIAM権限

lambrollとは

fujiwara/lambroll は、AWS Lambda関数のデプロイを簡単に行うための軽量デプロイツールです。

デプロイに必要なIAM権限

lambrollを使ってLambda関数をデプロイする際、GitHub ActionsやCI/CDパイプラインで実行する場合に必要なIAM権限の一覧です。

権限一覧

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "lambda:CreateFunction",
        "lambda:GetFunction",
        "lambda:GetFunctionConfiguration",
        "lambda:InvokeFunction",
        "lambda:ListTags",
        "lambda:TagResource",
        "lambda:UntagResource",
        "lambda:UpdateFunctionCode",
        "lambda:UpdateFunctionConfiguration"
      ],
      "Resource": [
        "arn:aws:lambda:ap-northeast-1:123456789012:function:your-function-name"
      ]
    }
  ]
}

各権限の説明

必須権限

権限用途備考
lambda:CreateFunctionLambda関数の初回作成既存関数の更新のみの場合は不要
lambda:GetFunction既存関数の情報取得lambrollが関数の存在確認に使用
lambda:GetFunctionConfiguration関数設定の取得現在の設定との差分確認に使用
lambda:UpdateFunctionCode関数コードの更新デプロイの主要な処理
lambda:UpdateFunctionConfiguration関数設定の更新(環境変数、タイムアウトなど)function.jsonの設定を反映
lambda:ListTags関数のタグ一覧を取得重要: lambrollがfunction.jsonのTagsと既存タグを比較するために必須
lambda:TagResourceタグの追加function.jsonにTagsフィールドがある場合は必須
lambda:UntagResourceタグの削除既存タグを削除する場合に必要

オプション権限

権限用途備考
lambda:InvokeFunctionLambda関数の実行デプロイ後のテスト実行を行う場合に必要

よくあるエラーと対処法

lambda:ListTagsが不足している場合

Error: failed to deploy function configuration: failed to list tags of
arn:aws:lambda:...: operation error Lambda: ListTags,
api error AccessDeniedException: User is not authorized to perform:
lambda:ListTags on resource

原因: lambrollはfunction.jsonTagsフィールドと既存のタグを比較するため、lambda:ListTags権限が必要です。

Read more...

aws/s3

背景

特定の画像ファイルをs3のバケット間でコピーしたい。下記のような画像ファイルのリストは得られているものとする。

20190224015128auhP0mxtSX.png
20190224190754KuNToorMQc.png
20190224190809ryOuqd6bTC.png
20190226065547aZVU6WQLQw.png
20190226065559jnla1SwUik.png

この際、 GNU parallel と aws-cli を使って手軽にコピーした。

GNU parallelインストール

sudo yum -y install parallel
cat 画像ファイル名 | parallel --jobs 60 aws s3 cp s3://test-bucket/chat/image/{} s3://test-depot/chat/{} 2>&1 | tee "$(date +%Y%m%d%H%M).log"
Read more...

MediaLiveでRTMP接続があった事を検知する

ひょっとするとServerlessFrameworkでも検索条件が作れるかもしれないが手動で作成した

MediaLiveでRTMPで接続ができた際にトリガーとする方法

{
  "source": [
    "aws.medialive"
  ],
  "detail": {
    "alarm_state": [
      "cleared"
    ],
    "message": [
      "Waiting for RTMP input"
    ]
  }
}

ターゲットはStepFunctionを指定した。 ServerlessFrameworkで、直接、CloudWatch ルールからStepfunctionを指定することはできなかった。 通常のlambdaであれば、ServerlessFrameworkで指定可能だろう、若干面倒そうではあるかな。手動で設定しよう。

Read more...

MediaLiveでライブ配信システムを構築する

ライブ配信システムの構成

映像データは下記のように流れる。

カメラ、マイク -> ローランドの映像ミキサー -> LiveShell X -> MediaLive -> MediaStore -> CloudFront -> 各プラットフォームのプレーヤー

この手順では、MediaLive、MediaStore、CloudFrontの設定について行う。

このうち、MediaLiveには

  1. インプット( LiveShell X からの RTMP を受け取る )
  2. チャンネル( 映像データをエンコードする ) で構成されている。

またMediaStoreはストレージで、MediaLiveでエンコードされたデータを保存する領域になっている( MediaLive だけでは映像を保存できない、かならず別の保存する領域に転送する必要がある )

CloudFrontは大規模配信で使われるCDNで、 複数ユーザにキャッシュを見せる事で、MediaStoreの負荷を下げるために用いている。つまりCloudFront無しでも配信は可能だが、CloudFront無しだとライブ授業のユーザー数には耐えられないため、導入しておいた方がよい。

MediaStore( 映像チャンク置き場 )を作る

MediaStoreは「MediaLiveでエンコードされた映像のチャンクを置く場所」として必要( MediaLiveにはストレージが無いので、別途つくる必要がある ) MediaLiveを作る際にMediaStoreのアドレスを指定する必要があるので、事前に作成する。

チャンネルを作成する

MediaLiveで映像データをエンコードするチャンネルを作成する

管理画面 からログイン

設定例

入力名: dev 入力タイプ: RTMP (プッシュ) Network mode: Public 入力セキュリティグループ: 既存の使用、0.0.0.0/0 入力の送信先: SINGLE_PIPELINE

  1. [チャンネルの作成] をクリック

  2. ( その環境にMediaLive用のロールが無ければ作る必要があるので )テンプレートからロールを作成する

チャンネルテンプレートは[ Live Action ]をベースに作成する事にした。 ( このテンプレートの内容は時代によって変わるようだ。以前よりテンプレートも増えているし内容も異なる )

[ Channel class ] は [ SINGLE PIPELINE ]を選択する。 標準では[ STANDARD ]になっているが、正しく冗長化を試みるとなると、インターネット回線を2つ用意するような話になるので、シンプルに[ SINGLE PIPELINE ]で設定する。

Read more...

MediaLiveで配信中のファイルを結合する

ライブ動画のTS結合方法

高解像度側 現在のチャンク数を確認

$ curl https://live3.test.com/a/live_1080p30.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:1230

現在、1230までチャンク数が進んでいる。

最初から現在までのチャンクをダウンロード ( ユーザから見えるのはCloudFrontであるため、MediaStore経由ではなく、CloudFront経由で取得している。 特にライブ中はMediaStoreの制限にかかるケースがありえるので、直接の取得は避ける ) wgetコマンドでTSファイルを取得

作業ディレクトリ作成

mkdir -p ~/tmp/$(date +%Y%m%d)
cd  ~/tmp/$(date +%Y%m%d)

ファイル取得

for num in $(seq -w 1 1230) ; do echo $num ; wget https://live3.test.com/a/live_1080p30_0${num}.ts ; done

ダウンロードしたファイルリスト作成

for num in $(seq -w 1 1230) ; do echo "file ./live_1080p30_0${num}.ts" >> file_list.txt ; done

結合

ffmpeg -f concat -safe 0 -i file_list.txt -c copy $(date +%Y%m%d).mp4

低解像度側 作業

ファイル取得

Read more...

nuxt向けのCloudFront設定

nuxt用の設定についてまとめた

nuxt.js向けのCloudFront設定をまとめた。

オリジンとCDNの関係

CloudFrontでは、複数のオリジンサーバを指定可能。例えば s3 や 複数のALBで振り分ける事ができる( Layer7レベルでの振り分けが可能 )、 更にALBはリスナーに設定を追加することで複数のドメインをLayer7レベルで振り分けられる。

  1. ALBで、FQDNで正しいターゲットグループに振り分けられる用に設定する
  2. CloudFrontで、 ALBの名前を指定する www-36?????.ap-northeast-1.elb.amazonaws.com ( CloudFront から ALB に要求されるFQDNの情報は飛ぶ )
  3. Route53 で、ユーザーがアクセスするFQDNをCloudFrontに振り向ける

それぞれの手順を下記に残しておく

1. ALBで、FQDNで正しいターゲットグループに振り分けられる用に設定する

ロードバランサー -> リスナー -> ルールの表示` をクリックして、Layer7設定を確認。

  • 目的のFQDNが存在するか?
  • ALBからの転送先が存在するか?
  • 転送先のターゲットグループにはサーバは存在するか? を確認する。

CloudFront設定

設定する前に…

  • SSL証明書はAWSで発行済か( CloudFrontのSSL証明書はバージニア北部に存在する必要がある )
  • ALBの設定はできているか
  • s3にログ用のバケットはあるか

を確認したほうが良い( でないと、CloudFrontの設定をやり直す必要がある )

オリジンサーバとしてALBのFQDN( dandelive-eikoh-51???.ap-northeast-1.elb.amazonaws.com のようなもの、EC2の「ロードバランサー」のページで確認できる)

オリジンサーバでALBを登録後、振る舞いとして /nuxt/配下を追加する。 デフォルトはキャッシュしないが、/nuxt/配下はキャッシュする。

  • Minimum Origin SSL Protocol : TLSv1
  • Origin Protocol Policy : HTTPS Only ( 暗号化された通信だけにしたい )
  • Origin Response Timeout : 60
  • Viewer Protocol Policy : Redirect HTTP to HTTPS ( http接続はhttpsにリダイレクトして暗号化を促す )
  • Allowed HTTP Methods : GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
  • Origin Keep-alive Timeout : 60 ( コネクションを再接続するコストを払わない )
  • Cache and origin request settings : 「Use a cache policy and origin request policy」と「Use legacy cache settings」がある。以前は legacy に該当する設定しかなかった。 最初に設定するオリジンはキャッシュしないポリシー「CachingDisable」を選択する。
  • Origin Request Policy : Managed-AllViewer ( 全てのリクエストヘッダ、クッキーなどをオリジンに通す )
  • Alternate Domain Names (CNAMEs) : test.net ( 都度、変えること )

Behaviors を追加する

CloudFrontを設定( ディストリビューションの設定 )を追加するウィザードで設定されるのは、 デフォルトのアクセスだけなので、 /_nuxt のようなURLごとの設定の場合、設定を追加する必要がある。

Read more...

簡単な EC2 インスタンスのバックアップ機構を作る

日次で自動的に cron で再起動して、AMI イメージを取得したい。 再起動が必要だが再起動時はメンテナンス画面を出しておきたい( 深夜メンテナンス時間が取れるサービスに限る ) ALB でメンテナンス画面を出せる機能を用いてサーバ終了、起動時にメンテナンス画面に切り替える

仕組み

  1. EC2 上で自分自身のイメージを取得するスクリプトを用意する
  2. EC2 の IAM ロールで AMI 化を実行するのに必要な権限を付与する
  3. EC2 サーバの crontab にスクリプトを用意する
  4. 起動終了時に ALB のルールのプライオリティを変更する処理を組み込む

EC2 上で自分自身のイメージを取得するスクリプトを用意する

/usr/local/bin/ami_backup.bash に下記のスクリプトを設置した。

#!/bin/bash

id=$(/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id)
/usr/bin/aws ec2 create-image --region ap-northeast-1 --instance-id $id --name "wordpress-www-update-$id-$(date +%Y%m%d%H%M)" --reboot

wordpress-www-update の部分はシステムによって変えた方が良いと思う。 あるいは$id にインスタンス名が入るので、それを持ってユニークとするか( ただし検索が面倒 )

EC2 の IAM ロールで AMI 化を実行するのに必要な権限を付与する

下記のロールを持つように IAM を作成、EC2 サーバーに付与

  • elasticloadbalancing はロードバランサーのルールのプライオリティの上下に使う
  • ec2 は AMI の作成に使う
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:DescribeRules",
                "elasticloadbalancing:SetRulePriorities",
                "ec2:ExportImage",
                "ec2:DescribeImages",
                "ec2:DeleteTags",
                "ec2:EnableImageDeprecation",
                "ec2:CreateTags",
                "ec2:RegisterImage",
                "ec2:CreateImage",
                "ec2:ModifyImageAttribute",
                "ec2:CreateStoreImageTask",
                "ec2:DisableImageDeprecation"
            ],
            "Resource": "*"
        }
    ]
}

EC2 サーバの crontab にスクリプトを用意する

AM 03:01 に実施

Read more...

ALBのメモ

背景

AWSが悪いわけではない、大抵、自分が悪い。自分の何が悪いのか分析したい

ALBのログを解析する

ログのステータスコードの意味

Application Load Balancer のトラブルシューティング

502 エラーの場合

状況としては

  • ALBはターゲットのコンピューティングノードに接続しようとしている
  • ALBはターゲットのコンピューティングノードに接続しようとしてるが、コンピューティングノード側が切れている

なぜ切れているのか? 様々な理由がありえるだとう

  • コンピューティングノード側が短い
    • 基本的にALB側を短くすべき( ALB主体で切るようにすればコンピューティングノード側で先に切ることはない )
  • コンピューティングノード側が切れている
    • Nginx、Ruby、php-fpmなどのポートは、その時に受け入れられる状態だったのか?
  • Application Load Balancer の属性を編集する - エラスティックロードバランシング
    • 接続のアイドルタイムアウト
      • 接続アイドルタイムアウトとは、ロードバランサーが接続を終了する前の、既存のクライアントまたはターゲット接続が非アクティブのままでデータの送受信が行われない時間のことです。

Read more...

MediaLiveでテンプレートから作製する

AWSメディアサービスで 動画配信のパラメータを変更して検証するの… 超面倒。

そもそも、都度チャンネル作らなきゃならない設定はなんなの。辛み。 CLIから作りたくなってきた。aws-cliをアップデートするとメディアサービスも使えるようになります!

最初に aws-cliをアップデートする

pip install -U awscli

チャンネルidを取得する

先にチャンネルのIDを確認します。WebUIだと [ MediaLive ]->[ Channels ]->作成したチャンネルのラジオボタンをクリック->[ ID ]の所の数字をメモ

aws medialive describe-channel --region ap-southeast-1 --channel-id チャンネルid > channel_sample.json

CLIからだと

aws medialive list-channels --region ap-southeast-1

で取得できます

チャンネル設定を変更する

上記の describe-channel はユニークであるべきidやチャンネルごとに振られるIPアドレス、ステータスなども出力されてしまいますので削除します。

  • PipelinesRunningCount
  • EgressEndpoints
  • State
  • Id
  • Arn

既にある設定を削除する

注) 下記を実行すると、既にあるチャンネル設定が一つ消えます。高速に検証するため、チャンネル設定を消して作ってを行っていますが、サービスするようになったら変更する必要があるでしょう。

上記のチャンネルidを取得する方法を利用して、既存のチャンネル設定を削除しています。

aws medialive delete-channel --region ap-southeast-1 --channel-id $(aws medialive list-channels --region ap-southeast-1 | jq -r '.Channels[].Id')

jsonからチャンネルを作る

aws medialive create-channel  --region ap-southeast-1  --cli-input-json file://channel_sample.json

チャンネルをスタートする

aws medialive start-channel --region ap-southeast-1 --channel-id $(aws medialive list-channels --region ap-southeast-1 | jq -r '.Channels[].Id')

チャンネルをストップする

aws medialive stop-channel --region ap-southeast-1 --channel-id (aws medialive list-channels --region ap-southeast-1 | jq -r '.Channels[].Id')
Read more...

AWS Organizationsで作った環境でVPCを作っていく

作業の流れ

  1. AWS OrganizationでOrganization Unit ( OU )作成、AWS Organization 内で AWSアカウントも作成
  2. VPC作成、サブネットを各AZごとに合計3つ作成
  3. VPC内でインターネットゲートウェイ作成, 作成したVPCに紐付け

AWS、アカウント作成直後のネットワーク設定

実作業

AWSの具体的なリソースは省略しています。得られた値で読み替えてください。

VPC作成
  • プロファイルは都度、変更してください
  • –cidr-block は 既存サブネットと被らないように取得してください
  • vpcのタグ名は都度、変更する

CLIでの作成はここが非常に参考になります

aws ec2 --profile test-site create-vpc --cidr-block "172.37.0.0/16" --tag-specifications  "ResourceType=vpc,Tags=[{Key=Name,Value=prod}]"
{
    "Vpc": {
        "CidrBlock": "172.37.0.0/16",
        "DhcpOptionsId": "dopt-08f0bf2e614f696d8",
        "State": "pending",
        "VpcId": "vpc-04d******"
        "OwnerId": "*************",
        "InstanceTenancy": "default",
        "Ipv6CidrBlockAssociationSet": [],
        "CidrBlockAssociationSet": [
            {
                "AssociationId": "vpc-cidr-assoc-",
                "CidrBlock": "172.37.0.0/16",
                "CidrBlockState": {
                    "State": "associated"
                }
            }
        ],
        "IsDefault": false,
        "Tags": [
            {
                "Key": "Name",
                "Value": "prod"
            }
        ]
    }
}

また上記のCLIで作成した際の 「 “VpcId”: “vpc-???“このVpcId の値は使うのでメモしておく

Read more...

AWS Organizations関連のメモ

AWS Organizations でアカウント管理してみる - ユニファ開発者ブログ

久しぶりに作業した時には、ざっと目を通す AWS Organizations の用語と概念 - AWS Organizations

手順

ログイン

https://console.aws.amazon.com/organizations/home#/accounts [ Organize account ]をクリック、組織を作成する

組織を作成する

[ Create organizational unit ]( [ 新規組織単位 ] )をクリック。 組織名を入力。ハイフンを利用可能だった。使わなくても良いが。

アカウント( というかOrganization のアカウント )の作成

[ Account ]->[ Add account ]->[ Create account ]

一旦、アカウントを作成、実際に使うOrganizationに紐付ける、という作業を行う

アカウント( というかOrganization のアカウント )の情報入力

  • [ アカウントの追加 ]->[ アカウントの作成 ]
  • フルネーム: hoge.co-dev
  • Eメール: system+dev@hoge.com
  • IAM ロール名: OrganizationAccountAccessRole [ 作成 ]をクリック

Organizationをアクティベートする

作成したOUの画面で、歯車アイコンをクリックする

Read more...

Dockerイメージの検証、更新する手順

できればインフラ構成についてもコード化したいため、CodeBuildのbuildspecでECSの設定を記述/更新していました。

このため、ECSの設定画面でポチポチと変更、検証することも可能ですが、Githubへのpush、CodeBuildで更新がかかると、ECSへの変更も元に戻ります。 (検証のために、ちょっとだけECS側で変更するのは無害です)

恒久的な変更はCodeBuild側へ変更するようにしましょう。

下記の手順はローカルでDockerイメージをダウンロードして検証する方法です。 「こうすると効率が良かった」というレベルのものです。

作業の流れ

  • ECRからイメージダウンロード
  • Mac上でコンテナを起動し、いろいろ検証( Dockerfileに必要な変更の検討など )
  • 必要な修正が決まったら、Githubのtestブランチにpush
  • Githubの testブランチへpushされるとCodeBuildでdocker buildが始まり、ECRにpushされる
  • ECRのDockerレポジトリのイメージIDをメモ
  • ECSで起動しているコンテナを変更して動作確認を行う という流れになります。

イメージをローカルにダウンロードする

プライベートなDockerレポジトリ(ECR)への認証を済ませる必要があります

認証情報の取得

bash/zsh:

aws ecr get-login-password --profile profile名 --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

fish:

aws ecr get-login-password --profile profile名 --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

手元で実行

(2019/02/22の内容で、環境変数などは将来的に変更する可能性があります)

docker run -p 10022:22 -e GITHUB_ENV=staging -e AWS_ACCESS_KEY_ID=XXXXXXXXXXXX -e AWS_SECRET_ACCESS_KEY=YYYYYYYYYYYYYYYYYYYYYYYY -it 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/image-name:latest /bin/bash

-p 10022:22 : リモートにSSHログインできるようにdocker内にsshdを立てました(将来的にはssmに切り替えたいですが)、sshdがlistenするポートが22番ポートなのですが、これをMacの10022にポートフォワードしています

Read more...

ECS開発環境の時刻を変えたい

背景

開発環境の時刻を変えたい時があります。 「その時刻になった時の振る舞いを確認したい」 「ある時間帯をターゲットにした開発を行いたい」 などです。 そういった開発の時だけ夜間に来る、というのは現実的ではないので、手軽に開発環境の時刻を変える方法があると便利です。

EC2 Linuxサーバですとdateコマンドなどで時間を変更できます( https://qiita.com/na0AaooQ/items/af6b853faf32c58c21d3 ) ただECS Fargate環境だと( システム時刻の変更に管理者権限が必要なため )上記の方法が使えません。 このため環境変数で開発環境のロケールを変更できるようにしてみました。

  • Dockerコンテナの起動、複数コンテナの連携方法などの設定などはタスク定義に行います。「タスク」という単位でサーバが起動します。
  • サービスという概念もあり、タスクが含まれます( 同じタスクを3セット立ち上げたりします)。 サービスにはロードバランサーとの接続など「Dockerと接続する外界」といった設定項目が含まれます。

※ この方法で時刻をずらした場合、なにかデプロイされる度に、設定は初期化されます。  なにか新しいリビジョンのものがCI経由でデプロイされると、この環境変数の設定は初期化されます。

手順

  • AWS Webコンソールにログイン
  • AWS_Fargateで目的の環境のタスク定義をここから探す( env27とか、そういったものです )
  • 最新のタスク定義をクリック
  • [新しいリビジョンの作成 ]
  • [コンテナの定義]のコンテナ[ nginx ]と[ php-fpm ]のなど変更をします。 `片方だけだとエラーがでるはずです。
  • [環境]の[Key]に環境変数名 TIMEZONE を入力、 値として任意のタイムゾーン( 例えば America/Argentina/Buenos_Aires のようなもの )を入力します。 ※ この『America/****』の文字列はスラッシュを含む全てです。
  • この地域はもうすぐ朝が来てしまう などで、他の地域を設定したい場合、 地図と時差を確認 して このIBMのページの文字列をコピペします。

インフラへの設定が反映されたかを確認するのは良い習慣です。確認する場合は、設定したコンテナをクリック、環境変数が設定されているかで確認できます。

  • [ 作成 ]をクリック *これでできた新しいリビジョンのタスク定義で、サービスを再起動します

時刻のロケールを戻す

2つの方法があります。 このページの[手順]の[新しいリビジョンの作成]のクリック後、 上記同様、nginxとphp-fpmの2つのコンテナの環境変数を変更します。 [コンテナの定義]のコンテナ[ nginx ]と[ php-fpm ]のそれぞれに対して設定を行います。 [環境]の[Key]のTIMEZONEの箇所で

  1. 環境変数 TIMEZONE の値を Asia/Tokyo にする
  2. 環境変数 TIMEZONE自体を消す( この環境変数が無かった場合は Asia/Tokyo を設定するようにしています )

2つの方法があります。どちらでも同じ結果になり、デメリットは発生しないので、どちらでも良いです。 強いていうと、 2 の方が綺麗になるので良いかと思います。

Read more...

ECS Fargate を CLIで操作

ECSのサービス設定、つくる作業が煩雑なので、CLIで自動化できないか検討。

aws ecs create-service --cluster example-dev-20181030-1 \
  --service-name env36\
  --task-definition env36\
  --desired-count 1\
   --launch-type FARGATE\
  --deployment-configuration maximumPercent=200,minimumHealthyPercent=100\
   --network-configuration "awsvpcConfiguration={subnets=[subnet-0123456789abcdef0,subnet-0123456789abcdef1,subnet-0123456789abcdef2],securityGroups=[sg-0123456789abcdef0],assignPublicIp=DISABLED}"\
   --deployment-controller type=ECS

aws cliのecsのcreate-serviceのオプションは多いのでCLIで作るのを想定してる感じある。

Read more...

AWS ECR へCLIでイメージをアップする

dockerコンテナをECR repository( 以下、ECR )にアップする

まず、Web UIにログインした後、上部メニューの[ サービス ]->[ Elastic Container Registry ]->[ リポジトリ ]->[ リポジトリの作成 ] からリポジトリを作成する。

リポジトリ名

『リポジトリ名は英字で始まる必要があり、小文字、数字、ハイフン、アンダースコア、スラッシュのみを含めることができます。』というルールがある。 スラッシュがつけられるので、組織名をつけた。Githubのレポジトリ名は大文字を許容するが、ECRは許容しないので小文字に変更する。

example/Hoge_Web -> example/hoge_web

AWS CLIがインストールされていなければインストールして、アカウント設定する

ECRへのアクセス設定をする

( これはリポジトリ作成時に説明が表示されます。一度、空のリポジトリを作成すると流れがより良く分かるかもしれません )

ECRにログインする

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

上記コマンドはそのまま実行できる形なので、出力を別途実行する必要はありません。

Dockerイメージをビルドする

カレントディレクトリにあるDockerfileを用いてイメージ作成。Dockerfileにある場所に移動してから docker buildする。

docker build -t example/hoge_api .

イメージにタグを付ける

docker tag example/hoge_api:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/example/hoge_api:latest

Dockerレポジトリを作成

aws ecr create-repository --region us-east-1 --repository-name hoge

実行例。 これは2017/12に出たばかりの fargateモードで検証するため、バージニア北部リージョンにレポジトリを作成している

Read more...

AMIについての雑多なメモ

  • 基本的に「AWSによる管理」のポリシーだけで構築可能ならそうする
  • ただ 「AWSによる管理」のポリシー だけだと、残念だが噛み合わない(権限が大きすぎる)のも多数あるので、自前で用意する。 ポリシー
  • 会社によっては、より厳密には「特定のリソースへアクセスできる、できない」もポリシーを作るか?という観点があるが、これはAWSアカウントレベルで分離する形の方が運用コストが下げられるので、避けていきたい。
  • ロールの作成方針は書く(方針なりIAMロール作成手順はあった方が効率良い、再利用性が高まる)。だが、台帳は作らないレベル
  • 「EC2につけられるIAMロールはひとつだけ」という制限がある。複数のポリシーを一つのロールにまとめるように作る

何かポリシーを作ったら下記に追加する( 作成した時の意図とユースケースくらい ) 作成したロールについては、現状、不要( ロールは、それぞれの管理画面、例えばEC2やlambda、RDSなどの管理画面側で確認できるので)

開発と本番は共通のポリシー。AWSアカウントは異なるので、アカウントの部分は「*」で記述して共通に使えるようにする。

EcsExec

ECS Fargate に AWS SSM の機能を用いて直接シェルを起動するのに作成した

ECS Fargate 用に既に作ってあったロール、 ecsTaskExecutionRole にポリシーを追加する想定

{
   "Version": "2012-10-17",
   "Statement": [
       {
       "Effect": "Allow",
       "Action": [
            "ssmmessages:CreateControlChannel",
            "ssmmessages:CreateDataChannel",
            "ssmmessages:OpenControlChannel",
            "ssmmessages:OpenDataChannel"
       ],
      "Resource": "*"
      }
   ]
}

Billing

経理情報を確認できるように作成 https://recipe.kc-cloud.jp/archives/6020 この情報を参考にした

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "aws-portal:ViewBilling",
        "aws-portal:ViewUsage"
      ],
      "Resource": "*"
    }
  ]

CloudWatchLogsWrite

  • 意図: ECSでサービスを作ったらCloudWatch logsに自動的にストリームを作成させたかった。
  • ユースケース: ECSのサービスを作った際に、自動的にログストリームを作らせたかった。ほか「自動的にログストリームを作成させたい」場合に使う
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:logs:ap-northeast-1:111111111111:log-group:/aws/codebuild",
                "arn:aws:logs:ap-northeast-1:111111111111:log-group:/aws/codebuild:*"
            ],
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ]
        }
    ]
}

ECSServiceRolePolicy

  • 意図: ECSでサービスを動作させるのに必要
  • ユースケース: ECSのサービスを作る際に、CloudWatchLogsWriteとセットで使う
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ECSTaskManagement",
            "Effect": "Allow",
            "Action": [
                "ec2:AttachNetworkInterface",
                "ec2:CreateNetworkInterface",
                "ec2:CreateNetworkInterfacePermission",
                "ec2:DeleteNetworkInterface",
                "ec2:DeleteNetworkInterfacePermission",
                "ec2:Describe*",
                "ec2:DetachNetworkInterface",
                "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
                "elasticloadbalancing:DeregisterTargets",
                "elasticloadbalancing:Describe*",
                "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                "elasticloadbalancing:RegisterTargets",
                "route53:ChangeResourceRecordSets",
                "route53:CreateHealthCheck",
                "route53:DeleteHealthCheck",
                "route53:Get*",
                "route53:List*",
                "route53:UpdateHealthCheck",
                "servicediscovery:DeregisterInstance",
                "servicediscovery:Get*",
                "servicediscovery:List*",
                "servicediscovery:RegisterInstance",
                "servicediscovery:UpdateInstanceCustomHealthStatus"
            ],
            "Resource": "*"
        },
        {
            "Sid": "ECSTagging",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateTags"
            ],
            "Resource": "arn:aws:ec2:*:*:network-interface/*"
        }
    ]
}

EC2RoleforSSM

EC2にAWS SSMを用いてsshできるようにロールを作成した。 AWSの管理ロールである、AmazonEC2RoleforSSM をそのまま割り当てた( AmazonEC2RoleforSSM をダイレクトにEC2のIAMロールに割り当てる事はできなかった )

Read more...

Athenaを簡単に使ってみる

Athenaは「s3にあるファイルをSQLで検索できる」というサービスになる。

既にs3にファイルの形で置かれている場合はAthenaで集計が可能だが、 コストが読み込んだファイルに応じてかかるので、なんらかの形で課金を抑える施策が必要。

日付でログを分けるような運用を考えてみる。

調査の流れ

下記がまとまっていて分かりやすい。 Amazon Athenaではじめるログ分析入門 - Qiita 上記で紹介されていた、下記のページ Amazon Kinesis Firehose, Amazon Athena, Amazon QuickSightを用いたVPCフローログの分析 | Amazon Web Services ブログ も、Athenaを理解するのに役立つ、ただ… ただnginxログ解析のために、

イベントを受けるlambda -> kinesis firehouse -> s3 -> Athena は冗長ではないか… もうちょっとラクはできないのか AWS Glue ? GlueはRedshift, RDS, S3をソースにできる。ただpython, scalaで記述するらしい。

私がソースにしたいのは、CloudWatchなのだ。

が、考えてみると、CloudWatch -> s3へエキスポートできれば良い。方法はあった。 Amazon S3 へのログデータのエクスポート - Amazon CloudWatch ログ

割とシンプルにありそう。たぶんAPIもあるだろう。 で、なぜkinesis firehoseか?を考えると、こちらはリアルタイム解析なのだと思う。 今回の要件については…. redashで解析できれば良いので日時で良かろう。

ただディレクトリ構造については悩ましい。 s3に吐き出すディレクトリ構造については、他のエントリを参考にしよう。

Amazon Kinesis Firehose, Amazon Athena, Amazon QuickSightを用いたVPCフローログの分析 | Amazon Web Services ブログ

クエリのパフォーマンス向上とコスト削減を目的とした、Athenaにおけるデータのパーティション化。
このセクションではLambda関数を用いてS3に格納されたAthena用のデータを自動的にパーティション化する方法を示します。
この関数はFirehoseストリームに限らず、他の手段でS3上に年/月/日/時間のプリフィックスで格納されている場合でも使用できます。
パーティショニングはAthenaにおいてクエリのパフォーマンス向上とコスト削減を実現するための3つの戦略のうちの1つです。
他の2つの戦略としては、1つはデータの圧縮、そしてもう1つはApache Parquetなどの列指向フォーマットへの変換があります。

Apache Parquetについては http://nagix.hatenablog.com/entry/2015/12/08/235512 が分かりやすかった。 解析には特定の列を用いて解析を行うが、あらかじめ列ごとのデータに分かれていた方が、特定の列のみを読み込むことができ、メモリ、検索の観点から早い。

Read more...

aws-cliが参照する環境変数

環境変数

AWS CLI の設定変数

CLIの初期設定について 認証情報とコマンド補完 TASK NOTES

||対象||設定ファイル変数||環境変数||オプション ||アクセスキーID||aws_access_key_id|| AWS_ACCESS_KEY_ID|| - ||シークレットアクセスキー||aws_secret_access_key|| AWS_SECRET_ACCESS_KEY|| - ||リージョン||region||AWS_DEFAULT_REGION||–region ||出力||output||AWS_DEFAULT_OUTPUT||–output ||プロファイル||profile|| AWS_DEFAULT_PROFILE|| –profile ||設定ファイル||-|| AWS_CONFIG_FILE|| - ||トークン||aws_session_token||AWS_SESSION_TOKEN||-

変数が参照される順序

  1. 環境変数
  2. AWS認証情報 ~/.aws/credentials
  3. CLI構成ファイル ~/.aws/config
  4. インスタンスプロファイルの認証情報

でも『環境変数を参照するプログラム』は沢山ある

という悩みを解決しそうな

AWSを操作(AWS CLIに限らない)する場合の環境変数設定作業を軽くする

Read more...

CloudWatch logsのログをinsightで検索

ログについては、ひとまずCloudWatch logsに投げ込む運用にしています(注1

このCloudWatch logsを高速に検索できるインサイトをCLIから使う紹介です( WEBでの使い方については[ CloudWatch ]->[ インサイト ]でいろいろ試していただきたいです ) 障害調査の場合、どのみちgrepすることになるのでCLIでの手順も残しておきます。

ログ取得

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatchLogs/latest/APIReference/API_StartQuery.html

--start-time 開始時刻をunixtime
--end-time 終了時刻をunixtime
--query-string 参考 https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html

クエリ(フィルタリング)について

検索する際の方法 limit 10 とか。

このためにインサイトを使っていると言えますが正規表現

| filter @message like /access_token=/

クエリ例

参考: サンプルクエリ - Amazon CloudWatch Logs

nginxのログのみを表示する

| filter @logStream LIKE /nginx/

ロードバランサからのヘルスチェックを除外する

| filter @message NOT LIKE /ua:ELB-HealthChecker/

ステータスコードが500番台のもののみを表示する

| filter @message LIKE /status:5\d+/

ログをパースして変数にセットする

| parse @message "time:*host:*forwardedfor:*req:*status:*size:*referer:*ua:*reqtime:*cache:*runtime:*vhost:*userid:*" as time, host, forwardedfor, req, status, size, referer, ua, reqtime, cache, runtime, vhost, userid

クエリ実行( ログ検索は時間がかかるため、後で別途getする必要があります)

bash環境(dateコマンドはbrewのcoreutilsを使用)

Read more...

MediaLiveをCloudWatchで監視する

背景

MediaLive ですが、いろいろなエラーを通知してくれます。

やれ「RTMP 接続が切れたよ」とか「オーディオ入力 or ビデオ入力が無いよ」とかですね。 通常、ライブ配信が始まる前は当然、MediaLive への入力は無いはずなので、通知は構わないのですが、 ライブ配信中に出ると、それはもうトラブルシューティングの情報の一つとして重要なものになります。 ( というか当初、エラーは出てるっぽいし、挙動はおかしいんだけど、どんなエラーが出てるか分からないケースがあって窮地な時がありました )

今は管理画面の[ channels ]->[ 目的のチャンネル ]->[ Alerts ]から確認できます。が、ログとして残しておくのは良い事だと思います。 このエラー出力のフォーマットは決まっている訳ではなく、たまに変わります。ので 『あー、エラー出力が変わったからアラートが上がらなくなったのね』、という事がログを残しておくと分かります。

手順

WebUI

SNS トピック作成

  • SNS のページ( https://ap-northeast-1.console.aws.amazon.com/sns/ )を開く

  • [ トピック ]->[ 新しいトピックの作成 ]->トピック名の入力、私は[ MediaLiveEvent ]、表示名[ MediaLiveEvent ]と入れてみた

  • 作成したトピックの ARN をコピペ arn:aws:sns:ap-northeast-1:123456789012:MediaLiveEvent

  • 同じ SNS 内の左側メニュー->[ サブスクリプションの作成 ]

  • [ トピック ARN ]に先程作成した MediaLive のトピックの ARN を入力

  • プロトコル メール(ほかにも lambda とかから Slack に送信できたりする)

  • エンドポイント : 自分のメールアドレス

はじめてのアラートメール設定の場合、AWS から確認のメールが飛ぶ

  • [ AWS Notification - Subscription Confirmation ]という件名のメールがあったらメール本文内のリンクをクリック

CloudWatch

  • cloudwatch のページに移動*
  • [ イベント ]->[ ルールの作成 ]
  • [ イベントパターン ]になってること
  • [ カスタムイベントパターン ]に変更 カスタムイベントパターンの内容としては下記を入力
{
  "source": [
    "aws.medialive"
  ]
}
  • 右側の[ ターゲットの追加 ]->[ SNS トピック ]に変更->[ トピック ]はプルダウンメニューから先程、作成した SNS のトピックを選択
  • [ 設定の詳細 ]
  • ルールの定義
  • 名前: 任意
  • 説明: 任意
  • [ ルールの作成 ]
  • メールボックスを確認

CLI

参考: SNS をコマンドラインから設定する : 電子の密林を開拓する

Read more...

ローカルサーバからCloudWatchに送信してアラートを設定する

CloudWatchのアラートを設定する方法

ここでは各環境向けにCPUとメモリ使用率のアラートを設定する方法を共有します。以下で説明する alarms.shalarm_mem_template.jsonalarm_cpu_template.json の3つのファイルを用いて作業します。

alarms.sh

各ECSサービスのアラームの設定をするShell Scriptです。 alarms.shの名前で以下の内容のファイルを作成します。 このスクリプトでは現在作成されている環境を全て取得し、そのそれぞれに対して、すでに同名のアラームがある場合には更新、 存在しない場合には新規にアラームを作成します。 そのため新しい環境を追加し、CPUおよびメモリ使用率のアラートを設定したい度に実行する必要があります。

#!/bin/bash
services=$(aws ecs list-services --cluster=test-dev-20181030-1 | jq -r .serviceArns[] | sed  s#.*/##g)
THRESHOLD_MEM=70
THRESHOLD_CPU=70

for service in ${services[@]}; do
  SERVICE=$service THRESHOLD_MEM=$THRESHOLD_MEM envsubst < ./alarm_mem_template.json > alarm_mem.json
  SERVICE=$service THRESHOLD_CPU=$THRESHOLD_CPU envsubst < ./alarm_cpu_template.json > alarm_cpu.json
  aws cloudwatch put-metric-alarm --cli-input-json file://alarm_mem.json
  aws cloudwatch put-metric-alarm --cli-input-json file://alarm_cpu.json
done

使い方

alarms.sh を作成したディレクトリに alarm_mem_template.jsonalarm_cpu_template.json をそれぞれ以下の内容で作成します。

alarm_mem_template.json

{
  "EvaluationPeriods": 3,
  "TreatMissingData": "missing",
  "ComparisonOperator": "GreaterThanThreshold",
  "ActionsEnabled": true,
  "AlarmActions": [
    "arn:aws:sns:ap-northeast-1:123456789012:alert2Slack"
  ],
  "OKActions": [
    "arn:aws:sns:ap-northeast-1:123456789012:alert2Slack"
  ],
  "Namespace": "AWS/ECS",
  "Period": 60,
  "Threshold": ${THRESHOLD_MEM},
  "AlarmName": "Memory Utilization of ${SERVICE} alert to Slack",
  "Dimensions": [
    {
      "Name": "ClusterName",
      "Value": "test-dev-20181030-1"
    },
    {
      "Name": "ServiceName",
      "Value": "${SERVICE}"
    }
  ],
  "DatapointsToAlarm": 3,
  "Statistic": "Average",
  "MetricName": "MemoryUtilization"
}

alarm_cpu_template.json

{
  "EvaluationPeriods": 3,
  "TreatMissingData": "missing",
  "ComparisonOperator": "GreaterThanThreshold",
  "ActionsEnabled": true,
  "AlarmActions": [
    "arn:aws:sns:ap-northeast-1:123456789012:alert2Slack"
  ],
  "OKActions": [
    "arn:aws:sns:ap-northeast-1:123456789012:alert2Slack"
  ],
  "Namespace": "AWS/ECS",
  "Period": 60,
  "Threshold": ${THRESHOLD_CPU},
  "AlarmName": "CPU Utilization of ${SERVICE} alert to Slack",
  "Dimensions": [
    {
      "Name": "ClusterName",
      "Value": "test-dev-20181030-1"
    },
    {
      "Name": "ServiceName",
      "Value": "${SERVICE}"
    }
  ],
  "DatapointsToAlarm": 3,
  "Statistic": "Average",
  "MetricName": "CPUUtilization"
}

上記2つのファイルがある状態で $ ./alarms.sh を実行すると、各環境のCPU、メモリの使用率のアラートが設定することができます。

Read more...

CodePipeline、ブランチごとデプロイ

基本、下記をなぞる。 が、「artifacts として事前準備で作成したタスク定義ファイルを指定します。」という表現だけが違う、気がする。 AWS CodePipelineがECSへのデプロイをサポートしたのでやってみる - Qiita

ECSのタスク定義に使用する( aws ecs register-task-definition –cli-input-json ./imagedefinitions.json で使用する )ファイルのフォーマットと artifactsのフォーマットは異なる。 [ The image definition file image definitions.json contains invalid JSON format ]というエラーが出る。

構成

  • Githubのあるブランチにgit pushすると、CodePipelineが反応する
  • CodePipeline経由で、CodeBuildが起動、DockerイメージをビルドしてECRにdocker push、ECRのタスク定義も更新して新しいイメージが見えるようにする
  • 開発者が見る、URLはALB -> ECSインスタンス -> ECSコンテナ という形でアクセスする
  • ALBはリクエストヘッダ中のホスト名の箇所で特定のターゲットグループに振り分ける設定にする
  • むやみにALBインスタンスを増やさない

作業の流れ

ECRでDockerレポジトリを作成、Dockerイメージをビルドして、Dockerレポジトリに入れる。 Dockerレポジトリにあるイメージを用いて、ECSのタスク定義を行う。

CodePipelineは設定を行えば、定期的にGithubの特定のレポジトリを監視して、 変更があったらDockerイメージをビルドできる。この際、『どのようにビルドするか』を Gitレポジトリのトップディレクトリにある buildspec.yml に従って行う。このbuildspec.ymlを用意しておく。 あらかじめGithubに目的のブランチを作っておく( でないとCodePipelineの設定時に、ターゲットのブランチがプルダウンメニューに現れない ) CodePipelineの設定を行い、自動ビルドを回し始める。

手順

  1. 対応ブランチごとにECRのリポジトリを作成する

https://ap-northeast-1.console.aws.amazon.com/ecs/home?region=ap-northeast-1#/repositories

ECSの管理コンソールにログイン ->[ リポジトリの作成 ]->[ リポジトリ名 ]にレポジトリ名[ api9 ]などを入れる。 このECRのレポジトリ名はGithubのブランチと揃えるようにした。

  1. Dockerイメージを作成する 既にあるDockerの作業環境を流用する。 Dockerイメージをビルドする。 このコマンドは ECRでDockerレポジトリを作成した後、[ プッシュコマンドの表示 ]で確認できるコマンドに沿う。
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

で表示されたコマンドを実行。Dockerfileがあるディレクトリに移動し

Read more...

redisのスケールダウン手順

redisのスケールダウン手順

手順

大きな作業の流れ。このページから複数ページに飛ぶようになっているので、作業ボリュームを見誤らないように。 https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/UserGuide/Scaling.RedisStandalone.ScaleDown.html

バックアップを取得する( m3インスタンス以上でないとバックアップは取れない模様。t2で検証したが取れなかった )

バックアップ自体は無停止( 内部的にはredisのBGSAVEが動いているようだ )

Webコンソールでのステータスは[ snapshotting ]に変わる。

バックアップから復元する

バックアップ完了後、バックアップイメージから新しく立ち上げ直す。 既存のクラスターは削除する。 エンドポイントを付け替える、などを期待して検証したが、そういう機能は無かった。

https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/UserGuide/backups-restoring.html#backups-restoring-CON

  • [ 管理コンソール ]->[ バックアップ ]->該当バックアップを選択->リストア
  • [ クラスターID ]は作成したいエンドポイントを考慮して正確に作成する

動作確認

キーが帰ってくるか

redis-cli -p 6379 -h test.hoge.ng.0001.apne1.cache.amazonaws.com  --scan --pattern '*'  | less
redis-cli -p 6379 -h test.hoge.ng.0001.apne1.cache.amazonaws.com GET _PHCRhoge.v2.user-status-11111
Read more...

MediaLive+MediaStore+CloudFrontで手軽に動画配信

2018年初頭 ライブ配信基盤を AdobeMdiaServer から MediaLive によるライブ配信に切り替えました。 2020年以降ですとVimeo Liveが有力候補です。

背景

  • 動画配信システムだけで良いのでシンプルに立てたい( カメラの映像を手っ取り早くユーザに届けたい )
  • 必要なときだけ配信システムを立てて終了したい。
  • 似たような案件ができたときに、似たようなシステムをスピーディーに構築したい
  • 現状、EC2 で AdobeMediaServer 立ててライブ配信している
  • AdobeMediaServer のバージョンアップ? <- それに伴う検証したいか、というと検証工数を割きづらい…
  • その点、AWS 上のサービスなら、後から機能追加があったりする。
  • 今回は使っていませんが、CMAF 対応が追加された。機能追加の検証をクラウドベンダがやってくれて、我々はその時間をもっと別な事に使える。あるいは早く帰れてハッピー。
  • 逆に「我々は配信方法で独自のチャレンジをして差別化を狙うぜ」には向いてない(現状、弊社的にそこでチャレンジはしてない)その観点でのチャレンジは EC2 上で構築した方が様々な戦術がとり得る
  • 何か仕様変更に伴う負荷上昇(対応ビットレートの追加とか)に対する検証工数がビジネスに繋がりにくい

なぜ、MediaService?

  • AWS で費用をまとめられる。あとトラフィックが増えた場合、ネットワーク費用のディスカウントができるかもという。
  • lambda から配信システムの起動/終了とかできそう
  • Azure も魅力的に見える。ただ CLI や API での操作ってどうやるんだろうか、という調査に時間とられそうだった(その点、AWS なら手軽に CLI で操作できるのは知っていった)

システム構成

カメラ -> エンコーダー -> MediaLive -> MediaStore -> CloudFront -> Safari

CDN でコストを下げつつ、ライブ配信したい構成ですね。

それぞれの役割は

  • MediaLive: RTMP などカメラからの情報を受け付ける。目的の動画フォーマットにエンコードする。ただ、これ自体にはストレージ機能は無い。

  • MediaStore: CloudFront と経由するためのストレージ

  • CloudFront: MediaStore に貯められた

それぞれを構築する順序だが、MediaLive の設定で「どこに動画データを貯めるのか」という設定が必要なため、 MediaStore の設定から行う

Read more...

lambdaのあれこれ

上限値

Lambda 関数の同時実行 - AWS Lambda

初めてのLambda

初めてのJavaScript、初めてのAWS Lambda

invokeする時のオプション

ブラウザから直接invokeする、という方法

AWS Lambdaのコードをローカルで実行する

この方法は導入した方が良さそう。デバックスピードを上げられる。 AWS Lambdaのための関数のローカル開発とテスト

handlerに渡ってくるeventとcontextというオブジェクトについての補足
event: 実際に渡ってくるイベントのデータ(S3のアップデートとかKinesisのレコードとか)。
context: Lambda functionの呼び出しコンテキスト。done()というAPIを呼び出すと関数が終了するのだが、コードをちょっと追いきれてないのでとりあえず単純にreturnするだけな感じにstub化。ちなみにcontextオブジェクトのダンプは以下のとおり。done()の中で呼び出されているpostDone()は後で追ってみる。

AWS Lambdaの関数をnpmでパッケージ管理

CLIで使う

http://qiita.com/toshihirock/items/8d06a524df79e7bb675c

  • Role作成
  • function作成( ファイルのアップロード )

Scheduleイベントで

EC2を自動起動終了

Amazonのサイトの説明、aws-cliで設定している

ユーザがEC2を起動 => CloudTrailがEC2起動を検知してS3バケットにログ記録 => Lambdaファンクション起動 => ログから実行ユーザを特定してEC2にタグ付け

LambdaでEC2作成者をタグ付けする

AWSへの接続に使う

AWSのリファレンスを見て、左側のメニューから使いたいサービスをクリック

トラブル集

node.jsでLambdaを実装した時のトラブル&解決策集

Read more...

AWS MediaLive + MediaPackageを使ってライブ配信

目的

2017/11 にリリースされた AWS メディアサービスを使って、ラクして動画配信したい。 できる限り遅延は無い方向で! まずざっくりとした使い方を把握して、どの程度、細かく設定できるのか知りたい! ( 実際のスマホでの確認までではなく、PC 上でエンコードされたライブが見えるところまでが今回のゴール )

作りたいシステム構成

ライブカメラ -> Wirecast -> RTMP(ないし RTSP) -> エンコーダー -> CDN -> ユーザ

CDN 使うと大規模に安く配信できるので使いたい。が、当然できる限り遅延は少なくしたい。

感想

あとマルチビットレートの設定が最初から入っているのとか、冗長化を初めから考慮されてる設定は素敵。 2017/12/04 時点では、MediaPackage で選択可能な配信フォーマットは HLS のみでした。Mpeg-DASH とか必要な場合は、対応待ちです。

ただ、UI というか画面遷移が迷うところが多いし、一通り設定が完了しないと、 カメラからのデータを送れないしで、挫けそうになりました。この辺は時間が解決してくれるよ!という気持ちで。

背景

EC2 で wowza や AdobeMediaServer 立てて運用するのはもちろんありだし、カスタマイズ性はこちらの方が高そうではある(インスタンスプランも選択できるし) が、運用コストはかかるのでありできれば減らしたい。

AWS メディアサービスって?(複数サービスの集合でした)

参考 クラウドベースの映像処理、保存、収益化 classmethod 様

2017/12 現在、MediaConvert、MediaLive、MediaPackage、MediaStore、MediaTailor という 5 つのサービスで構成されています。 このうち、自分に必要そうな『MediaLive』『MediaPackage』のみを使ってみました。 VOD、および他動画解析サービスなどと連携する場合は S3 に保存する MediaStore も併せて使う必要があるかもしれません。

設定方法

MediaLive について

(先に MediaPackage から設定する必要があります ) 当初、名前に Live ってあるし、MediaLive だけで完結できるか?と思いきやできず… なんか、CDN から見えるはずのオリジンサーバに該当する設定が無くね? どこで作るの? と見つからなかった。 MediaLive は「カメラから入ってきたデータをエンコードして Push する」という機能までなので、 それを「CDN などから Pull するための機能は『MediaPackage』が担当する」という事に気づかなかった。ので先に MediaPackage の設定から行う必要があります。

Read more...

AWS SQSを使う際に調べた事

API リファレンス

Class: AWS.SQS — AWS SDK for JavaScript

送信/受信/削除

AWS SDK for Node.js を用いた SQS の操作 – ゴミ箱

FIFO になって情報古くなってる面もあるが有益な情報

【AWS】SQS をただただ触ってみただけの話 - ニクニクドットミー Amazon SQS を利用する前に抑えておくべき 7 つのポイント - Qiita Amazon SQS を使う前に知っておきたい基本的なこと - Qiita Schoo の非同期パイプライン処理について - Qiita

『ロングポーリングして』という話は下記でも触れてる(一番下の方) フレクトのクラウド blog(New): lambda から lambda を起動するリレー方式 SQS コンシューマ

ショートポーリングの場合、キュー内のメッセージ数が少ない(1000以下など)場合、
キュー内のメッセージ数で重み付けされたサンプル数のサーバにしか問い合わせにいかないため、
MaxNumberOfMessagesに指定した数より少ないメッセージしか返ってこず、
キュー内のメッセージ数が極めて少ない場合、メッセージが返却されないことがあるため、
繰り返しreceiveMessageを発行する必要がある。

という理解であってるんですかね?

ロングポーリングの場合はどうなんでしょうか? 次の記述が見つかりました。
どうやらロングポーリングの場合、上記の問題は発生しないようです。

(receiveMessageのWaitTimeSecondsを1以上にすると、ロングポーリングになる)

Lambdaはコンピューティング時間で課金されるため、なるべく「待ち」の時間は減らしたいところですが、ショートポーリングで1,2件づつメッセージを処理するよりは効率が良さそうです。

ログポーリング必須…

ロングポーリングを利用する(これは必須。劇的にリクエスト数が改善されます)
ロングポーリングは管理画面から設定できるので簡単。
送信側はバッチリクエストを利用すると良い(SendMessageBatch)
受信側も複数メッセージを一度に受信すると良い(MaxNumberOfMessages)

FIFO に関する情報

【新機能】Amazon SQS に FIFO が追加されました!(重複削除/単一実行/順序取得に対応) | Developers.IO FIFO/重複排除のイメージがつかみやすい

Read more...

CloudFrontに関する雑多なメモ

障害時の対応に付いて

AWS - Amazon CloudFront の障害に備えてフェイルオーバーを設定する

ログフォーマット

s3, MediaPackageをオリジンとして使った時

ウェブディストリビューションでの Amazon S3 オリジン、MediaPackage チャネル、およびカスタムオリジンの使用

TTLがどのように効くのか

【新機能】Amazon CloudFrontに「Maximum TTL / Default TTL」が設定できるようになりました! | Developers.IO

パスパターンはワイルドカード

このため、HLSを配信するCDNは様に設定しました。

/studio*-lq.m3u8
/studio*.m3u8

重要 エラーページについて

『どの程度エラーページを保持するべきか』という設定がある

エラーレスポンスのカスタマイズ - Amazon CloudFront

CloudFrontのエラーキャッシュのTTLを変更する - Qiita

カスタムオリジンの話 別ドメインをオリジンとする。大抵のサービスはこれなのではないか

カスタムオリジンの場合のリクエストとレスポンスの動作 - Amazon CloudFront

初期設定

参考 キャッシュしないCloudFrontを設置する | // sakura note

Minimum TTL / Maximum TTL の話 一覧がある

【新機能】Amazon CloudFrontに「Maximum TTL / Default TTL」が設定できるようになりました! | Developers.IO

「Mimimum TTL / Maximum TTLはヘッダより強い」
「ブラウザのキャッシュはヘッダが優先される」
「何も設定しなければDefault TTLの値になる」
くらいのざっくりで覚えておいて、実際に設定する際にこの記事を参考にして頂ければと思います。

CDNのレイテンシ比較

Is TLS Fast Yet? コアな人々が反応してる

Read more...

cloudwatchメモ

クォータ

上限値

EC2 から Logs に飛ばす方法

結構、簡単に飛ばせる。 AWS CloudWatch Logs エージェントで Amazon EC2 上の Nginx の access.log , error.log , php-fpm error.log , Linux の messages , secure ログを収集する

セットアップ

推奨 (CloudWatch agent)

CloudWatch Logs エージェント (awslogs) は非推奨になったため、現在は統合された CloudWatch agent を利用する方が安全です。インストールと設定は公式手順を参照してください。

EC2 の IAM ロールに下記を追加

CloudWatch Logs でのアイデンティティベースのポリシー (IAM ポリシー) の使用

実際のケースだと EC2 には既に IAM ロールが設定済みの場合が多いと思うので、下記を追記する形になる

[ IAM ]->[ ポリシー ]->[ ポリシーの作成 ]->[ JSON ]->テキストフィールドに下記の内容入り込んで[ Review Policy ] ポリシー名には[ CloudWatchLogs ]とした。

Read more...

MediaService関連で知ったこまごまとした事

RTMPの接続が切れた場合どうするか

チャンネルのグローバル設定にありそう

グローバル構成 - 入力損失の動作

グローバル構成設定。 Input Loss Behaviorフィールドは、AWS Elemental MediaLiveが入力ロスを処理する方法を変更します。 AWS Elemental MediaLiveは、入力が予定時刻内に到着していないことを検出すると、前のフレームを設定可能なミリ秒数(ゼロから永遠に)繰り返します。 その時間が経過すると、設定可能なミリ秒数(ゼロから永遠)の黒いフレームが表示されます。 その時間が経過すると、指定されたスレートまたは指定された色に切り替わります。 入力が再開されると、通常の取り込みが続行されます。

この動作を変更することができます。入力損失動作で、入力損失動作を選択します。 表示されるフィールドにはデフォルト値が表示されます。 必要に応じてフィールドを変更します。 後でデフォルトの動作に戻したい場合は、Input Loss BehaviorをDisabledに設定するだけです。

TSファイルを確認する

ffmpeg内のツールの ffprobeを使う -show_frames

フレームごとの情報を取得する( かなり出力されるのでlessで見る )

キーフレームを30秒ごとに入れると、videoとaudioで30フレーム分の情報を見ることになるのでかなり出力される。

ffprobe -show_frames hoge.ts  | less

フォーマットを確認する

❯ ffprobe -show_format hoge.ts
ffprobe version 3.3.2 Copyright (c) 2007-2017 the FFmpeg developers
  built with Apple LLVM version 8.1.0 (clang-802.0.42)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.3.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-libmp3lame --enable-libx264 --enable-libxvid --enable-opencl --disable-lzma --enable-vda
  libavutil      55. 58.100 / 55. 58.100
  libavcodec     57. 89.100 / 57. 89.100
  libavformat    57. 71.100 / 57. 71.100
  libavdevice    57.  6.100 / 57.  6.100
  libavfilter     6. 82.100 /  6. 82.100
  libavresample   3.  5.  0 /  3.  5.  0
  libswscale      4.  6.100 /  4.  6.100
  libswresample   2.  7.100 /  2.  7.100
  libpostproc    54.  5.100 / 54.  5.100
Input #0, mpegts, from 'hoge.ts':
  Duration: 00:00:01.06, start: 27410.447556, bitrate: 1105 kb/s
  Program 1
    Stream #0:0[0x1e1]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(progressive), 320x240 [SAR 4:3 DAR 16:9], 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #0:1[0x1e2](und): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 192 kb/s
[FORMAT]
filename=hoge.ts
nb_streams=2
nb_programs=1
format_name=mpegts
format_long_name=MPEG-TS (MPEG-2 Transport Stream)
start_time=27410.447556
duration=1.064000
size=147016
bit_rate=1105383
probe_score=50
[/FORMAT]
Read more...

aws/codebuild

CodeBuildで設定した方が良さそう環境変数リスト

※ サービス固有に設定した方が良さそうな環境変数もあるので注意が必要( たとえば外部サービスの鍵など )

変数用途
${AWS_ID}開発と本番で共通のbuildspec.ymlを利用したい。それぞれAWS IDが異なるので環境変数で設定可能にする。
${API_ROOT}開発時に参照するエンドポイントと本番系は異なるため開発: dev.hoge.com 本番: wwww.hoge.com
${NODE_ENV}開発時はdev、本番時はproductionを指定することが多い( productionを設定していると、yarn install時、devDependinciesが無視される) devはMac上の開発環境で使い、ECSはproductionを用いる開発: dev 本番: production
${ECS_TASK}開発時はenv**という名前でECSのリソース(タスク定義、サービス)をアサインする。本番系はenvではなくサービス名称を用いるため異なる。開発: dev32 本番: wwwなど
${ECS_SERVICE}開発、本番で異なるため
${ECS_CLUSTER}ECSクラスター名も開発と本番で異なる(開発環境は都度クラスターを構築するのは工数がかかりすぎるので統一している。が本番系は別にクラスターを構築し、コンテナ間でリソースの上限やお互いのサービスの負荷の影響を与える可能性を考慮して、クラスターレベルで分離している)
${API_SHARED_ACCCESS_TOKEN}
${AWS_ACCOUNT_ID}
${AWS_DEFAULT_REGION}
${HOST_NAME}
${IMAGE_REPO_NAME}
${IMAGE_TAG}
${PORT}
${WWW_ROOT}

ECRのタグ( buildspec内でdocker pushしている )ポリシー

開発用のECSタスク定義で使用するDockerイメージには dev のタグをつける

イメージに対しては必ずタグをつける( タグがないイメージにアクセスしにくいので、実質的にバックアップの意味にもならない。

Read more...

aws/codebuildで設定を複製する

CodeBuildの設定を複製する

環境固有の環境変数の修正がある。

既存の設定情報を取得する

aws codebuild batch-get-projects --names hoge-web | jq '.projects[0]' > ~/original.json

取得したjsonファイルを修正する

比較として、CodeBuildを作成する際に参考になるjsonは aws codebuild create-project –generate-cli-skeleton で取得可能

取得したjsonと –generate-cli-skeleton で取得した雛形を比較しながら、 取得したjsonを修正する。

  1. name を修正
  2. arn は新規に割り振られるので削除
  3. environment.environmentVariables を修正 IMAGE_REPO_NAME SERVICE_NAME
  4. logsConfig.cloudWatchLogs.groupName を修正
  5. badge を削除

反映

aws codebuild create-project –cli-input-json file://修正したもの.json

Read more...

aws/rds

replicaが高負荷になった

replica1のmax_connectionsを確認したところ上限値1000でした

mysql> show global variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 1000  |
+-----------------+-------+
1 row in set (0.01 sec)

この障害はreplicaがボトルネックと断定できます。

AWS_RDS_Aurora_監査ログ取得のための変更

大体、ClassmethodのページのようにIAMを作成し付与します。

Classmethodのサンプルだと、全てのクエリをロギングする設定なので絞ります。 クラスターパラメータグループを変えます。

[ RDS ]->[ クラスター ]->[ aurora ]->[ DB クラスターのパラメータグループ ]のリンクをクリック->[ フィルタ パラメータ ]のテキストフィールドに[ audit ]を入力 下記の要素がリストアップするので変更します。都度、[ 変更の保存 ]をする必要があります。

  • server_audit_events -> QUERY_DCL, QUERY_DDL, TABLE ここで、ロギング対象を絞ります。パラメータの詳細についてはここを参照
  • server_audit_excl_users -> 空欄 ( [If not empty, it contains the list of users whose activity will NOT be logged] 全てのユーザの変更を取りたいため空欄 )
  • server_audit_incl_users -> 空欄 ( [If not empty, it contains a comma-delimited list of users whose activity will be logged] )
  • server_audit_logging -> 1 ( ロギングを有効にする場合は 1 )
  • server_audit_logs_upload -> 1 (CloudWatch logsへログのアップロードを行う場合は 1 )

DBスナップショットの作成時のダウンタイム

Single-AZ DB インスタンスでこの DB スナップショットを作成すると、I/O が短時間中断します。この時間は、DB インスタンスのサイズやクラスによって異なり、数秒から数分になります。

結構ばらつきがあるのに注意が必要だ。

Read more...

CodePipelineを試す

CIを回すサービス

それほど設定は面倒ではなかった。CodePipelineのウィザードに従うと、必要なIAMの作成、CodeBuildのプロジェクトが一気通貫で作成される。

ただ、buildspec.ymlなど各種手順を構築するのが面倒ではある ( が、これは、会社やサービスのシステム構成によってデプロイ方法は異なるものなので、しょうがない。本質的な問題と言える。 この手のツールにありがちな「本質的な悩みに到達する前の作業に時間がかかる」といった悩みの時間は少ないと言える )

はまりポイント

git cloneできない。これsshの設定からやらねばならんか…

[Container] 2017/12/21 11:25:28 Running command git clone git@github.com:zemi/Docker_Dev.git
Cloning into 'Docker_Dev'...
Host key verification failed.

fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

参考

基本、これに添っていきたい CloudFormationで、ECSのCI/CD環境を構築した際のハマりどころ 〜CodePipeline,CodeBuild,KMSも添えて〜 - Qiita

CodePipeline, CodeBuildを使ってAmazon ECSへの継続的デプロイメントを試してみた | Developers.IO

ここが非常に参考になった、権限が足りない場合がある https://qiita.com/tiibun/items/f0045011c86efca254fc

高速化は –cache-from を使うようだ https://qiita.com/na-o-ys/items/7e7a7e4cde378fc54b32

手順

CloudFormationで構築した方が、作業早いし、再現性が高い、理想的といえる。 がGUIでやってみても、それほど時間がかかる訳ではないので残しておく

  • CodePipelineページ開く

名前

  • [ パイプラインの作成 ]->[ パイプライン名 ]

ソース

  • [ ソースプロバイダ ]は s3, CodeCommit, Githubが選択できる。Githubを選択
  • [ GitHubに接続 ]押すとGithubとの認証が走る模様->[ リポジトリ ]->[ ブランチ ]->[ 次のステップ ] ここでの疑問、パイプラインはブランチ単位で作成するものだろうか? できれば「新しいブランチができたら自動的に処理して欲しい」ぶっちゃけていうとRoute53で新しいブランチ名のついた検証用ドメインを作って欲しい。

ビルド

  • ビルドプロバイダは AWS CodeBuild, Jenkins, Solano CIが選択可能、私はCodeBuildを選択

Codebuildを選択すると、追加で設定可能なメニューが現れる。 これはCodeBuild側のプロジェクト設定( わかりづらいが、PipelineからCodeBuildのプロジェクトが作れるようになってる。慣れると一気通貫で設定ができるので、この方が効率良さそう ) [ 新しいビルドプロジェクトを作成 ]を選択、プロジェクト名も入力。

Read more...

ECS EC2タイプでの基本的なサービスの立ち上げ

ALB->ECSインスタンス->コンテナ->RDSとかRedis といった構成を構築する

  • ネットワークはECSデフォルトのブリッジをつかう
  • イメージ内には2つのポートをlistenするnginxが立っている。
  • ALBのリスナーでは、リクエストヘッダ内のパラメータを見て、人ごとに作られたターゲットグループに振る
  • ターゲットグループからECRのタスク、サービスに振られる。

作業の流れ

ECRにログイン

  • Dockerイメージ作成
  • ECRにコンテナイメージのpush
  • クラスターを作成( ECSインスタンスの入れ物的なもの )
  • タスク定義
  • タスク定義を元にクラスター内にサービスを作成

ECRにイメージをpush

ECRへのアクセス権を得るには下記出力を実行する

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

コンテナにタグつけ

docker tag example_web:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/example_web:latest

push

docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/example_web:latest

タスク定義

  • タスク定義名 : 何か入力
  • ネットワークモード : <default>

コンテナの追加

コンテナ名 : 任意

イメージ : ECRのページで確認。 あるいはdocker push で指定する先

メモリ制限 : ソフト制限 500MB / ハード制限 1000MB にした

参考

コンテナ用に予約するメモリのソフト制限 (MiB 単位)。
システムメモリが競合している場合、Docker はコンテナメモリをこのソフト制限に維持しようとします。
ただし、コンテナは必要に応じて、memory パラメーターで指定したハード制限 (該当する場合)、またはコンテナインスタンスの使用可能なメモリの、
いずれか先に達するまで、追加のメモリを消費できます。

このパラメータは、Docker Remote API の コンテナを作成する セクションの MemoryReservation と docker run の --memory-reservation オプションにマッピングされます。

コンテナ定義で memory と memoryReservation の一方または両方を 0 以外の整数を指定する必要があります。 両方を指定する場合、memory は
memoryReservation より大きいことが必要です。memoryReservation を指定する場合、
コンテナが配置されているコンテナインスタンスの使用可能なメモリリソースからその値が減算されます。それ以外の場合は、memory の値が使用されます。

たとえば、コンテナが通常 128 MiB のメモリを使用しているが、短期間に 256 MiB のメモリにバーストする場合は、
memoryReservation を 128 MiB に、memory ハード制限を 300 MiB に設定できます。
この設定により、コンテナは、コンテナインスタンスの残りのリソースから 128 MiB のメモリのみを確保できますが、必要に応じて追加のメモリリソースを消費できるようにもなります。

ポートマッピング ホストポート : 空 / コンテナポート 10080 / プロトコル TCP

Read more...

コンテナの再起動

ECSのある環境を再起動したい

いろいろな理由で再起動したいことはあります。例えば

  • SecretsManagerの変更したので再起動して反映したい
  • docker-php環境を更新したので、再起動して最新のdockerイメージで起動し直したい
  • 起動時のログを追いかけたいとき

などですね。

手順

1. タスク定義のリビジョンを上げる

  • AWS管理画面にログイン
  • 左上のサービス一覧から[ ECS ]を検索してクリック
  • 左側メニューから[ タスク定義 ]を選択
  • 目的の環境のタスク定義をクリック(env25など)
  • 一番新しいリビジョン( 数字の大きいもの )をクリック
  • [ 新しいリビジョンを作成 ]->[ 作成 ] ( この作成は失敗することがあります )

2. クラスター内の各サービスが参照するタスク定義のリビジョンを上げる

  • ECS管理画面の左側のメニューから[ クラスター ]を選択
  • [ dev-20181030-1 ]
  • サービス名のカラムから再起動したいサービス名をクリック(env25など)
  • 右上の方の[ 更新 ]をクリック
  • [ リビジョン ]のプルダウンメニューをクリック
  • 少しスライドして[ latest ]と書いてあるタスク定義を選択(1で作成したリビジョン番号を選択)
  • [ 次のステップ ]->[ 次のステップ ]…->[ サービスの更新 ]

以上でECSコンテナの再起動が行われます

※ 再起動ですが、結構時間かかります… 細かく『いまどういう状態なのか?』を確認する場合ですが、 この再起動はブルーグリーン方式で、ダウンタイムが無いように再起動するようにしています。

どのような順番で行われるかというと、

  1. ECSの該当サービスで追加のタスク( タスクの中には nginx, php-fpm, volumeなどのコンテナが含まれます )が追加されます。
  2. タスクはロードバランサーの中のターゲットグループの中に追加されます( EC2 -> ロードバランサー -> ターゲットグループで該当のサービス名が書いてあるターゲットグループを探す )
  3. dockerコンテナはターゲットグループに追加され、ヘルスチェックに成功すると新しいコンテナをheltyにし、アクセスを受け付け始め古いコンテナをdrainingします 上記の流れで『今、デプロイがどのような状態なのか?』を知ることができます
Read more...

AWS KMSで鍵を保存、取得する

AWS KMS を awscli から利用してみる

http://qiita.com/kanagi/items/2008aa9f43be26bd2746

classmethod AWS Key Management Serviceでキーの”管理”と”利用”を分離する

http://dev.classmethod.jp/cloud/aws/kms-admin-user/

AWS Key Management Service(KMS)の利用方法

2016/12/13 mackerelの監視のON/OFFに使用した

KMSのざっくりとした理解としては 「 暗号化、復号化の悩みとして『鍵を使って暗号化するのは技術的に可能』だが『鍵の保管場所』に困る」という点を解決するサービス、 という理解。

AWS KMSでの暗号化/復号化の手順はclassmethodのココが分かりやすい。

一度、aws-cliで復号化まで行う(15分程度)とよく分かる。 また暗号化されたciphertextはコードに埋め込んで使用する

下記にmackarelでの暗号化、復号化の方法ですが

[ IAM ]->[ 暗号化キー(Encryption Keys) ]->[ フィルター: ]で[ アジアパシフィック(東京) ]をクリック [ MackarelAPI ]をクリックし、[ ARN ]の値をメモする。 ( 2016/12/13時点の mackarelのマスターキーは[ arn:aws:kms:ap-northeast-1:123456789012:key/12345678-1234-1234-1234-1234567890ab ]だった )

ココの方法に従い、 aws-cliで上記のarnを指定して環境変数KEYIDにarnを指定する

export KEYID=arn:aws:kms:ap-northeast-1:123456789012:key/12345678-1234-1234-1234-1234567890ab

暗号化

aws kms encrypt --key-id $KEYID --plaintext 'mackarelのAPIキー'

下記の内容が出力される

{
  "KeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/12345678-1234-1234-1234-1234567890ab",
  "CiphertextBlob": "himitu"
}

CiphertextBlobをコード側で利用する。 node.jsでのコードは下記が参考になる。

Read more...

Route53

新しいドメインの設定

どこかでドメインを取る

Route53 の設定は https://qiita.com/Yuki_BB3/items/effdf1bb38263bfef82a を参考にした

CLI でいろいろ

ゾーン ID の取得

ZONENAME="example.net."  # 最後に「.」ドットをつけるの重要... 30minほど悩んだ...
aws route53 list-hosted-zones | jq -r ".HostedZones[] | select(.Name == \"${ZONENAME}\") | .Id"     # bashの変数を読むためにダブルコーテーションをクオートする

参考 上の list-hosted-zones の内容

aws route53 list-hosted-zones
Read more...

ALBだけでメンテナンス画面を表示させる際の注意

なるべくサービス側のシステムを触らずにALBだけでメンテナンス画面を出したかった

参考: FixedResponseActionConfig (ALB)

• Fixed response のメッセージボディは 1024 バイトまで

• HTML を入れる場合はサイズ制限が厳しいので、必要なら minify して縮める

• CDNキャッシュ初期化は必要なドメインすべてで行う必要がある

Read more...

AWS EC2 オートスケール

EC2のオートスケールは、EC2のWebUIの下記の要素で作成する

  • AMI <- ami-idを確認する
  • AUTO SCALING
  • 起動設定 <- 主にEC2の起動設定、どのAMIからEC2インスタンスを作成する、spotインスタンスにするか、など。複数作成して切り替える事が可能。
  • Auto Scalingグループ <- 主にネットワーク周りの設定

起動設定を作ってから、AutoScalingグループを作成する。 [ AutoScalingグループ ]には「どのAMIからEC2インスタンスを作成するか」という[ 起動設定 ]を切り替えることができる。

高負荷時のオートスケールにかかる時間は5分から6分程度、EC2インスタンス起動に通常、120秒ほどかかる事を考えると、 負荷の検知、スケールアウト準備、インスタンス起動、サービス開始、と妥当な時間のように思う。

が、ライブ開始前と21:00の負荷の際にはあらかじめサーバを足しておきたい。この設定は [ AutoScalingグループ ]->[ スケジュールされたアクション ]で設定可能。

※ このスケジュールされたアクションを設定する際の [ 開始時刻 ]の注意点は

  • デフォルトで翌日の設定になってる
  • 一度開始時刻を設定しようとすると、CRONの設定が消える という点が注意点。スケジュールが実行されないケースがあった。

実際にスケジュールが実行されたかどうかは[ アクティビティ履歴 ]を見ると分かる

Read more...

AWS EC2メモ

インスタンスタイプごとのネットワーク帯域

iperfなどで計測する。

iperf -c %LOCAL_IP_ADDRESS% -t 60

EC2 – EC2 間 は5Gbps程度 参考 水門は開いた – EC2 インスタンスのネットワーク帯域幅が増大

起動時、パッケージのセットアップがうまく行かない場合

/etc/sysconfig/cloud-init の package_setupの項目をnoにする。

参考 VPC内にEC2を立ち上げようとしてcloud-initのpackage_setupでハマる

チェックポイント

EC2
  • 余計なセキュリティグループがついてないか、つまり余計なポートが空いてないか

  • opsに余計なのがついてたり( port 22 が、まだ空いていたり )

  • AZ分散しているか?

  • たまに「サブネットを作ってなかった」というミスがあり、この場合、サブネットが寄ってしまっている。

  • opsにはEIPが割り当てられているか

  • パラメータストアにSLACKの値は設定しているか

ロードバランサー
  • port 443 でリスナーが立っているか?

  • 『CloudFront障害』のケースを考えると、オリジン側もHTTPではなくSSLで受ける必要がある。

  • Deletion Protection をonにする。削除されなくするやつか

ターゲットグループ

ELBのtarget groupにおける stickness が無効になってたので30秒で有効に変更する

EC2 上に Nginx + PHP + Phalcon 構築手順

nginxの UID:GIDを揃える

下記のファイルで必要になる。 UID:GID統一の方法としては

  1. NIS or LDAP 導入
  2. 追加するアプリのUID:GID全て統一
  3. 必要なアプリのUID:GID統一 があるが、今回は3にした。基本的には『サーバ間でファイルをコピーする場合』にUID:GIDが揃ってないと、動作しないので。 ( 上場してパスワード更新が求められるようになったらldap導入するか検討しても良いかもしれない )

パッケージインストール

git インストール
yum -y install git gcc make libtool

カーネルパラメータ追加

sudo vi /etc/sysctl.conf

下記を追記

Read more...

AWS WAFメモ

手順

IPアドレスフィルタ

  • https://console.aws.amazon.com/waf/ を開く

  • [ IP Address ]->[ Create Condition ]

  • 名前は対象とフィルタリングルールが分かるように

  • 左側の[ Rule ]

  • [ dose ]->[ origin from an IP adress in ]->IPアドレスグループ

  • [ Web ACLs ]->[ Create web ACL ]

  • Web ACL name

  • Region

  • Resource type to associate with web ACL -> ALB

  • AWS resource to associate -> 付与するALB

  • [ Set up a web access control list (web ACL)]は、既にルールを作っているので、そのまま次へ

  • [ Create rules ]では作成済みのルールを選択->[ Add rule to ACLs ]

  • Action を Allow

    Read more...

AWS アカウント関連のメモ

[[Amazon Linuxの正体 ~タイムゾーン~ | サボり屋の技術メモ|https://angelndxp.wordpress.com/2012/06/25/amazon-linux%e3%81%ae%e6%ad%a3%e4%bd%93-%ef%bd%9e%e3%82%bf%e3%82%a4%e3%83%a0%e3%82%be%e3%83%bc%e3%83%b3%ef%bd%9e/]]

AWS rootアカウント

そもそも必要になるケースが少ない、ので触れる機会が少ないのでメモを残しておく

MFA周り

- 例えばスマホが壊れるケースなどが考えられる
- [AWSアカウントで多要素認証(MFA)できなくなった。電話認証も失敗した時の対処方法 - そろそろ本気を出しますか](https://that-is-nuts.com/archives/142)
- [スマホ交換したら、AWSアカウントで多要素認証(MFA)できなくなった→電話認証も失敗! | リーマンダッシュ](https://salaryman-dash.com/2020/11/08/aws%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%88%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%A7%E5%A4%9A%E8%A6%81%E7%B4%A0%E8%AA%8D%E8%A8%BCmfa%E3%81%A7%E3%81%8D%E3%81%AA/)

オフィシャルの情報

Read more...

AWSマーケットプレイスでのイメージ検索

AMI( HDDイメージのようなもの )の選択

AMIの選択はEC2を起動する際やここから検索できる ただ検索できた方が、なにかと自動化しやすい( わざわざブラウザで開かなくて良い )ので方法を残す

例えばAMI名に『KUSANAGI』を含むAMIを検索する場合

aws ec2 describe-images \
  --region ap-northeast-1 \
  --owners 'aws-marketplace' \
  --filters 'Name=name,Values=*KUSANAGI*'

例えば Amazon Linux の最新AMI IDが欲しい場合

Amazon Linux は SSM パブリックパラメータから取得する方が確実。 公式: Amazon Linux 2023 の AMI を取得する

Amazon Linux 2023 (x86_64) の例:

aws ssm get-parameter \
  --region ap-northeast-1 \
  --name /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 \
  --query 'Parameter.Value' \
  --output text

Amazon Linux 2 など他の系列は、該当するパラメータ名を公式一覧から確認する。

プロダクトコード、オーナーで検索する場合

「あるオーナーの更に、プロダクトごとに絞り込みたい」ようなケース。

オーナーは、大雑把にいうと「Amazonが所有者のもの( amazon )」と「それ以外( aws-marketplace )」な区分がある。

Read more...

AWSとヤマハのルーターでVPNを行う

多対地接続で、確実な帯域配分を行う

http://jp.yamaha.com/products/network/solution/advanced-qos-hierarchy-rtx5000/#kyoten_1

ヤマハのルータでの帯域制御は 優先制御帯域制御がある。 優先制御が、キューイング、で 4 つの優先度のキューにあり、最上位の 4 のキューが空にならないと 3 以降のキューが処理されないタイプ 帯域制御は、帯域で、最低限の帯域保証という形になる。

既存の設定は優先制御だった。 QoS のグラフは 2 点の問題がある。

  • そもそも rtmp プロトコルの処理も class2( デフォルトで全ての通信はここに含まれる )に含まれてしまう。つまりフィルタリングできていない。

  • これはフィルタリングルールを tunnel 内に移動しても同様だった。書籍どおり設定しているのだが。

  • [ 設定している帯域の何%か ]で表示する。つまり speed 100m のように帯域を絞らないと表示されない。

  • これは speed 100m のように帯域制限すれば class 2 の所にトラフィックのグラフが動くようになる。本来はプライオリティの高い 4 の所のグラフが動いて欲しいが

  • 更に、[ では 80, 443 ポートへの通信のプライオリティを下げてはどうか ]と試した段階でルータへの接続ができなくなった。

  • wifi ルータが死んだだけかもしれない。 仮に[ これが問題を引き起こしたのだ ]と考える( 考えなくても良いかもしれないが )と、結構、80, 443 への通信が多く。なにかウェイトがかかるような、特に wifi ルータが異常になるようなことなんだろうか

  • 2017/06/07 時点で ipsec sa policy …..(既存の設定に追加する形で) anti-replay-check=off は有効になっている。 と思ったら、Active 機の tunnel 201 の設定に入っていない。 が配信時間中なので、明日、設定を投入するようにしよう。

    Read more...

AWS SNSを使う

lambdaネタ

SNS + Lambda + Slack でアラート通知を受け取る - Qiita

障害時でも まずPush通知がされるまでの流れを把握

http://dev.classmethod.jp/cloud/aws/sns-mobile-token/ この中のフローが非常に参考になる。

大規模Push配信環境 メルカリの例

ハイパフォーマンスGaurun〜メルカリの大規模プッシュ配信を支えるミドルウェア〜 - Mercari Engineering Blog

Push通知が届かない場合

http://faq.growthbeat.com/article/60-push

  • 電源が入っていない
  • 証明書の有効期限が切れてる
  • デバイスのプッシュ通知ステータスがアクティブ(Active)になっていない
  • アプリがアンインストールされてる
  • 登録されているデバイストークンと環境(development/production)が一致しない

証明書の扱いは難しいらしい

http://faq.growthbeat.com/article/81-growthpush

具体的にエラーとなるのは、下記のような場合です:

iOSの証明書の有効期限が切れている

iOSの証明書が無効化されている。

AndroidのAPIキーのIP制限が設定されている

Androidの証明書が無効化されている

PHPでPush通知を実装する

http://qiita.com/toshiyuki_wada/items/a072ec557a49c6f8c00a

AWS CLIで取得する

http://qiita.com/tcsh/items/e2184f8c7c283e93b167

各メトリクスの説明

Amazon Simple Notification Service のメトリックスおよびディメンション - Amazon CloudWatch

NumberOfMessagesPublished 発行されたメッセージの数。
NumberOfNotificationsDelivered 正常に配信されたメッセージの数。
NumberOfNotificationsFailed Amazon SNS が配信に失敗したメッセージの数。
このメトリクスは、Amazon SNS が Amazon SQS、電子メール、SMS、またはモバイルプッシュのエンドポイントへのメッセージ配信の試行を停止した後に適用されます。
HTTPまたはHTTPSエンドポイントに対して配信が試行されるたびに、メトリクスが1つ追加されます。
他のすべてのエンドポイントの場合、メッセージが配信されないとカウントが1増加します (試行回数に関係なく)。
HTTP エンドポイントの再試行の数は制御できます。詳細については、「HTTP/HTTPS エンドポイントに対する Amazon SNS 配信再試行ポリシーの設定」を参照してください。

AWS CLI でトピックを作成する

aws sns create-topic --name test_20150715 --region ap-northeast-1

出力例:

Read more...