20190215のAWSに関する記事は14件です。

React製WebアプリのAWSへのdeploy scriptを作った試行錯誤の過程

システム構成図

AWS Design.png


システム構成

  • ReactのソースコードはS3 Backetにアップロード
  • BacketはCloudFrontを経由して公開する
  • ステージング環境と本番環境がある

やりたいこと

残念ながらCIは導入されていないので、手動でデプロイする必要がある
ステージング環境と本番環境へのデプロイをできるだけ簡素化したい


これまで手動でやってたこと

  • APIの向き先を変更して npm run build
  • 該当S3バケットにbuildしたファイルをアップロード
  • CloudFrontのキャッシュを無効化
  • これをproductionとstaging で実施

ひとつずつスクリプト化していく!


これまで手動でやってたこと

  • APIの向き先を変更して npm run build
  • 該当S3バケットにbuildしたファイルをアップロード
  • CloudFrontのキャッシュを無効化
  • これをproductionとstaging で実施

Reactのbuild時に.envファイルを切り替える

  • npm-scriptsにprebuildを定義して、そこで.envファイルを差し替え
  • で、postbuildで元に戻す

まぁ 動いた


env-cmd

あとで公式ドキュメント見てたら、そのものズバリの記載があった

Deployment · Create React App
Customizing Environment Variables for Arbitrary Build Environments
(任意のビルド環境用の環境変数のカスタマイズ)

For example, to create a build environment for a staging environment:


どう使う?

package.json
{
  "scripts": {
    "build": "react-scripts build",
    "build:staging": "env-cmd .env.staging npm run build"
  }
}

これまで手動でやってたこと

  • APIの向き先を変更して npm run build
  • 該当S3バケットにbuildしたファイルをアップロード
  • CloudFrontのキャッシュを無効化
  • これをproductionとstaging で実施

Amazon S3へのファイルのアップロード

  • AWS SDKでアップロード
async function putFile(sourceFile) {
  // S3にputするファイル名
  const dir = process.env.DIRECTORY ? `${process.env.DIRECTORY}/` : '';
  const key = sourceFile.replace('build/', dir);
  // ファイルの内容を取得
  const data = await fs.readFile(sourceFile);

  const params = {
    Bucket: process.env.BUCKET,
    Key: key,
    Body: data,
    ContentType: mime.lookup(sourceFile),
  };
  await s3.putObject(params).promise();

  debug(`putObject: ${key}`);
}

これまで手動でやってたこと

  • APIの向き先を変更して npm run build
  • 該当S3バケットにbuildしたファイルをアップロード
  • CloudFrontのキャッシュを無効化
  • これをproductionとstaging で実施

CloudFrontのキャッシュ無効化

deploy.js
const cloudFront = new aws.CloudFront();

await cloudFront.createInvalidation({
  DistributionId: process.env.DistributionId,
  InvalidationBatch: {
    CallerReference: uuid(),
    Paths: {
      Quantity: 1,
      Items: ['/*'],
    }
  }
}).promise();

これまで手動でやってたこと

  • APIの向き先を変更して npm run build
  • 該当S3バケットにbuildしたファイルをアップロード
  • CloudFrontのキャッシュを無効化
  • これをproductionとstaging で実施

環境変数をいい感じに切り替える

dotenv
Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.

.env.production.env.staging をnpm-scriptsで呼び分ける


どう使う?

deploy.js
// 環境変数TARGETを元に読み込むファイルを切り替え
const target = process.env.TARGET || 'production';
require('dotenv').config({
  path: `${process.cwd()}/.env.${target}`,
});
package.json
{
  "scripts": {
    "deploy": "node scripts/deploy.js",
    "deploy:staging": "TARGET=staging npm run deploy"
  }
}

まとめ

ec2のWebAPI更新が手動なので、これもnpm-scriptsから更新がキックできたらいいな

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

TypeScriptでamazon-connect-streamsを利用して電話かけてみる

世界130億超のAmazonConnectユーザのみなさん、こんにちは。

UIをカスタマイズしてAmazonConnectを使いたい!!
そんな皆さんの強い味方であるamazon-connect-stream、便利ですよね。

ですが、TypeScriptから利用するにはヒトクセあります。

What is ヒトクセ?

  • npmに公開されてない
  • 公式Docを参考にgulpでbuildしてもimportできない
  • npm i aws/amazon-connect-streams --saveしてもimportできない(実体がない)
  • でもindex.d.tsはある

こんな具合でできそうでできない...グヌヌって感じな癖があります。

解決策

  • 公式Docを参考にgulpでbuild
  • index.d.tsと同じDirectoryにいれる

これだけです。
構成やファイルは以下を参考にしてください。
サンプルはAngularです。

ディレクトリ構成
/app/Modules/Connect
  /index.d.ts
  /index.js
app.component.ts
import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core';
import './module/index';
import Endpoint = connect.Endpoint;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements AfterViewInit {
  title = 'applicatioin';

  state: string;
  @ViewChild('ccp') ccpContainer: ElementRef;

  ngAfterViewInit() {
    connect.core.initCCP(this.ccpContainer.nativeElement, {
      ccpUrl: 'https://YOUR-ENDPOINT.awsapps.com/connect/ccp#',
      softphone: {
        allowFramedSoftphone: true,
      },
    });
    connect.agent(agent => {
      // ここで自分のステータスを出してみた
      this.state = JSON.stringify(agent.getState());

      const phoneNumber = '+819012341234';
      const endpoint = Endpoint.byPhoneNumber(phoneNumber);
      // 電話かけてみた
      agent.connect(endpoint, {});
    });

  }
}

コレ、いい感じに補完が効いてますし、カスタマイズしたUIから電話の発信までできました!

おまけ

connection.core.initCCP()の ccpUrlの最後に / が入ってると駄目だったのも注意点です。

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

複数アカウントのCloudTrailをKMSで暗号化する

前書き

AWSからCIS (Center for Internet Security) AWS Foundations Benchmarkという、汎用的なセキュリティガイドラインが提供されている(*1)。

その中で、以下のようにCloudTrailのログをKMS暗号化することが推奨されている。
2.7 Ensure CloudTrail logs are encrypted at rest using KMS CMKs (Scored)

また、CloudTrailのログは、一つの管理アカウントに集約する運用もままある(*2)。

双方を両立させる設定について、公式ドキュメントに一部(*3)載っているが、通しての手順はネット上でも見つからなかったので、忘備録として残しておく。

構成

Cloud Trail.png

・Trail管理アカウント(AccountID: 111111111111)
バケットを持つアカウント。KMSのCMKもここに作る。
自分自身のTrailログもとる

