20190327のAWSに関する記事は11件です。

aws s3 lsを打っても応答が返ってこない時はregionを指定しよう

はじめに

AWS CLIを導入して、うまいことAPI叩けるかなーなんてとりあえずaws s3 lsを打ったりしますよね。
しませんか。そうですか。

打ったは良いが応答が返ってこない。
何かの権限が足りてない?
せめてエラーか何か返してよ、と思ったことが最近(1年半前)ありました。

いきなり結論

「--region <リージョン>」オプションを付けて打ってください。

例)
aws s3 ls --region ap-northeast-1

権限足りてなかったりしたら、ひとまずそういう趣旨のエラーが返ってきます。
状況が変わらなかったら、ごめんなさい。

蛇足

ちなみに、応答が返ってこない状態でも、数分待ってれば以下のようなエラーが返って来ます。
返ってこなかったら、ごめんなさい。

('Connection aborted.', error(10060, 'A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond'))

原因

CLIコマンドを実行したときに、アクセスする先のS3エンドポイントへの通信が行えないため起こります。
(ちなみに本事象はVPCエンドポイント経由でS3へのアクセスを試みる際に起こることを想定しています。)
(単純にセキュリティグループでアウトバウンドがふさがれている時などに同じ事象が起こるか?昔調べて気がしますが忘れました。優しい方教えてください。)

VPCエンドポイント経由で通信を行う際には、ルートテーブルにはターゲットにプレフィックスリストID、ゲートウェイにVPCエンドポイントを指定することになります。

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpce-gateway.html#vpc-endpoints-routing

エンドポイントを作成または変更するときは、エンドポイントを通じてサービスにアクセスするために使用する VPC ルートテーブルを指定します。ルートは自動的に各ルートテーブルに追加されて、送信先としてサービス (pl-xxxxxxxx) のプレフィックスリスト ID、ターゲットとしてエンドポイント ID (vpce-xxxxxxxx) が登録されます。その例を以下に示します。

送信先 Target
10.0.0.0/16 ローカル
pl-1a2b3c4d vpce-11bb22cc

プレフィックスリストIDはリージョン単位でのパブリックIPの集まりを表すものです。例えば東京リージョンのS3が取りうるIPの集まりを表しているとします。この場合、上記のルートテーブルにおいては、東京リージョン以外のS3への通信は定義されていません。リージョンを指定しないでaws s3 lsを打った場合、アクセス先のS3エンドポイントが東京リージョン以外だと解釈されると、うまく通信が行えないため、エラーが生じます。
(aws ls s3を打った時にどこに向けて通信を行うは、OSにより挙動が異なるようです。後述の参考サイト参照。aws configureの実行など、プロファイルでデフォルトリージョンを明示的に指定することでも回避できる事象です。)

終わりに

事象の切り分けの一助になれば幸いです。
当時自分がハマったのはHTTPプロキシがあったりVPCを跨いだりする構成だったので、泣きたくなりました。

参考サイト

VPC エンドポイント経由で S3 へアクセスする時の注意点
https://dev.classmethod.jp/cloud/aws/sugano-031-vpc-endpoint-to-s3/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

はじめてのAWS

AWSについての調査記録をざっくりまとめたものです。
※まだまだ勉強中につき追記するかもしれません。

1. AWSとは?

Amazonが提供しているWebサービスの総称。
ストレージやデータベース、サーバ、アプリケーションといった
様々なITリソースを利用することが出来る。

2. つかうための準備

2.1 アカウント作成

AWSを使うには、始めにAWSアカウント
IAMアカウントというものを作る必要がある。
上記二つのアカウントについて、事前に述べておく。

★AWSアカウント
AWS全般をつかさどるアカウント。
全てのリソースにフルアクセスできる。

★IAMアカウント
そもそもAWSアカウントだけでもAWSは始められる。が、
AWSの全リソースへアクセス出来てしまうため、多数のユーザーで
共有して使うのは好ましくない。
ソロ開発でも、万が一AWSアカウントが乗っ取られると全て使えなくなる為危険。

そこで、各ユーザーごとに出来ることと出来ないことを分けたり、さらに誰がどんな事を
行ったか履歴を管理出来るのがIAMアカウントである。

2.1.1 AWSアカウントの作成

これを作らないとIAMアカウントも作れない。
AWSアカウントの作成手順についてはこちらを参照。

※注意点
・アカウントの種類は、法人利用であれば、「プロフェッショナル」、
個人利用であれば「パーソナル」を選択すること。

2.1.2 IAMアカウントの作成

① IAMのページを開く
① 「個々のIAMユーザの作成」を選択して、「ユーザの管理」ボタンをクリック
③ 「新規ユーザーの作成」をクリック
④ ユーザ名を入力し、「ユーザーごとにアクセスキーを生成」のチェックを外す。外したら「作成」ボタンをクリック
⑤ 一覧に作成したユーザが表示されるのでクリック
⑥ 「認証情報」タブを選択し、「パスワードの管理」ボタンをクリック
⑦ カスタムパスワードの割り当てをクリックして、パスワードを二回入力し「適用」ボタンをクリック
⑧ 「認証情報」タブ内の「MFAデバイスの管理」ボタンをクリック
⑨ 「仮想MFAデバイス」にチェックを入れて「次のステップ」ボタンをクリック
⑩ QRコードを読み取って、表示された認証コード二つを入力し「仮想MFAの有効化」ボタンをクリック
⑪ 「完了」ボタンクリックで完了!