・Trail管理配下アカウント(AccountID: 222222222222)
Trailログ取得が必要になるアカウント。

手順

<Trail管理アカウント>S3バケットを作る

次の手順で、S3バケットを自動生成するオプションもあるが、予め作ってあるバケットにTrailログを保存することもできる。ここでは、自分でS3バケットを作る手順で進める。

バケット作成は、デフォルトのまま、任意のリージョンでOK。
ただし、既存のCMKを使う場合は、リージョンを揃える必要がある。

バケットポリシーは公式サイト(*4)より以下となる。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AWSCloudTrailAclCheck20131101",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "s3:GetBucketAcl",
      "Resource": "arn:aws:s3:::myBucketName"
    },
    {
      "Sid": "AWSCloudTrailWrite20131101",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": [
        "arn:aws:s3:::myBucketName/[optional] myLogFilePrefix/AWSLogs/111111111111/*",
        "arn:aws:s3:::myBucketName/[optional] myLogFilePrefix/AWSLogs/222222222222/*"
      ],
      "Condition": { 
        "StringEquals": { 
          "s3:x-amz-acl": "bucket-owner-full-control" 
        }
      }
    }
  ]
}

<Trail管理アカウント>Trail設定をする

Trail認証情報を作成する。
バケット指定はバケット名で行う。
例)myBucketName

KMSもS3バケットと同じく、予め用意したものを指定できるが、ポリシーが結構複雑になるので、自動生成に任せた方が楽。

とりあえず、ここまでの手順でTrailログがバケットに流れ込み出すはず。

<Trail管理アカウント>CMKポリシーの修正

Trail管理配下アカウントのために、CMKポリシーを修正する。
マネジメントコンソール のIAM画面から、先の手順で作られた暗号化キーを参照する。
見つからない場合は、リージョンが合っているかを確認する。※画面右上のものでない

対象キーを選択、キーポリシー欄にて、ポリシービューに切り替えて、編集できる状態にする。

以下の部分を修正する。

    {
      "Sid": "Allow CloudTrail to encrypt logs",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "kms:GenerateDataKey*",
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "kms:EncryptionContext:aws:cloudtrail:arn": [
            "arn:aws:cloudtrail:*:111111111111:trail/*",
            "arn:aws:cloudtrail:*:222222222222:trail/*"
          ]
        }
      }
    },

StringLikeの要素をリストにし、管理配下のアカウントを追加する。

<Trail管理配下アカウント>Trail設定をする

ほぼ同様の手順でOK。
バケット名はリージョン内でユニークなはずなので、先と同じくバケット名でよい。

一方、KMSの指定は、ARNで行う。 
例)arn:aws:kms:ap-northeast-1:111111111111:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx

これで、管理配下のTrailログも、管理アカウントのバケットに流れ込む。

<両方>確認

目視でもいいが、Configでチェックするとより安心。

参考)
(*1) https://aws.amazon.com/jp/about-aws/whats-new/2017/12/new-quick-start-implements-security-configurations-to-support-cis-aws-foundations-benchmark/
(*2) https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/cloudtrail-receive-logs-from-multiple-accounts.html
(*3) https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/create-kms-key-policy-for-cloudtrail-encrypt.html
(*4) https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/cloudtrail-set-bucket-policy-for-multiple-accounts.html

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

CloudWatchグラフ自動更新のカウントダウン表示

CloudWatchコンソールでメトリクスをグラフ表示していて気づいたので投稿

update_setting.png

右上の更新ボタンから自動更新On/Offと更新間隔の指定ができますね。

で、このボタンの下の方に、青い線が見えますよね?
これがカウントダウンのゲージです。

update1.png

↑これが時間が経過するにつれて
↓こんな感じでゲージが減っていき、青線が消えるタイミングでグラフが更新されます。

update2.png

これ気づいてない人結構いるんじゃないかと思い投稿しました!
(AWSマネジメントコンソールのUIは頻繁に変わるので、いつまで残っているかはわかりません)

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

AWS CDK を使って簡単に ECS(Fargate) 環境を構築する方法

streampack の Tana です。

ECS(Fargate) 環境を手動セットアップするには、画面からぽちぽちすればある程度できるものの、
ALB を作成したり、Service, Task Definition などを設定するのが複雑です。
また、コンセプトを理解するのにも時間がかかります。
Dynamic Port Mapping を使う場合は、Security Group に inbound を登録しないといけなかったり、トライ&エラーの繰り返しです。
構築だけで疲れちゃいます。

そこで、AWS Cloud Template Kit(CDK) を使えば、20行ぐらいのコードと数回のコマンド実行で
下記のリソースと共にベストプラクティスなECS(Fargate)環境を構築してくれる方法です。

ネットワーク

  • VPC
  • Subnets
  • Internet Gateway
  • NAT gateway(EIP)
  • Route Tables
  • Security Group

ECS(Fargate)

  • ALB(Target Group, Security Group込み)
  • Cluster
  • Service
  • Task Definition(Container)

CDK の installや初期手順などはこちらで記載あるので割愛します。
https://github.com/awslabs/aws-cdk#getting-started

cdk init で作成されたテンプレートを元に、下記が実際に書いたコードです。
Dockerhub を使って例は他にもあるので、今回は ECR を使用します。

lib/demo-stack.ts
import cdk = require('@aws-cdk/cdk');
import ecs = require("@aws-cdk/aws-ecs");
import ec2 = require("@aws-cdk/aws-ec2");
import ecr = require("@aws-cdk/aws-ecr");

export class DemoStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // ------------- ここを記載 --------------
    // ベストプラクティスなネットワーク環境の構築
    const vpc = new ec2.VpcNetwork(this, 'MyCdkVpc', {maxAZs: 2});
    const cluster = new ecs.Cluster(this, 'Cluster', {vpc});

    // ECSクラスタ設定(t2.medium指定)
    cluster.addDefaultAutoScalingGroupCapacity({instanceType: new ec2.InstanceType("t2.medium"), instanceCount: 1});

    // ECRを使用
    const repository = new ecr.Repository(this, 'myRepoName');

    // ECS(ALB/Service/Task Defintion/Container) 関連をまとめて構築
    new ecs.LoadBalancedEc2Service(this, 'Service', {
      cluster,
      memoryLimitMiB: 512,
      image: ecs.ContainerImage.fromEcrRepository(repository),
      containerPort: 8080,   // コンテナポート番号
      environment: {
        ENV: 'production'
      }
    });
    // ------------- ここまで --------------
  }
}

synth で typescript 書いたコードから CloudFormation Template(Yaml)で事前確認できます。
CloudFormationの400行ぐらいのコードを書く必要が無くなります。

$ cdk synth
$ cdk deploy

deploy は IAM Policy や Security Group のプレビューが表示され、AWSアカウントに構築開始されます。

ECRを使う場合はレポジトリまで作成してくれますが、アプリケーションの Docker Image を push してあげる必要があります。
よって、作成されたレポジトリを取得し、Image を push します。

# リポジトリ名を取得
$ aws ecr describe-repositories | jq -r '.repositories[].repositoryName'
----
demos-demoa-xxxxxx

下記のようなコマンド(shell)を実行して build&push します。

build_push.sh
ECRID=xxxxxxxxx
ECRNAME=demos-demoa-xxxxxx

# build an your docker app
docker build -t ${ECRNAME} .
docker tag ${ECRNAME}:latest ${ECRID}.dkr.ecr.ap-northeast-1.amazonaws.com/${ECRNAME}:latest

# push
$(aws ecr get-login --no-include-email --region ap-northeast-1)
docker push ${ECRID}.dkr.ecr.ap-northeast-1.amazonaws.com/${ECRNAME}:latest

成功すると、ALBのURLが払い出されますので、アクセスして確認し、結果が返ってくれば完了です!
demo-stack_ts_—_cdk.png

結果が正しく表示されなければ、Cluster の EventのログやTaskをAWSコンソールや ecs-cli などを使って再度確認します。

ecs-cli ps --cluster DemoStack-Clusterxxxx-xxxxx

たいてい、container port が正しくなかったり、環境変数、ECRリポジトリに登録されているかなどを確認します。

削除したい場合は、destory を実行します。(事前に ECRに登録した Image の削除の必要あり)

$ cdk destory

CDKデメリットとしては細かな指定や調整したい場合は、別途それぞれコードを書く必要がありそうです。
例えば、

  • コスト削減のためにも NAT Gateway(EIP) を省きたい
  • コンテナの log driver や ulimits を設定したい

下記はコンテナに log driver などを追加する場合です。

demo-stack.ts
    const demoContainer = demoTaskDefinition.addContainer('demo-container', {
      image: ecs.ContainerImage.fromEcrRepository(repository),
      logging: new ecs.AwsLogDriver(this, 'demo-logging', { streamPrefix: 'demo-app' })
    });

    demoContainer.addUlimits(
      {
        name : ecs.UlimitName.Fsize,
        hardLimit : 10240000,
        softLimit : 10240000
      }
    )

細かな引数の指定や props の指定は CDK doc にてブラウザにてドキュメントを開いてくれて、検索・確認できます。

$ cdk docs

まだ、プレビューで今後改善さらに改善されそうですが、ECS(Fargate) 環境を頻繁に作ってはテストして削除するケースには最適です。

CDK workshop もあるようなので、一度見て試してみるとイメージが湧くかと思います。
https://cdkworkshop.com/

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

AWS S3 のバケットポリシーでログ配信サービス以外の特定の IAM ロールのみを許可するポリシー例

VPC フローログ等のログ配信はしたいけど、特定の IAM ロールにのみアクセス権限を与えたい例。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "NotPrincipal": {
                "Service": [
                    "delivery.logs.amazonaws.com"
                ]
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::<バケット名>",
                "arn:aws:s3:::<バケット名>/*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:userId": [
                        "<ロールID>:*"
                    ]
                }
            }
        }                           
    ]
}

ちなみにロール ID って何だろ?って人。ロールの ARN じゃないですよ。
実はこのロール ID、マネージメントコンソールからは確認出来ません。(2019/02/15 現在)

じゃあどうやって確認するかって?
AWS CLI を使いましょう!

$ aws iam get-role --role-name <ロール名>
...
        "RoleId": "ロールID", 
...
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon Linux EBSサイズ拡張手順

「Amazon Linux 2 AMI」限定で、EBS拡張手順のメモです。EBSは1つのみアタッチしている前提。

公式Documentは、下記参照

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-modify-volume.html

  • AWS Management Console -> EC2 -> EBS
    • 対象のEBS Volumeを選択、Modify
    • ご希望のSizeを指定
  • SSHでEC2に接続
    • lsblk で状態確認
    • sudo growpart /dev/nvme0n1 1 でパーティション拡張
    • lsblk で状態確認
  • Reboot後、df -hで、ディスク認識されている事を確認。
    • sudo xfs_growfs -d / を実行すれば、rebootしなくても良さげだが、念のためRebootで反映。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS初心者が3ヶ月で出来るようになったこと

業務でAWS使うことになったので、成果をまとめてみました。

開始時の状況

オンプレの新規システム構築経験あり。
AWSの実務経験:実務経験なし。ハンズオンで触った程度。

出来るようになったこと

Route 53

ドメイン管理
DNSレコード登録

Certificate Manager

ACM証明書の無料証明書適用

VPC

VPC作成

無計画に/24で切ると、IPアドレス不足で作り直す羽目になるので注意。大きめに切ろう。

サブネット設計

public/private分離

EC2

イメージ

AMIの作成、インスタンスへの複製、

ネットワーク&セキュリティ

セキュリティグループ設計
ElascticIP管理/リソース上限の追加

ロードバランシング

ALB作成
SSL証明書適用

RDS

新規作成、起動停止

AWS認定試験

Cloud Practitonerの合格

やりたかったけど出来なかったこと

CloudFront
ECS
CI/CDの自動化

感想

オンプレと同じよう構成で構築することが出来た。
AWS特有の構成で作れなかった。

また、コスト面でももっと削減できそう(特にEC2)

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

教えて欲しい!AWSやGCPの上り・下りの概念はおかしいのでは?

ネットワークのおける上り・下りってご存知ですか?

皆さんが使ってるスマホからみた場合は以下のとおりです。

  • ダウンロード:下り
  • アップロード:上り

さて、ここでGCPの料金表を見てみましょう。

どうやらGCPのVPC(ネットワーク)では、上り通信が無料のようです。

image.png

ということはGCPからみると「外に出ていく通信」が無料ということですね。

しかしこちらを見てください。これは同じページを英語で表示したものです。

image.png

ん? 無料なのは「Ingress」となっていますね。

IngressとはVPCに入ってくる通信のことを指し示しますので、GCPからみると「中に入っていく通信」が無料ということですね。

どゆこと???
つまり「Ingress=上り」ってこと?? しかしIngressを

辞書をひくとingress=入ってくるというニュアンスなので、アップロード(出ていく)を意味する上りとは違いますよね。

ingressの意味や使い方 【名詞】 (⇔egress) 《文語》【不可算名詞】1立ち入り,入来,進入.2入場権,入場の自由. 