※これだけでは意味がないので、下記「グループを使用したアクセス許可の割り当て」を参照。

2.1.3 初期設定

いずれの設定もIAMのページから入れる。

ルートアカウントの MFA を有効化

AWSアカウントへ二段階認証を導入してセキュリティ面を強化する。

①「ルートアカウントのMFAを有効化」を選択して、「MFAの管理」ボタンをクリック
②「仮想MFAデバイス」にチェックが入っていることを確認し、「次のステップ」ボタンをクリック
③ 注意書きを読み「今後はこのダイアログボックスを表示しない。」にチェックを入れて「次のステップ」ボタンをクリック
④ QRコードを読み取って、表示された認証コード二つを入力し、「仮想MFAの有効化」ボタンをクリック
⑤ 「完了」ボタンクリックで完了!

グループを使用したアクセス許可の割り当て

権限を設定したグループを作成し、ユーザを所属させる。

① IAMのページを開く
②「グループを使用してアクセス許可を割り当て」を選択し、「グループの管理」をクリック
③「新しいグループの作成」をクリック
④ グループ名を入力し、「次のステップ」をクリック
⑤ 「AdministratorAccess」ポリシーにチェックをいれて、「次のステップ」をクリック
⑥ 内容を確認し「グループの作成」をクリック
⑦ グループ一覧から作成したグループをクリックし、「グループにユーザーを追加」ボタンをクリック
⑧ 作成したユーザを選択し、「ユーザーの追加」ボタンをクリック

IAM パスワードポリシーの適用

デフォルトのパスワードポリシーは緩いので、なるべく縛りを入れる。
① IAMのページを開く
②「IAMパスワードポリシーの適用」を選択し、「パスワードポリシーの管理」をクリック

詳しくはこちらを参照。

アクセスキーのローテーション

アクセスキーはIAMユーザ一つにつき2個作成出来る。
キー変更時には新たなキーを作成し、古いものを一時的に残しておくことで
アプリケーションやツールで使用するキーの更新時、更新漏れが分かりやすくなる。
詳しくはこちらを参照。

※パスワードとアクセスキーは異なるものである。
AWSのコンソールにサインインするときにはパスワードを、
AWSのコマンドやAPIを使うときにはアクセスキーが必要となる。
詳しくはこちらを参照。

3. AWSで使える基本機能(ざっくり)

基本的にAWSは使った分(時間等)だけ支払う「従量課金制」である。

3.1. EC2ついて

AWSが提供している「仮想サーバ」のこと。
色んなOSの仮想サーバを瞬時に用意することが出来る。
EC2用のHDDであるEBSとの併用もすべき。バックアップを行うときなどには必要。

3.2. RDSについて

AWSが提供している「リレーショナルデータベース構築サービス」のこと。
MySQL、PostgreSQL、MariaDB、Oracle BYOL、SQL Serverから使用するDBを選べる。
サーバーOSやミドルウェアの管理はAWS側が自動でやってくれる為、DBサーバー管理の手間が無い。

3.3. ELBについて

AWSが提供している「ロードバランサー」のこと。
サーバの処理を負荷分散して処理速度を上げたり、障害でシステム全体が
停止するのを防ぐために使用する。故にEC2との併用がメイン。

3.4. VPCについて

AWSが提供している「仮想ネットワーク環境」のこと。
DBやアプリケーションサーバを特定の所からしかアクセスできないようにする。
この設定が無いとどこからでもサーバにアクセス出来てしまう為必須。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[AWS]Athenaのコメントアウトの仕方とフォーマットについて

■概要

  • AWSのAthenaのコメントアウトの仕方と、フォーマットについて紹介する

■Athenaのコメントアウトの仕方

/* コメント記入 */

上記のように「/*」と「*/」で囲んだ部分がコメントとなります。

■Athenaのフォーマットについて

Athenaは「Presto」ベースのマネージドサービスです。

なので、Athena上で関数など使いたい場合は下記のリファレンスを参照してください。
(大概のものは揃っているので、是非下記を参考にしてください。)

https://prestodb.github.io/docs/current/

■最後に

以上、フィードバックやご指摘等いただけると大変ありがたいです!!よろしくお願いいたします!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel + Nuxt +Fargate にCodePipelineで継続的デプロイを実現する

前提

Laradock + Nuxt(SSRモード)をAWS Fargateで実行する

こちらでFargateで起動できていること

やりたいこと

githubのソースコードがmasterブランチにpushされた際にCodeBuildでDockerイメージをビルドし
Fargateにデプロイを自動化する
できればテストも実施する

参考

LaravelアプリケーションをローカルでもAWSでもDockerで動かす

LaravelアプリケーションをCodePipeline/CodeBuildでECSに自動デプロイする

Laravelのセッション管理にRedisを指定し、AWSのElastiCacheを利用する

手順

  1. リポジトリにDocker関連のファイルを追加し修正する
  2. buildspec.ymlを追加する
  3. ソースをpushしデプロイできるか確認
  4. buildspec.ymlにS3から環境に合わせた.envファイルを取得するコマンドを追加
  5. 再度デプロイし、DBとRedisキャッシュから値を取得できるか確認する

1. リポジトリにDocker関連のファイルを追加し修正する