どうしてこんなことになっているのでしょうか???

そしてみなさん誤解しないのでしょうか???

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

API Gatewayに別アカウントで所有しているドメインを使ってカスタムドメイン名を設定する

Steps

  1. 別アカウントで所有しているドメインを利用した証明書の取得
  2. 証明書をセットしたカスタムドメイン名の作成
  3. カスタムドメイン名をRoute53のレコードに設定

1. 別アカウントで所有しているドメインを利用した証明書の取得

証明書の発行自体はACMからすぐにできましたが、ドメインを持っていること自体の証明が必要でした。

DNS証明という方法があって、これから証明書を取得するドメイン名のサブドメインに対して、自分が指定したドメイン名(=証明書を申請した側のAWSアカウントで作成された、******.acm-validations.aws/のようなアドレス) の組み合わせを作成し、それをドメインを所有している側のアカウントでレコードに登録することで証明しています。

参考:
- AWS Certificate Manager で証明書の準備をする
- DNS を使用したドメインの所有権の検証

2. 証明書をセットしたカスタムドメイン名の作成

API Gatewayの Custom Domain Nameから、こんな感じでドメイン名を設定します。

なお、ドメイン名に関する用語が紛らわしいので整理すると...

"デフォルトのベースURL": https://api-id.execute-api.region.amazonaws.com/stage

"リージョンのドメイン名"(またはターゲットドメイン名): https://api-id.execute-api.region.amazonaws.com
"カスタムドメイン名": https://api.example.com/myservice

ガイドにも書いてありますが、リージョンAPIのカスタムドメイン名を作成する場合にAPI Gatewayから返ってくるのは"リージョンのドメイン名"なんですね。これをDNSレコードに設定することで、カスタムドメイン名を使うための手続きが完了します。

参考: API Gateway で API のカスタムドメイン名を設定する

3. カスタムドメイン名をRoute53のレコードに設定

ドキュメント API Gateway でリージョン別 API 用のカスタムドメイン名をセットアップするではCLIのコマンドが示されている箇所です。

Aliasとして設定します。

その他

  • 疎通確認の際、 http でアクセスしないように気をつけてください。Chromeでドメインだけ(test.example.com)打ち込むとhttp として解釈されます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

マイグレーションコンペで優勝して100万円頂きました

はじめに

こんにちは、drama(@1901drama)です!
今回は、先月私が参加した「マイグレーションコンペティション」について書きます。
(AR記事でなくてすみません。。)

マイグレーションコンペティションとは

migcon2019.png
日本MSP協会が開催している競技会です。
全国から集まったメンバーでランダムにチームを組み、制限時間内に 既存システムを新たな環境へいかに移行できるか を競います。

いわゆるIT系コンテストでは 成果物の機能 を元に評価されることが多いのですが、
この競技会は、以下のような実際のサービスや顧客を意識することが評価に含まれています。

・既存環境の機能が継続して使えるか
・移行時のサービス停止をどれだけ短くできるか
・顧客とのコミュニケーションが円滑に取れているか
・その後の運用に必要な情報(システム構成、実施内容、手順書)がまとめられているか... など

また、賞金額が「3位:10万円!、準優勝:30万円!、優勝:60万円!!!」
高額なためか、ある程度技術力に自信のあるエンジニアの方が多かった印象です。

私の本職はインフラ系(元エンジニアで、今はディレクション/サービスデザイン/要件定義等)で 昨年参加したのですが、入賞さえ出来ませんでした...。
今年は、そんな昨年の悔しい思いを晴らすべく、事前に勉強し準備万全の状態で臨みました!

競技開始まで

開会時間になると、最初にメンバーの振り分けが行われます。 

今回の参加者は29名で、9チーム(1チーム3名で、2チームだけ4名編成)
私のチームは3名編成の「Team5」となりました。
DSC01327_570.jpg
※チーム分けの様子

そして、今回のお題は以下のようなものでした。

 【とある文書サイトを移行します。】
 お題:いま動いているシステムを新しい環境に移行して欲しい
 要望的な何か
 ・今の環境を新しい環境に完全移行して欲しいです。
 ・実施した内容と結果については報告が欲しいです。
 ・システムを止めるときは利用者に告知が必要なので連絡が欲しいです。
 ・昔から使っている古い環境なので、バージョンアップして欲しいです。
 ・できれば利用者に影響を出さないように切り替えたいです。
 ・できればサーバに関する資料があるとありがたいです。
 ・できれば今はまったくバックアップを取っていないのでバックアップを取れるようにしたいです
 ・できれば今後は利用者が増えるのでシステムを冗長化したいです。
 ・できれば新しいインフラエンジニアに引継ぎするために必要な情報がまとまっていると嬉しいです。
 担当者のコメント
 ・体制変更とかいろいろありまして、システムが分かる人がいなくなってしまいました。
 ・結構前から使っているので、いいタイミングなのでリフレッシュしたいなと思っています。
 ・サイト上での商売は続いているので、できるだけ利用者さんに影響が少ないと嬉しいです。
 ・そうそう、近々新しいインフラエンジニアが入社予定だから、その方に引き継げるようになっていると嬉しいですね。
 ・本当はいろいろとナウっぽいこともしていい感じにしていきたいんですよ
 ・このご時勢ですから、セキュリティ的なものも気になっていますが詳しくなくて……
 移行元環境
 ・Amazonです
 ・そろそろサポート期限が切れそうなCentOS
 ・アパッチとパイソンとギットなど
 移行先環境
 ・Microsoftのクラウドを用意しました 

お題はホームページ上で事前に公表されており、当日に詳細や 追加要望が発表されました。

競技スタート!

まず、大まかな役割分担を決めます。
事前に必要な役割を以下のように想定し、どれでもできるよう準備していました...

1.移行元環境の調査 役
2.移行先環境の構築 役
3.ディレクション(顧客対応・チームの進行・補助など) 役

が、メンバーのスキルが上手く分かれ
自分の得意分野である 3.ディレクション を担当することができました!
DSC01334_570.jpg
DSC01354_570.jpg
※競技中の様子

DSC01342_570.jpg
DSC01347_570.jpg
※昼食もあります

競技中には多くの課題があったので、特に印象に残っている課題のみ記載します。

①新環境へ移行したJenkinsから大量のワーニングログが出力されていた。

▶文書サイトを表示するために参照しているファイルが、想定外の場所にも存在していました。(外字ファイル)
 メンバーの一人が細かく稼働確認をしていたおかげで、発見することができました。

②Jenkinsの処理実行時にメール通知を行っているが、新環境では失敗していた。

▶MicroSoft Azureで作成したインスタンスは、25番ポートを標準でブロックする仕様です。
 MicroSoft Azureの特徴として事前に把握していたため、紆余曲折を経て、回避策を実施できました。

③追加要望を「どのように」「どこまで」実装するか。

▶例えば、一口に「セキュリティ強化」と言っても、想定する脅威によって導入すべき手段は異なってきます。
 今回は 文書サイトを参照できなくなることがサービス影響に対する最大の脅威と考え、
 多重アクセスを検知して次の行動に移すための監視機能と、簡易的なアクセス制限を導入しました。
 また、その他の要望として、構成への影響が少ないバックアップを導入することにしました。
 顧客要望をヒアリングしたり、既存環境の変更リスクや制限時間を加味したうえではできることが少なかったので、結果として良い判断だったと思います。
 

いずれの課題においてもメンバーの連携やスキルが上手く活用されて、着々と解決できたので、とても良いチームだな...と思いながら競技に取り組んでいました。

競技終了!

何とか制限時間内に「システム移行」「切り替え」「資料の納品」を完了!
朝10時に開始しましたが、気づけば17時となっていました。
DSC01366_570.jpg
競技終了後、約2時間ほどの懇親会を挟み、結果発表となります。

驚きの結果発表

まず、全体の振り返りが行われました。
DSC01372_570.jpg

そして、第三位の発表!
DSC01373_570.jpg
まさかの「該当なし」

準優勝の発表!
DSC01374_570.jpg
DSC01375_570.jpg
またも「該当なし」

そこで急遽、運営から「レギュレーション変更のお知らせ」が!
DSC01376_570.jpg
DSC01378_570.jpg
なんと、優勝チームが賞金を総取りということに!

突然の展開に 会場内がざわつきます。

 

 

優勝は.......................
DSC01381_570.jpg
DSC01382_570.jpg
Team5!!!

 
DSC01384_570.jpg
DSC01389_570.jpg
まさかの優勝でした。
(賞金100万円は メンバーと仲良く3等分に!)

感想

DSC01412_570.jpg
ということで、無事 昨年の雪辱を果たすことができました!
最後に、競技を通じて感じたことを記載しておきます。

 

1.準備の大切さ
今回は、事前に移行環境を想定したマイグレーションを行ったり、
ホームページでお題として公表されていた環境・ツールのコマンドや仕様などを、ある程度調査しておきました。

また、ディレクションを行う際は、どのようなタイムスケジュールやプランで進めるか シミュレーションして臨みました。
1.png

※必要そうなコマンドやリンクまとめ

2.jpg

※開始時の進行メモ(字が汚いですね...)

当日はディレクション担当だったので、実際にシステム移行処理を行うことは少なかったし、必要なかった情報もありましたが、準備してきた結果が自信に繋がり積極的に行動できたと思います。

 
2.チームで行動するには
チームで何かを達成するためには「お互いの不足を補い合えること」「同じ目標に向かっていること」「モチベーション」の3つが大事と考えています。

今回のチームメンバーは、スキルが高い上に 役割分担が上手くできていたので、
自ずとそれぞれ不足を補い合えたチームでした。一緒になったメンバーには とてもとても感謝しています! 

また、目標については「達成すべきこと」「達成したほうがいいこと」の違いをチーム内で明確に共有できていたのが幸いでした。実際の現場でもぶれないように心がけたいです。

モチベーションは、賞金のおかげで十分な状態でした(笑)。
3.png

※チーム内で共有していたタスク表

4.jpg

※達成すべきことである移行先環境での「サイト表示」「メール通知」を実装できていたのは、2チームだけでした。 

まとめ

業務で明確な勝敗がつくことって中々ないので、勝っても負けても貴重な経験になると思います。
もちろん賞金だけでなく、他社の方とプロジェクトを進めるなかで、いろいろなことを学べるイベントでした。
次年度も開催予定とのことですので、皆さんも是非参加してみてくださいね!

写真は公式の開催ログからお借りしました。
 写真引用元:マイグレーションコンペティション 2019 WINTER 開催ログ

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

MSPJマイグレーションコンペティションで優勝して100万円頂きました

はじめに

こんにちは、drama(@1901drama)です!
今回は、先月私が参加した「マイグレーションコンペティション」について書きます。
(AR記事でなくてすみません。。)

マイグレーションコンペティションとは

migcon2019.png
日本MSP協会が開催している競技会です。
全国から集まったメンバーでランダムにチームを組み、制限時間内に 既存システムを新たな環境へいかに移行できるか を競います。

いわゆるIT系コンテストでは 成果物の機能 を元に評価されることが多いのですが、
この競技会は、以下のような実際のサービスや顧客を意識することが評価に含まれています。

・既存環境の機能が継続して使えるか
・移行時のサービス停止をどれだけ短くできるか
・顧客とのコミュニケーションが円滑に取れているか
・その後の運用に必要な情報(システム構成、実施内容、手順書)がまとめられているか... など

また、賞金額が「3位:10万円!、準優勝:30万円!、優勝:60万円!!!」
高額なためか、ある程度技術力に自信のあるエンジニアの方が多かった印象です。

私の本職はインフラ系(元エンジニアで、今はディレクション/サービスデザイン/要件定義等)で 昨年参加したのですが、入賞さえ出来ませんでした...。
今年は、そんな昨年の悔しい思いを晴らすべく、事前に勉強し準備万全の状態で臨みました!

競技開始まで

開会時間になると、最初にメンバーの振り分けが行われます。 

今回の参加者は29名で、9チーム(1チーム3名で、2チームだけ4名編成)
私のチームは3名編成の「Team5」となりました。
DSC01327_570.jpg
※チーム分けの様子

そして、今回のお題は以下のようなものでした。

 【とある文書サイトを移行します。】
 お題:いま動いているシステムを新しい環境に移行して欲しい
 要望的な何か
 ・今の環境を新しい環境に完全移行して欲しいです。
 ・実施した内容と結果については報告が欲しいです。
 ・システムを止めるときは利用者に告知が必要なので連絡が欲しいです。
 ・昔から使っている古い環境なので、バージョンアップして欲しいです。
 ・できれば利用者に影響を出さないように切り替えたいです。
 ・できればサーバに関する資料があるとありがたいです。
 ・できれば今はまったくバックアップを取っていないのでバックアップを取れるようにしたいです
 ・できれば今後は利用者が増えるのでシステムを冗長化したいです。
 ・できれば新しいインフラエンジニアに引継ぎするために必要な情報がまとまっていると嬉しいです。
 担当者のコメント
 ・体制変更とかいろいろありまして、システムが分かる人がいなくなってしまいました。
 ・結構前から使っているので、いいタイミングなのでリフレッシュしたいなと思っています。
 ・サイト上での商売は続いているので、できるだけ利用者さんに影響が少ないと嬉しいです。
 ・そうそう、近々新しいインフラエンジニアが入社予定だから、その方に引き継げるようになっていると嬉しいですね。
 ・本当はいろいろとナウっぽいこともしていい感じにしていきたいんですよ
 ・このご時勢ですから、セキュリティ的なものも気になっていますが詳しくなくて……
 移行元環境
 ・Amazonです
 ・そろそろサポート期限が切れそうなCentOS
 ・アパッチとパイソンとギットなど
 移行先環境
 ・Microsoftのクラウドを用意しました 