Dockerイメージをビルドするために必要なファイルをlaradockからコピーしてくる

mkdir docker
cp -r ../laradock/nginx ./docker/nginx
cp -r ../laradock/php-fpm ./docker/php-fpm
cp ../laradock/docker-compose.production.yml docker-compose.production.yml

コピーしてきたらDockerfile-productiondocker-compose.production.ymlのパスを修正する

/{projectname}/docker/nginx/Dockerfile-production

COPY ./docker/php-fpm/laravel.ini /usr/local/etc/php/conf.d
COPY ./docker/php-fpm/xlaravel.pool.conf /usr/local/etc/php-fpm.d/
# php.iniをコンテナに配置する
COPY ./docker/php-fpm/php7.2.ini /usr/local/etc/php/php.ini
# ソースコードをコンテナにコピーする
COPY . .

/{projectname}/docker/nginx/Dockerfile-production

# nginxの設定ファイルをコンテナ内に配置する
COPY ./docker/nginx/nginx.conf /etc/nginx/
COPY ./docker/nginx/sites/ /etc/nginx/sites-available/
COPY ./docker/nginx/ssl/ /etc/nginx/ssl/
COPY ./docker/nginx/sites/default.conf /etc/nginx/conf.d/
# ソースコードをコンテナにコピーする
COPY . .

docker-compose.production.yml

version: '3'

services:
### PHP-FPM ##############################################
    php-fpm:
      build:
        context: .
        dockerfile: ./docker/php-fpm/Dockerfile-production
        # args:
        #   - LARADOCK_PHP_VERSION=${PHP_VERSION}
      expose:
        - "9000"

### NGINX Server #########################################
    nginx:
      build:
        context: .
        dockerfile: ./docker/nginx/Dockerfile-production
      ports:
        - "80:80"
        - "443:443"
      depends_on:
        - php-fpm

ビルドと同時にDockerコンテナを起動してみる

docker-compose -f docker-compose.production.yml build --no-cache nginx php-fpm
docker-compose -f docker-compose.production.yml up -d nginx

2. buildspec.ymlを追加する

build時の実行内容を記載する

touch buildspec.yml

buildspec.yml

version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - $(aws ecr get-login --no-include-email --region ${AWS_DEFAULT_REGION})
      ## イメージ名を定義
      - IMAGE_NAME_PHP_FPM=laradock_php-fpm
      - IMAGE_NAME_NGINX=laradock_nginx
      ## nginxとphp-fpmコンテナイメージのECRリポジトリURIを生成する
      - REPOSITORY_URI_PHP_FPM=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_NAME_PHP_FPM}
      - REPOSITORY_URI_NGINX=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_NAME_NGINX}
      ## ここは何をしてる?
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      ## docker-composeでbuildを行う
      - docker-compose -f docker-compose.production.yml build --no-cache nginx php-fpm
      #- docker build -t ${REPOSITORY_URI_PHP_FPM}:latest -f docker/php-fpm/Dockerfile-production .
      #- docker build -t ${REPOSITORY_URI_NGINX}:latest docker/nginx/Dockerfile-production .
      - docker tag ${REPOSITORY_URI_PHP_FPM}:latest ${REPOSITORY_URI_PHP_FPM}:$IMAGE_TAG
      - docker tag ${REPOSITORY_URI_NGINX}:latest ${REPOSITORY_URI_NGINX}:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push ${REPOSITORY_URI_PHP_FPM}:latest
      - docker push ${REPOSITORY_URI_PHP_FPM}:$IMAGE_TAG
      - docker push ${REPOSITORY_URI_NGINX}:latest
      - docker push ${REPOSITORY_URI_NGINX}:$IMAGE_TAG
      - echo Writing image definitions file...
      - IMAGE_DIFINITION_PHP_FPM="{\"name\":\"${IMAGE_NAME_PHP_FPM}\",\"imageUri\":\"${REPOSITORY_URI_PHP_FPM}:${IMAGE_TAG}\"}"
      - IMAGE_DIFINITION_NGINX="{\"name\":\"${IMAGE_NAME_NGINX}\",\"imageUri\":\"${REPOSITORY_URI_NGINX}:${IMAGE_TAG}\"}"
      - echo "[${IMAGE_DIFINITION_PHP_FPM},${IMAGE_DIFINITION_NGINX}]" > imagedefinitions.json
artifacts:
    files: imagedefinitions.json

CodePipelineを作成する

CodePipelineを新規作成する
image.png

リポジトリはgithubを選択する
image.png

AWS CodeBuildを作成し、プロジェクトを新規作成する
image.png

image.png

image.png

image.png

デプロイ先を「AmazonECS」を選択する

image.png

デプロイの設定を行う

image.png

ビルドが失敗するので環境変数を変更する

image.png

image.png

環境変数の定義

環境変数 AWS_ACCOUNT_ID

ビルドを実行する

ビルドを実行したら下記のエラーが発生

An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:sts::636990608596:assumed-role/codebuild-GuildApp-CodeBuild-service-role/AWSCodeBuild-c714c40b-8e5e-466d-9d97-fda2158797d4 is not authorized to perform: ecr:GetAuthorizationToken on resource: *
 [Container] 2019/03/26 16:04:29 Command did not exit successfully $(aws ecr get-login --no-include-email --region ${AWS_DEFAULT_REGION}) exit status 255