お題はホームページ上で事前に公表されており、当日に詳細や 追加要望が発表されました。

競技スタート!

まず、大まかな役割分担を決めます。
事前に必要な役割を以下のように想定し、どれでもできるよう準備していました...

1.移行元環境の調査 役
2.移行先環境の構築 役
3.ディレクション(顧客対応・チームの進行・補助など) 役

が、メンバーのスキルが上手く分かれ
自分の得意分野である 3.ディレクション を担当することができました!
DSC01334_570.jpg
DSC01354_570.jpg
※競技中の様子

DSC01342_570.jpg
DSC01347_570.jpg
※昼食もあります

競技中には多くの課題があったので、特に印象に残っている課題のみ記載します。

①新環境へ移行したJenkinsから大量のワーニングログが出力されていた。

▶文書サイトを表示するために参照しているファイルが、想定外の場所にも存在していました。(外字ファイル)
 メンバーの一人が細かく稼働確認をしていたおかげで、発見することができました。

②Jenkinsの処理実行時にメール通知を行っているが、新環境では失敗していた。

▶MicroSoft Azureで作成したインスタンスは、25番ポートを標準でブロックする仕様です。
 MicroSoft Azureの特徴として事前に把握していたため、紆余曲折を経て、回避策を実施できました。

③追加要望を「どのように」「どこまで」実装するか。

▶例えば、一口に「セキュリティ強化」と言っても、想定する脅威によって導入すべき手段は異なってきます。
 今回は 文書サイトを参照できなくなることがサービス影響に対する最大の脅威と考え、
 多重アクセスを検知して次の行動に移すための監視機能と、簡易的なアクセス制限を導入しました。
 また、その他の要望として、構成への影響が少ないバックアップを導入することにしました。
 顧客要望をヒアリングしたり、既存環境の変更リスクや制限時間を加味したうえではできることが少なかったので、結果として良い判断だったと思います。
 

いずれの課題においてもメンバーの連携やスキルが上手く活用されて、着々と解決できたので、とても良いチームだな...と思いながら競技に取り組んでいました。

競技終了!

何とか制限時間内に「システム移行」「切り替え」「資料の納品」を完了!
朝10時に開始しましたが、気づけば17時となっていました。
DSC01366_570.jpg
競技終了後、約2時間ほどの懇親会を挟み、結果発表となります。

驚きの結果発表

まず、全体の振り返りが行われました。
DSC01372_570.jpg

そして、第三位の発表!
DSC01373_570.jpg
まさかの「該当なし」

準優勝の発表!
DSC01374_570.jpg
DSC01375_570.jpg
またも「該当なし」

そこで急遽、運営から「レギュレーション変更のお知らせ」が!
DSC01376_570.jpg
DSC01378_570.jpg
なんと、優勝チームが賞金を総取りということに!

突然の展開に 会場内がざわつきます。

 

 

優勝は.......................
DSC01381_570.jpg
DSC01382_570.jpg
Team5!!!

 
DSC01384_570.jpg
DSC01389_570.jpg
まさかの優勝でした。
(賞金100万円は メンバーと仲良く3等分に!)

感想

DSC01412_570.jpg
ということで、無事 昨年の雪辱を果たすことができました!
最後に、競技を通じて感じたことを記載しておきます。

 

1.準備の大切さ
今回は、事前に移行環境を想定したマイグレーションを行ったり、
ホームページでお題として公表されていた環境・ツールのコマンドや仕様などを、ある程度調査しておきました。

また、ディレクションを行う際は、どのようなタイムスケジュールやプランで進めるか シミュレーションして臨みました。
1.png

※必要そうなコマンドやリンクまとめ

2.jpg

※開始時の進行メモ(字が汚いですね...)

当日はディレクション担当だったので、実際にシステム移行処理を行うことは少なかったし、必要なかった情報もありましたが、準備してきた結果が自信に繋がり積極的に行動できたと思います。

 
2.チームで行動するには
チームで何かを達成するためには「お互いの不足を補い合えること」「同じ目標に向かっていること」「モチベーション」の3つが大事と考えています。

今回のチームメンバーは、スキルが高い上に 役割分担が上手くできていたので、
自ずとそれぞれ不足を補い合えたチームでした。一緒になったメンバーには とてもとても感謝しています! 

また、目標については「達成すべきこと」「達成したほうがいいこと」の違いをチーム内で明確に共有できていたのが幸いでした。実際の現場でもぶれないように心がけたいです。

モチベーションは、賞金のおかげで十分な状態でした(笑)。
3.png

※チーム内で共有していたタスク表

4.jpg

※達成すべきことである移行先環境での「サイト表示」「メール通知」を実装できていたのは、2チームだけでした。 

まとめ

業務で明確な勝敗がつくことって中々ないので、勝っても負けても貴重な経験になると思います。
もちろん賞金だけでなく、他社の方とプロジェクトを進めるなかで、いろいろなことを学べるイベントでした。
次年度も開催予定とのことですので、皆さんも是非参加してみてくださいね!

写真は公式の開催ログからお借りしました。
 写真引用元:マイグレーションコンペティション 2019 WINTER 開催ログ

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

マイグレーションコンペティションで優勝して100万円頂きました

はじめに

こんにちは、drama(@1901drama)です!
今回は、先月私が参加した「マイグレーションコンペティション」について書きます。
(AR記事でなくてすみません。。)

マイグレーションコンペティションとは

migcon2019.png
日本MSP協会(MSPJ)が開催している競技会です。
全国から集まったメンバーでランダムにチームを組み、制限時間内に 既存システムを新たな環境へいかに移行できるか を競います。

いわゆるIT系コンテストでは 成果物の機能 を元に評価されることが多いのですが、
この競技会は、以下のような実際のサービスや顧客を意識することが評価に含まれています。

・既存環境の機能が継続して使えるか
・移行時のサービス停止をどれだけ短くできるか
・顧客とのコミュニケーションが円滑に取れているか
・その後の運用に必要な情報(システム構成、実施内容、手順書)がまとめられているか... など