[Container] 2019/03/26 16:04:29 Phase complete: PRE_BUILD Success: false
[Container] 2019/03/26 16:04:29 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: $(aws ecr get-login --no-include-email --region ${AWS_DEFAULT_REGION}). Reason: exit status 255

ロールが足りなかったみたい

【備忘録】CodeBuildでaws ecr get-loginコマンド実行時にエラーが発生する

下記のロールをアタッチした
AmazonEC2ContainerRegistryPowerUser

その後細かいエラーを解消した結果

buildspec.yml

version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - $(aws ecr get-login --no-include-email --region ${AWS_DEFAULT_REGION})
      ## ECRイメージ名を定義
      - IMAGE_NAME_PHP_FPM=laradock_php-fpm
      - IMAGE_NAME_NGINX=laradock_nginx
      ## nginxとphp-fpmコンテナイメージのECRリポジトリURIを生成する
      - REPOSITORY_URI_PHP_FPM=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_NAME_PHP_FPM}
      - REPOSITORY_URI_NGINX=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_NAME_NGINX}
      ## ここは何をしてる?
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      ## docker-composeでbuildを行う
      #- docker-compose -f docker-compose.production.yml build --no-cache nginx php-fpm
      - docker build -t ${REPOSITORY_URI_PHP_FPM}:latest -f docker/php-fpm/Dockerfile-production .
      - docker build -t ${REPOSITORY_URI_NGINX}:latest -f docker/nginx/Dockerfile-production .
      - docker tag ${REPOSITORY_URI_PHP_FPM}:latest ${REPOSITORY_URI_PHP_FPM}:$IMAGE_TAG
      - docker tag ${REPOSITORY_URI_NGINX}:latest ${REPOSITORY_URI_NGINX}:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push ${REPOSITORY_URI_PHP_FPM}:latest
      - docker push ${REPOSITORY_URI_PHP_FPM}:$IMAGE_TAG
      - docker push ${REPOSITORY_URI_NGINX}:latest
      - docker push ${REPOSITORY_URI_NGINX}:$IMAGE_TAG
      - echo Writing image definitions file...
      ## コンテナ定義の更新するためのファイルを作成する
      #- IMAGE_DIFINITION_PHP_FPM="{\"name\":\"${IMAGE_NAME_PHP_FPM}\",\"imageUri\":\"${REPOSITORY_URI_PHP_FPM}:${IMAGE_TAG}\"}"
      #- IMAGE_DIFINITION_NGINX="{\"name\":\"${IMAGE_NAME_NGINX}\",\"imageUri\":\"${REPOSITORY_URI_NGINX}:${IMAGE_TAG}\"}"
      - IMAGE_DIFINITION_PHP_FPM="{\"name\":\"php-fpm\",\"imageUri\":\"${REPOSITORY_URI_PHP_FPM}:${IMAGE_TAG}\"}"
      - IMAGE_DIFINITION_NGINX="{\"name\":\"nginx\",\"imageUri\":\"${REPOSITORY_URI_NGINX}:${IMAGE_TAG}\"}"
      - echo "[${IMAGE_DIFINITION_PHP_FPM},${IMAGE_DIFINITION_NGINX}]" > imagedefinitions.json
artifacts:
    files: imagedefinitions.json

3. ソースをpushしデプロイできるか確認

image.png
image.png

4. buildspec.ymlにS3から環境に合わせた.envファイルを取得するコマンドを追加

.env配置用のS3バケットを作成し、環境毎の.envファイルを配置する

CodeBuildプロジェクトにS3にアクセスできるポリシーを追加する
image.png

下記の取得する処理とCodeBuildに環境変数も追加する

buildspec.yml

## s3からenvファイルを取得する
- aws s3 cp s3://${BUCKET_NAME}/staging/env ./.env

5. 再度デプロイし、DBとRedisキャッシュから値を取得できるか確認する

作業中...

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DigDagをEC2にいれてHelloWorld的なワークフローを動かしてみる

DigDagとは?

Workflowのためのツールです。定期的に何か処理をしたいという時に使うものです。
毎日の天気をSlackに通知したいとか?そんな感じ。

要はcronとかWindowsのサービスでバッチを動かしたりするのをモダンに出来る仕組みです。

さっそくインストールしてみる

今回はAWS EC2に入れてみます。

Javaを8系にUpdateする

java -version

時と場合によるかもしれませんがEC2 LinuxではJava 1.7が入っているかもしれませんがDigDagでは8系が必要なようです。まずバージョンを確認して 1.8 になっているか確認してみてください。1.8ならOKなので次の手順は飛ばしてください。 1.7だった場合には下記手順で8系にしてください。

まずyumでインストール。

$ sudo yum install java-1.8.0-openjdk-src.x86_64

その後使うバージョンをalternativesコマンドで入れ替えます。メニューが出てくるので 1.8 を選択。

$ sudo alternatives --config java

バージョンを確認しておいてください。1.8とかになってればOKです。

$ java -version

DigDagを入れる

基本は公式の通りです。
http://docs.digdag.io/getting_started.html

ただ今回は諸事情で ~/bin/diag ではなく /usr/local に入れたかったのでパスを書き換えています。この辺りはお好きなところへどうぞです。

$ cd /usr/local
$ sudo curl -o ./digdag/digdag --create-dirs -L "https://dl.digdag.io/digdag-latest"
$ sudo chmod +x ./digdag/digdag
$ sudo chown ec2-user:ec2-user ./digdag
$ echo 'export PATH="/usr/local/digdag/:$PATH"' >> ~/.bashrc
$ . ~/.bashrc

入ったことを念のため確認しておきます。

$ digdag --version
0.9.35

サンプルを動かしてみる

適当な場所を作って。

$ mkdir digdag_test
$ cd digdag_test

initでプロジェクトを作ってみる。

$ digdag init mydag
2019-03-26 09:30:44 +0900: Digdag v0.9.35
  Creating mydag/mydag.dig
  Creating mydag/.gitignore
Done. Type `cd mydag` and then `digdag run mydag.dig` to run the workflow. Enjoy!

出来上がったファイルを見てみる。

$ cd mydag
$ ls
mydag.dig

中身を見てみる。

mydag.dig
timezone: UTC

+setup:
  echo>: start ${session_time}

+disp_current_date:
  echo>: ${moment(session_time).utc().format('YYYY-MM-DD HH:mm:ss Z')}

+repeat:
  for_each>:
    order: [first, second, third]
    animal: [dog, cat]
  _do:
    echo>: ${order} ${animal}
  _parallel: true

+teardown:
  echo>: finish ${session_time}

とりあえず実行してみる。

$ digdag run mydag.dig
    :

日時が出たり、dog とか cat とか出てたら成功です。
無事に実行されました。

HelloWorld的な簡単なものを作ってみる

ちょっとサンプルだけだとよくわからないので簡単なものを作ってみます。
ファイルの中身をがさっと書き換えてください。

mydag.dig
timezone: Asia/Tokyo

+step1:
  echo>: Hello World!! ${session_time}

+step2:
  echo>: Fin.

実行。

$ digdag run mydig.dag

色々ログも一緒にでますが要は下記のように出ると思います。

  :
Hello World!! 2019-03-26 09:00:00 +09:00
  :
Fin.
  :

何度か連続で動かそうと思うと何も出ないかもしれません。
実行済みのタスクになっているためです。その場合には --rerun オプションを付けてやってみてください。
digdag run mydig.dag --rerun です。

echo>: で書いた文字列が順番に出るだけなのでなんとなく想像通りの動きだったかと思います。

少しだけこったものを作ってみる

せっかくなのでREST的な通信も加えたサンプルです。

timezone: Asia/Tokyo

+setup:
  echo>: Hello World!! ${session_time}

+a:
  http>: https://us-central1-get-simple-json.cloudfunctions.net/hello
  content_type: "applicication/json"
  store_content: true

+b:
  _export:
    date: ${JSON.parse(http.last_content).date}
    msg: ${JSON.parse(http.last_content).msg}

  +c:
    echo>: date is ${date}, msg is ${msg} .

+teardown:
  echo>: Fin.

結果こうなります(ログとかは省略)。

$ digdag run mydag.dig  --rerun
  :
2019-03-27 17:18:39 +0900: Digdag v0.9.35
  :
Hello World!! 2019-03-26T09:00:00+09:00
  :
date is Wed Mar 27 2019 08:18:59 GMT+0000 (UTC), msg is hogehoge .
  :
Fin.

説明するほど複雑ではありませんが。
上から簡単に説明してみます。

  • +{label_name} で書いたタスクが上から順に実行されます。今回は setupabcteardown の順に実行されます。
  • timezone: Asia/Tokyo でタイムゾーンを日本にしてます。
  • http>: {URL} でREST APIをたたいて store_content: true で結果を保持して。
  • _export: でDigDag内で使う変数定義が出来るので date: ${JSON.parse(http.last_content).date}date にJSONのパース結果を保存。
  • echo>: date is ${date}, msg is ${msg} . で結果を出力。

次には何をする?

ここまでで簡単なチュートリアルは完了です。

あとは DigDag で検索! ということで調べながらやりたいオペレータを調べて付け加えていってください。
例えば今回使った http>: 以外にも mail>: であったり、処理の制御を行う loop>: if>: や、凝った処理をRubyやPythonで行うための rb>: py>: などたくさんあります。

あとは良い感じでデーモン化するなりして動かしておけば処理の自動化がはかどります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ALB + EC2環境で、CloudFrontを利用し画像は特定のパスでS3に振り分ける設定をする

株式会社NoSchoolでCTOをしている@mejilebenです。
今日は画像サーバーとしてS3を利用したときのURLの振り分けと、ALBを初めて使ってみたので全体の流れを記録します。

CloudFrontを利用し、画像は特定のパスでS3に振り分ける状態でALBを利用してWebサイトを構築する