また、賞金額が「3位:10万円!、準優勝:30万円!、優勝:60万円!!!」
高額なためか、ある程度技術力に自信のあるエンジニアの方が多かった印象です。

私の本職はインフラ系(元エンジニアで、今はディレクション/サービスデザイン/要件定義等)で 昨年参加したのですが、入賞さえ出来ませんでした...。
今年は、そんな昨年の悔しい思いを晴らすべく、事前に勉強し準備万全の状態で臨みました!

競技開始まで

開会時間になると、最初にメンバーの振り分けが行われます。 

今回の参加者は29名で、9チーム(1チーム3名で、2チームだけ4名編成)
私のチームは3名編成の「Team5」となりました。
DSC01327_570.jpg
※チーム分けの様子

そして、今回のお題は以下のようなものでした。

 【とある文書サイトを移行します。】
 お題:いま動いているシステムを新しい環境に移行して欲しい
 要望的な何か
 ・今の環境を新しい環境に完全移行して欲しいです。
 ・実施した内容と結果については報告が欲しいです。
 ・システムを止めるときは利用者に告知が必要なので連絡が欲しいです。
 ・昔から使っている古い環境なので、バージョンアップして欲しいです。
 ・できれば利用者に影響を出さないように切り替えたいです。
 ・できればサーバに関する資料があるとありがたいです。
 ・できれば今はまったくバックアップを取っていないのでバックアップを取れるようにしたいです
 ・できれば今後は利用者が増えるのでシステムを冗長化したいです。
 ・できれば新しいインフラエンジニアに引継ぎするために必要な情報がまとまっていると嬉しいです。
 担当者のコメント
 ・体制変更とかいろいろありまして、システムが分かる人がいなくなってしまいました。
 ・結構前から使っているので、いいタイミングなのでリフレッシュしたいなと思っています。
 ・サイト上での商売は続いているので、できるだけ利用者さんに影響が少ないと嬉しいです。
 ・そうそう、近々新しいインフラエンジニアが入社予定だから、その方に引き継げるようになっていると嬉しいですね。
 ・本当はいろいろとナウっぽいこともしていい感じにしていきたいんですよ
 ・このご時勢ですから、セキュリティ的なものも気になっていますが詳しくなくて……
 移行元環境
 ・Amazonです
 ・そろそろサポート期限が切れそうなCentOS
 ・アパッチとパイソンとギットなど
 移行先環境
 ・Microsoftのクラウドを用意しました 

お題はホームページ上で事前に公表されており、当日に詳細や 追加要望が発表されました。

競技スタート!

まず、大まかな役割分担を決めます。
事前に必要な役割を以下のように想定し、どれでもできるよう準備していました...

1.移行元環境の調査 役
2.移行先環境の構築 役
3.ディレクション(顧客対応・チームの進行・補助など) 役

が、メンバーのスキルが上手く分かれ
自分の得意分野である 3.ディレクション を担当することができました!
DSC01334_570.jpg
DSC01354_570.jpg
※競技中の様子

DSC01342_570.jpg
DSC01347_570.jpg
※昼食もあります

競技中には多くの課題があったので、特に印象に残っている課題のみ記載します。

①新環境へ移行したJenkinsから大量のワーニングログが出力されていた。

▶文書サイトを表示するために参照しているファイルが、想定外の場所にも存在していました。(外字ファイル)
 メンバーの一人が細かく稼働確認をしていたおかげで、発見することができました。

②Jenkinsの処理実行時にメール通知を行っているが、新環境では失敗していた。

▶MicroSoft Azureで作成したインスタンスは、25番ポートを標準でブロックする仕様です。
 MicroSoft Azureの特徴として事前に把握していたため、紆余曲折を経て、回避策を実施できました。

③追加要望を「どのように」「どこまで」実装するか。

▶例えば、一口に「セキュリティ強化」と言っても、想定する脅威によって導入すべき手段は異なってきます。
 今回は 文書サイトを参照できなくなることがサービス影響に対する最大の脅威と考え、
 多重アクセスを検知して次の行動に移すための監視機能と、簡易的なアクセス制限を導入しました。
 また、その他の要望として、構成への影響が少ないバックアップを導入することにしました。
 顧客要望をヒアリングしたり、既存環境の変更リスクや制限時間を加味したうえではできることが少なかったので、結果として良い判断だったと思います。
 

いずれの課題においてもメンバーの連携やスキルが上手く活用されて、着々と解決できたので、とても良いチームだな...と思いながら競技に取り組んでいました。

競技終了!

何とか制限時間内に「システム移行」「切り替え」「資料の納品」を完了!
朝10時に開始しましたが、気づけば17時となっていました。
DSC01366_570.jpg
競技終了後、約2時間ほどの懇親会を挟み、結果発表となります。

驚きの結果発表

まず、全体の振り返りが行われました。
DSC01372_570.jpg

そして、第三位の発表!
DSC01373_570.jpg
まさかの「該当なし」

準優勝の発表!
DSC01374_570.jpg
DSC01375_570.jpg
またも「該当なし」

そこで急遽、運営から「レギュレーション変更のお知らせ」が!
DSC01376_570.jpg
DSC01378_570.jpg
なんと、優勝チームが賞金を総取りということに!

突然の展開に 会場内がざわつきます。

 

 

優勝は.......................
DSC01381_570.jpg
DSC01382_570.jpg
Team5!!!

 
DSC01384_570.jpg
DSC01389_570.jpg
まさかの優勝でした。
(賞金100万円は メンバーと仲良く3等分に!)

感想

DSC01412_570.jpg
ということで、無事 昨年の雪辱を果たすことができました!
最後に、競技を通じて感じたことを記載しておきます。

 

1.準備の大切さ
今回は、事前に移行環境を想定したマイグレーションを行ったり、
ホームページでお題として公表されていた環境・ツールのコマンドや仕様などを、ある程度調査しておきました。

また、ディレクションを行う際は、どのようなタイムスケジュールやプランで進めるか シミュレーションして臨みました。
1.png

※必要そうなコマンドやリンクまとめ

2.jpg

※開始時の進行メモ(字が汚いですね...)

当日はディレクション担当だったので、実際にシステム移行処理を行うことは少なかったし、必要なかった情報もありましたが、準備してきた結果が自信に繋がり積極的に行動できたと思います。

 
2.チームで行動するには
チームで何かを達成するためには「お互いの不足を補い合えること」「同じ目標に向かっていること」「モチベーション」の3つが大事と考えています。