やりたいこと

  • AWS EC2上にWebサービスをデプロイしたい
  • 画像は画像サーバー(S3)に置きたい
  • 同ドメインの/wp-content/uploads/*のPathではS3を向き、それ以外ではEC2を向くようにしたい(WordPressサイトのAWS移行です)
  • EC2は冗長化のため2台構成にしてロードバランサを前段に置きたい
  • いずれも独自ドメインを取得の上、動かしたい。HTTPS化もしたい

本記事では書かないこと

  • EC2より後段のRDS等の話
  • IAMロールは関連する権限をすべて持っている前提として書きます

全体的な流れ

ひたすら各サービスの知識を繋げあわせて作りました。大まかな流れは下記のとおりです。

  1. Route53でドメインを取得する
  2. CloudFrontでDistrubutionを作る
  3. VPC内にサブネットを2個作り、それぞれ別のアベイラビリティゾーンに設定しておく
  4. EC2を単体でIPでアクセスしてページが開けるまでセットアップし、それぞれのサブネットに1台ずつ設置しておく
  5. ACMからドメインを指定して証明書を発行する
  6. ALBを作成し、その際にドメインは作成したものを、証明書に先程発行した証明書を、ターゲットグループにサブネット2つを指定する
  7. Distributionに戻り、Originに対してALBを追加する
  8. S3で画像の置き場となるバケットを作成し、/wp-content/uploadsフォルダを作成する
  9. S3もDistributionのOriginにセットする
  10. Behaviorを新規追加し、/wp-content/uploads/*でS3に向くように設定する
  11. Route53でドメインのHosted Zoneを作成し、AレコードにCloudFrontのDistributionをAliasに指定したレコードを加える

用語解説

EC2, VPC, S3は割愛。

Route53

AWS上でドメインを取得し、そのドメインに対して向き先となるIPアドレスの設定などもできるサービス。ちなみに53はDNSのポート番号53にちなんでいるらしい。

CloudFront

静的コンテンツを配信する時に色々ロジックをかませることができる便利サービス。

その名の通りサービスの前段に噛ませるもので、ALB(ロードバランサ)よりも前段に置くことができる。

WAF(ファイアウォール)を付けたり、Route53を通さなくてもSSL証明書付きのドメインやURLを自動で発行したり、なんだか色々できる。

ACM

SSL証明書をマネジメントできるサービス。ドメインに対してSSL証明書の発行を申請したり、期日の確認なども一元管理できる。

ALB

アプリケーションロードバランサの略。ロードバランサの名の通り、バックエンドに複数のEC2をぶらさげてリクエストを振り分けることができる。以前はELBという名前のロードバランサがデファクトだったので、今でもググるときはELBでググったほうがいいときもある。

特に注意するところ

CloudFrontの待ち時間の長さ

CloudFrontは作成したり設定値を編集する時に待ち時間が数分〜数十分の単位で発生します。気長に待ちましょう。

EC2内のWebサーバーではhttpsアクセスを許可する設定が必要

今回はNginxを利用していたのですが、httpsを許可していないままにしておくと、せっかくACMで証明書を発行したのにCSSやJSがhttpアクセスになって表示崩れが起きるので、下記のような設定をしましょう。

Laravel 5.5 にてロードバランサ配下のアプリケーションにHTTPS通信を適用させる - Qiita

    set $my_ssl "off";
    if ($http_x_forwarded_proto = "https") {
        set $my_ssl "on";
    }
(略)
    location ~ \.php$ {
        fastcgi_pass   unix:/var/run/php-fpm/www.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        include        fastcgi_params;
        fastcgi_param HTTPS $my_ssl;
    }

ALBのバックエンドに指定するサブネットはアベイラビリティゾーンを分ける

勉強不足で理由がわからないのですが、ALBのバックエンドに配置する条件としては、とにかくサブネットを2つ以上、かつアベイラビリティゾーンを分けて作らないといけないです。

サブネットさえ切れば、あとはそのサブネット内にポート番号80番が空いたインスタンスを置くだけでALBが動きます。

CloudFrontのキャッシュの時間には気をつける

ALB側はアプリケーションなので、変にキャッシュされても困ります。

そのためキャッシュの設定値には気を払いましょう。

このあたりまだ理解が甘いので、色々触ってみて理解を深めていきます。

CloudFrontでミスしたらInvalidationする

設定を変えたのに反映されていないときは、キャッシュされている可能性があるので、

InvalidationsというタブからCreate Invalidationをクリックします。これでキャッシュを消したいPathを記入して動かすと、キャッシュを消すことができます。

S3へのパスはそのままS3のディレクトリ構成と一致させなければならない

今回の場合だと/wp-content/uploadsのURLでS3上の画像を見に行くのですが、S3でも同じフォルダを作成して、同じパスで画像を見れるようにしないといけません。

CloudFrontをリバースプロキシ的に使おうと思った場合、ここが力不足だと感じる点です。

検討課題

S3のアクセスは公開でいいのか

例えばCloudFrontからのリダイレクトのみ許可するようなことができれば、直接S3を覗くルートがなくなると思われます。

ALB, EC2周りの適切なセキュリティグループ設定

開発用ということでセキュリティ周りの設定を適当に制限した状態で進めていたので、こちらも本番適用にあたっては検討課題です。

CloudFrontからS3へアクセス時に307リダイレクトが掛かってしまう

Cloudfront,S3で307リダイレクトに苦しめられた - パパエンジニアのアウトプット帳にあるように、私の環境でも https://HOGEHOGE/wp-content/uploads/hoge.jpg へアクセスすると、S3のオリジンにリダイレクトされてしまう事象が起きました。

直接的に大きな問題がないとしても、解消したほうがいい問題です。

CloudFrontのURLを直接叩いてもアクセスができてしまう

本来意図しないドメインで開くことができてしまうので、こちらを閉じることができるなら閉じたいです。

ただ先程開いてみたら502エラーを吐いていたので、もしかするとAliasを貼ってしばらくすると元URLでは何もできなくなるのかもしれません・・・

EC2を同じもの2台設置する手順が面倒

今のところ僕がやっている方法が、AMIを作ってイメージから起動するというのをやっていまして、masterのほうのインスタンスを更新するたびに同じことをやっているので、ここのフローをどうにかしたいです。

また、デプロイ時のCodeDeployでも複数インスタンスに同時にコードを反映できるのか、は今後調べていこうと思います。

証明書の期日の管理、ドメインの期日の管理

ACMやRoute53にアラートを設定できるならしたほうがいいし、それがSlackに流せたらなお良いですね。

参考URL

最後に

僕が働いているNoSchoolでは仲間を募集中です!
創業期真っ只中、社員は僕と社長の2人きり(+副業メンバー3人)でEdTechを変えに行ってます!

興味あればお茶でもしましょう。Twitterからの連絡でも大歓迎です!
https://www.wantedly.com/companies/noschool

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS MediaLive から MediaPackage に出力 (2019/3/8 新機能)

いつの間にか桜がほぼ満開なことに気がついた streampack 木村です。

さてさて MediaLive の output group に新たに MediaPackage が追加されました。

https://aws.amazon.com/jp/about-aws/whats-new/2019/03/aws-elemental-medialive-simplifies-sending-live-streams-to-aws-elemental-mediapackage/

これまでも HLS から webdav もしくは basic put で MediaPackage に出力することは可能でしたが、destination で Credential 情報を入力しないといけないので少々面倒でした。
これで便利になるかと思いきや、普通に使っている人は 2019/3/27 現在、ユーザーガイド記載の方法だけではエラーで失敗します。

その他、お作法もあるのでやり方を纏めてみました。

ユーザーガイド
https://docs.aws.amazon.com/medialive/latest/ug/creating-mediapackage-output-group.html

Add output group

はい、以下のように MediaPackage が追加されているのでこれを選択して進めます。

スクリーンショット 2019-03-27 13.44.47.png

MediaPackage group

入力するのは MediaPackage であらかじめ作成しておいた channel ID のみです。
エンドポイント URL やユーザー名/パスワードの入力は必要ありません!

スクリーンショット 2019-03-27 13.50.48.png

Stream settings

あとは HLS 出力設定をおこなうのですが、ここでお作法
Frame RateAspect Rate の項目で INITIALIZE_FROM_SOURCE は選択することができず、SPECIFIED にして任意の値を入力してあげる必要があります。

Frame Rate

以下の項目を設定する必要があります。

ITEM Value
Framerate Control SPECIFIED
Framerate Numerator 任意の値
Framerate Denominator 任意の値

例えば 30fps なら、
Framerate Numerator を 30
Framerate Denominator を 1

29.97fps なら
Framerate Numerator を 30000
Framerate Denominator を 1001

にします。

スクリーンショット 2019-03-27 13.53.08.png

Aspect Ratio

こちらは PAR ControlSPECIFIED にすれば他の項目は未入力でも設定可能です。

スクリーンショット 2019-03-27 13.52.48.png

その他、エンコードに必要な項目を入力し Update channel でチャンネルが作成できます。

配信エラー

しかしながら、このまま流しても前述のとおりエラーとなり配信できません。

スクリーンショット 2019-03-27 13.58.32.png

回避方法

ロール MediaLiveAccessRole にポリシー AWSElementalMediaPackageReadOnly をアタッチする。

要は MediaLive で普通に使っているロールからは MediaPackage の Credential 情報にアクセスできない為、読み取り権限を付与しようということです。

MediaLiveAccessRole

IAM ページから MediaLiveAccessRole を探します。

スクリーンショット 2019-03-27 15.13.46.png

割り当てられてるポリシーを確認します。

スクリーンショット 2019-03-27 13.57.22.png

ポリシーをアタッチしますMediaPackage 関連のポリシーを探し、AWSElementalMediaPackageReadOnly を選択してアタッチします。

スクリーンショット 2019-03-27 15.22.50.png

ロールに新ポリシーが適用されていることを確認して準備完了です。

スクリーンショット 2019-03-27 15.23.21.png

あとは通常通りライブを入れるとエラー無しで配信可能となります。

スクリーンショット 2019-03-27 14.21.27.png

最後に

MediaServices 関連は気がつくと新機能が増えてたりします。
上記の機能も MediaLive を弄って気がついたのですが、当初はユーザーガイドにもまだ記載がなく自分で適当に設定してもエラーで動かなかったので AWS さんに問い合わせて教えてもらいました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS+nginxサーバーに独自ドメインを設定したい

はじめに

現在の状況です。
下記環境でAWSにnginxサーバーを使用してデプロイはできている状態です。
IPでアプリケーションは表示されているが、自分で取得したドメインでも表示できるように
したいというのが今回の目的です。

環境

ruby 2.3.1
Rails 5.0.7.2
MySQL
git
unicorn
nginx
capistrano
AWS EC2

事前準備

[参考]お名前.comで取得したドメインをAmazon EC2に紐付ける

上記を参考にドメインの設定は完了しております。

エラー発生

キャプチャ.png

設定したドメインをブラウザで表示しても上記のように表示されてしまいます。
表示されている文面を翻訳するとnginxのどうやら設定が必要なようです。

対応したこと

[参考]【超初心者向け】AWSでたてたnginxサーバーにドメインを設定する

上記記事を参考にnginxの「conf」の変更、nginxのrestartを行いました。

[ec2-user@ip-XXX-XX-XX-XXX ~]$ sudo vim /etc/nginx/conf.d/rails.conf
rails.conf
server_name XXXX.com; #ここの部分を取得したドメインに変更
#変更後保存
sudo service nginx restart #nginxのrestart

結果

正常にドメインでページが表示できました!!

おまけ

上記を行うと逆にIPからはページが表示できなくなります。
私はIPからも接続できるようにしたかったので、その際にはその設定も必要です。

[参考]nginxでip入力によるアクセスをドメインにリダイレクトする

[ec2-user@ip-XXX-XX-XX-XXX ~]$ sudo vim /etc/nginx/conf.d/rails.conf

下記を追記でOKです。

server {
    server_name XXX.XXX.XXX.XXX; #IPアドレス
    return 301 http://XXXX.com; #取得したドメイン
}

以上です。宜しくお願いします。

参考

[参考]お名前.comで取得したドメインをAmazon EC2に紐付ける
[参考]【超初心者向け】AWSでたてたnginxサーバーにドメインを設定する
[参考]nginxでip入力によるアクセスをドメインにリダイレクトする

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon Linux 2 のbashでリダイレクト先が補完されなくなった

困ったこと

# test.sh を実行し、標準出力/エラー出力を log/test.log に書き出す
$ sh test.sh >& log/test.log

このとき、log/を打とうとすると、補完されなかった。これまでは出来たのに。。と思って調べると以下の通り。
- Amazon Linux 2 では補完されない
- Amazon Linux (1) では補完される
- RHEL7 では補完される

bash_completion が原因?

  • rpm -qi bash_completion で調べると、Amazon Linux 2にだけ入っている。
  • /usr/share/bash-completion/bash_completion をrenameして再ログインすると、補完された。
  • (が、当然bash-completionをもって機能する補完も使えなくなる)
  • これまでの感じに戻したければこれでOK

より前向きな解決

>&ではなく&>を使おう

$ sh test.sh &> log/test.log

http://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.html
「標準出力と標準エラー出力のリダイレクト」の項
意味は同じだが、&>の方が推奨とされている。
これであればbash-completionが効いたままでもOK

ぼやき

(この辺て困ることでも無いと、使い始めた時点の知識からなかなかアップデートされないのでおじさんたちは注意しよう)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DBeaverでSSHポートフォワーディングしてAWS EC2のMySQLに接続

概要

SSIA

環境

  • 開発端末
    • Mac
  • サーバ
    • AWS Linux 2
    • MySQL 8.0.15

目的

  • AWSにDBを置いて3306で通信すると、暗号化されてないので危険
  • そこで暗号化ですよ
  • そこでSSHポートフォワーディングですよ
    • SSHトンネリングと言った方が想像しやすいが、googleabilityはポートフォワーディングの方が上

手順

  • AWS EC2にMySQLをインストール
  • インスタンスにSSH接続 ssh -i "mylara-db.pem" ec2-user@50.198.199.200
  • mysqlコマンド実行してから
CREATE DATABASE IF NOT EXISTS `mylaradb` COLLATE 'utf8_general_ci';
CREATE USER 'mylara'@'localhost' IDENTIFIED WITH mysql_native_password BY 'Mylara-Password1234';
GRANT ALL ON `mylaradb`.* TO `mylara`@`localhost`;

※ mysql_native_passwordは本題と関係ないです

  • 開発端末にDBeaverをインストール
  • 接続設定

スクリーンショット 2019-03-27 2.04.40.png
スクリーンショット 2019-03-27 2.05.50.png

結果

接続成功

スクリーンショット 2019-03-27 2.19.36.png

Hope this helps.

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[備忘録] RDSで外部サーバからアクセス許可する方法

経緯

開発環境でVagrantを使用していて、EC2を経由せず、ローカル環境からRDSを接続し
データベースの操作を行いたいと思ったから。
今回はMySQLを例に書いていきます。

RDSとは

「Amazon Relational Database Service (通称:RDS)」はAmazonの提供する、リレーショナルデータベース構築サービスことです。
より詳しい情報は下にリンクを貼っておきます。
https://dev.classmethod.jp/cloud/aws/cm-advent-calendar-2015-aws-re-entering-rds/#overview

RDSの設定

設定にパブリックアクセシビリティという項目があるので「はい」に変更する。
新規設定のときは「[詳細設定]の設定」、既存DBの設定変更のときは設定変更を選択後の一覧画面に表示される。
下の画像は新規設定の時の画面です。
スクリーンショット 2019-03-26 23.45.38.png

セキュリティグループの設定

MySQLに紐づくセキュリティグループの設定を行う。
VPCセキュリティグループのリンクをクリックする。
スクリーンショット 2019-03-27 0.15.06.png

セキュリティグループに接続許可するサーバーや接続したい場所のIPアドレスを追加する。
※今回は、「0.0.0.0」にしてますが、これは全てのIPアドレスからの接続許可することになるので、現在使用しているIPのみ許可する方がセキュリティ的にいいと思います。
スクリーンショット 2019-03-27 0.50.49.png

MySQLに接続できるか確認

vagrant@localhost
$ mysql -h RDSのエンドポイント -P 3306 -u ユーザ名 -p
Enter password:パスワード

スクリーンショット 2019-03-27 1.22.50.png
接続できた!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む