今回のチームメンバーは、スキルが高い上に 役割分担が上手くできていたので、
自ずとそれぞれ不足を補い合えたチームでした。一緒になったメンバーには とてもとても感謝しています! 

また、目標については「達成すべきこと」「達成したほうがいいこと」の違いをチーム内で明確に共有できていたのが幸いでした。実際の現場でもぶれないように心がけたいです。

モチベーションは、賞金のおかげで十分な状態でした(笑)。
3.png

※チーム内で共有していたタスク表

4.jpg

※達成すべきことである移行先環境での「サイト表示」「メール通知」を実装できていたのは、2チームだけでした。 

まとめ

業務で明確な勝敗がつくことって中々ないので、勝っても負けても貴重な経験になると思います。
もちろん賞金だけでなく、他社の方とプロジェクトを進めるなかで、いろいろなことを学べるイベントでした。
次年度も開催予定とのことですので、皆さんも是非参加してみてくださいね!

写真は公式の開催ログからお借りしました。
 写真引用元:マイグレーションコンペティション 2019 WINTER 開催ログ

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

AWS Lambda - Test のアンチパターン

はじめに

Lambda 関数 のテストについていろいろと試行錯誤した結果、見通しが悪かった方法をアンチパターンとして共有します。
「MySQL アンチパターン」みたいなノリです。
FaaS として AWS Lambda を前提として記事を書いていますが、同じ考え方は他のFaaSにも適用できると思います。
専門的な概念を指す用語についてはなるべく注を書くようにしました。

:poop: アンチパターン: AWS コンソール上のエディターを開発環境として使う

Lambda 関数 を使い始めた人がまず最初にとる方法です。お手軽に始められて便利ですが、本格的に開発する場合は辛いです。ちょっとした動作確認や、数10行程度の小規模なスクリプトの開発のみに使いましょう。

具体的な方法

  • AWS コンソール上で直接 Lambda 関数 を編集する。手動で関数を実行し、目視で結果を確認する

見通しが悪い理由

  • Lambda 関数 の起動してから結果を得るまでに数秒かかる
  • 修正しながら同じテストを何度も再現するのがダルい。
    • ソースコード修正後に一度チェックをパスした試験項目がデグレる。。
  • テストに失敗した場合にどこで失敗したのかがすぐにわからない
  • 実行後に Typo や構文エラーがあることがわかり、再実行。。
  • エディタが好きなものを使えない
  • etc.

推奨する別の方法

  • ローカルで作成したテスト済みのリソースを Lambda 関数 にデプロイする
    • デプロイツールとしては AWS SAM CLI, Serverless Flamework, APEX などがある 1

:poop: アンチパターン: ローカルで Lambda 関数 を直接起動して実行結果を確認する

Lambda 関数 をローカルに起動すれば、テストの実行時間が短縮するように思えますが、テストが手動だと時間短縮はほとんど見込めません。また、E2Eテスト2を実装しても、大きなテストしか書けず、失敗した原因の調査に時間がかかります。アプリケーションが複雑になるほど開発効率は悪化します。

具体的な方法

  • sam local invoke を使って Docker コンテナ上に起動した Lambda 関数 を起動し、結果を目視で確認する、またはE2Eテストを実装する
  • lambci/docker-lambda 3 イメージから起動した Docker コンテナ上に Lambda 関数 を起動し、結果を目視で確認する、またはE2Eテストを実装する

見通しが悪い理由

  • Docker コンテナの起動に数秒かかかる。
  • 手動テストの場合、同じテストを何度も再現するのがダルい。
    • ソースコード修正後に一度チェックをパスした試験項目がデグレる。。
  • E2Eテストを実装する場合、大きいテストしか書けないので、実行に時間がかかる。
  • テストに失敗した場合にどこで失敗したのかがすぐにわからない

推奨する別の方法

  • Lambda 関数 を直接起動するのでなく、Lambda 関数 の中身を別のコードにクラスや関数として切り出し、Lambda 関数 からそのコードを呼び出すようにする
  • 別のコードに切り出した関数やクラスの単体テストを実装する

:poop: アンチパターン: ユニットテスト実行時、AWSマネージドサービスに直接アクセスする

具体的な方法

  • Lambda 関数 から機能を切り出し、単体テストを実装している
  • ユニットテスト実行時、テストコードから AWS マネージドサービスに直接アクセスする

見通しが悪い理由

  • 1回の接続で数秒かかります。何回も接続するとテスト実行から完了までに時間がかかります(数十秒〜数分)
  • AWS マネージドサービスの利用コストがかかります

推奨する別の方法

  • AWSマネージドサービスと同一の機能を再現した疑似サービス(localstack, DynamoDB local など)をローカルに起動し、テストコードから Mock Service に接続する
  • AWSマネージドサービスのインターフェースのMock4 を作成する5。または、他の人が作った Mock ライブラリを利用する6

:green_apple: ベストプラクティス

以上をまとめると、Lambda 関数 テストのベストプラクティスは以下のようになります。

  • ローカルでテスト済みのリソースを Lambda 関数 にデプロイする
    • AWS SAM CLI, Serverless Framework, APEX などのデプロイツールを使う
  • Lambda 関数 を直接起動するのでなく、Lambda 関数 の中身を別のコードにクラスや関数として切り出し、Lambda 関数 からそのコードを呼び出すようにする
  • 別のコードに切り出した関数やクラスの単体テストを実装する
  • AWSマネージドサービスと同一の機能を再現した疑似サービス(localstack, DynamoDB local など)をローカルに起動し、テストコードから Mock Service に接続する
  • AWSマネージドサービスのインターフェースを模した Mock クラスや関数を作成する。または、他の人が作った Mock を利用する。

具体的なテストの実装方法やリソースの作り方についてはサンプルコードを作っていますのでこちらを参照してください。

過去の記事「Lambda 関数 の開発について悩んだところをまとめてみた」にもLambda 関数 のテストについて記述がありますので、参考にしてみてください。

終わりに

そもそも、和田卓人さんのスライドで自分が言いたいことはすべてコンパクトにまとまっていますが、高度な概念が出てきてとっつきにくい人もいるかも? と思ったので、あえて泥臭い書き方で書きました。


  1. デプロイツールの比較については過去記事も参照してみてください。 

  2. End To End Test。システムの外側から見た振る舞いを検査するテスト。 

  3. Lambda 関数 と同一の環境を再現した Docker Image 

  4. あるサービスのインターフェースを擬似的に再現したクラスや関数のこと。 

  5. この記事で紹介されているような方法です。https://qiita.com/horike37/items/034f731f1b40c5a28e74 

  6. https://github.com/dwyl/aws-sdk-mock 

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