SHOW Toro TIME

ゲームや技術的なこと、最近の気になることをどんどん書いていくブログです

最近のAWSはyamlを書かずにデプロイできるらしい

お久しぶりです、小とろです。
色々あってブログが更新できなかったですが、
また改めて、ためになりそうな記事を上げていこうと思います!

私の周りでは、毎年12月になるとアドベントカレンダーなるものが、Qiitaで盛り上がりを見せます。
(Qiitaは技術職の方ならだれでもお世話になっているであろうプログラマのための技術情報共有サービスですね。)
今回はそのアドベントカレンダーで載せる記事になります。



テーマは「AWSのサービスをyamlを書かずにデプロイできる」という内容です!

f:id:shotoro:20201220171919p:plain

はじめに

この記事は株式会社富士通システムズウェブテクノロジーが企画する
いのべこ(富士通システムズウェブテクノロジー) Advent Calendar 2020の21日目の記事です。
本記事の掲載内容は私自身の見解であり、所属する組織を代表するものではありません。

今回触れる技術

AWSとは

言わずとしれた、Amazon社が提供しているクラウドサービスです。
インターネットさえ繋がっていれば、どこからでもサーバを払い出せるし自分の思うサーバ構成を作れる便利なサービスです。
幅広くインフラ面をカバーしてくれるサービスなので、日本国内でも導入事例増えているようです。
(知っている企業がたくさん!)

aws.amazon.com

その他クラウドサービス

AWSと同じようなサービスを提供している企業は他にもいます。
有名どころは以下の2社ですが、今回はAWSの話なので割愛しますね。

azure.microsoft.com

cloud.google.com

ちなみに、GCPの記事は過去にあげてます。
興味があれば是非。
www.shotoro.com

yamlとは

タイトルにyamlと書いたので、これの説明をしておこうと思います。
yamlは拡張子.yaml(または.yml)のファイルのことを指します。
yamlで書かれたファイルは、定められたルールによって書き方が決まっているので、かなり特徴的です。

どんな場面でyamlファイルが登場するかというと、
以下の場面が多いです。

  • 環境変数の定義(例:Spring Boot)

  • インフラ配備構成の定義(例:Ansible、Docker、AWS SAM)

  • CI/CD関連の定義(例:GitLab CI、AWS CodePipeline、Azure DevOps、Concourse CI)

このあたりをやっている方は良く知っているファイルなのかなと思います。

本題

そもそもAWSのデプロイについて

AWSが提供する数多のサービスをデプロイするにあたって何が使われているか...
実践的な方法は3種類あります。(手作業ではデプロイしませんよ笑)

AWS Serverless Application Model(SAM)を使う方法

ユーザが楽にAWSサービスをデプロイできるようにAWSが提供しているフレームワークの一つです。
アーキテクチャ構成を定義したyamlファイルを用意してしまえば、後はAWSが自動でyamlファイルの通りにサービスをデプロイしてくれます。

具体的には、AWS CloudFormationと呼ばれるサービスがyamlファイルを読み取ってデプロイしてくれます。

aws.amazon.com

AWS Cloud Development Kit(CDK)を使う方法

AWS Serverless Application Model(SAM)に並ぶもう一つのフレームワークAWS Cloud Development Kit(CDK)です。
AWS CloudFormationを使うところは、AWS SAMと同じですがAWS CDKはyamlで書きません!

厳密なプログラミング言語でインフラ構成のコードを書けます!
例えば、以下のような言語です。

docs.aws.amazon.com

Infrastructure as Code(IaC)ツールを使う方法

私も最近知った単語のInfrastructure as Code、
端的に言うと、インフラ構成をコードにしておくことらしいです。
この概念を実現・サポートしてくれるツールを活用して、デプロイすることができます。

例えば、HashiCorp社のTerraformが有名らしいです。

www.hashicorp.com

AWS CDKを使おう!

今回はyamlを書かずにTypeScriptといった厳密に型を定義できるような言語で定義ファイルを書ける
AWS CDKを使ってAWSサービスをデプロイしました!

AWSしか使わない、かつyamlではなくてしっかりインフラ構成をコードに書きたい場合は、これをお勧めします!

実際にやってみた

完成図

実際にやってみた時の完成図とそのソースコードです。

【完成図】
f:id:shotoro:20201220155123p:plain



ソースコード
github.com

全体的な流れ

AWS CDKのインストール

まず、npmでAWS CDKのライブラリをインストールします。

# npm install -g aws-cdk

AWS CDKのテンプレート作成

テンプレートは以下のコマンドでインストールすることができます。

【テンプレートのインストール】

# cdk init app --language=typescript"

【サンプルコード付きでテンプレートをインストール】

# cdk init sample-app --language=typescript"



全体的なインフラ構成は以下のコードのように書くことができます。

AWS API Gataway・AWS Lambdaを構成内容として書き込んでいますが、
これ以外にもDynamoDBなども書き込んでデプロイすることもできます。

import cdk = require("@aws-cdk/core")
import { Function, Runtime, Code } from "@aws-cdk/aws-lambda"
import { RestApi, Integration, LambdaIntegration, Resource,
    MockIntegration, PassthroughBehavior, EmptyModel } from "@aws-cdk/aws-apigateway"
export class APILambda extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props);
// API Gateway 作成 const restApi: RestApi = new RestApi(this, "DemoAPIGateway", { restApiName: "DemoAPIGateway", // API名 description: "Deployed by CDK" // 説明 });
// Lambda Function 作成 const lambda1Function: Function = new Function(this, "Lambda01", { functionName: "Lambda01", // 関数名 runtime: Runtime.NODEJS_10_X, // ランタイムの指定 code: Code.asset("src/Lambda01"), // ソースコードのディレクトリ handler: "index.handler", // handler の指定 memorySize: 256, // メモリーの指定 timeout: cdk.Duration.seconds(10), // タイムアウト時間 environment: {} // 環境変数 });
// Integration 作成 const integration1: Integration = new LambdaIntegration(lambda1Function);
// リソースの作成 const getResourse1: Resource = restApi.root.addResource("lambda01");
// メソッドの作成 getResourse1.addMethod("GET", integration1);
// CORS対策でOPTIONSメソッドを作成 getResourse1.addMethod("OPTIONS", new MockIntegration({ integrationResponses: [{ statusCode: "200", responseParameters: { "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'", "method.response.header.Access-Control-Allow-Origin": "'*'", "method.response.header.Access-Control-Allow-Credentials": "'false'", "method.response.header.Access-Control-Allow-Methods": "'OPTIONS,GET,PUT,POST,DELETE'", } }], passthroughBehavior: PassthroughBehavior.NEVER, requestTemplates: { "application/json": "{"statusCode": 200}" } }), { methodResponses: [{ statusCode: "200", responseParameters: { "method.response.header.Access-Control-Allow-Headers": true, "method.response.header.Access-Control-Allow-Origin": true, "method.response.header.Access-Control-Allow-Credentials": true, "method.response.header.Access-Control-Allow-Methods": true, }, responseModels: { "application/json": new EmptyModel() }, }] }) } }

デプロイ確認

デプロイは単純で、aws-cdkのコマンドを使います。

 # npm run build
 # npm run bootstrap
 # npm run deploy

bootstrapの処理については初回のみ実行できていれば良いです。
基本的には、以下の処理を行っています。

  • 対象アカウント、リージョンにつき1回だけ実施

  • CDKがデプロイのために使用するS3バケットを作成

CodePipelineで自動化

CodePipelineで自動化するために、buildspec.ymlを最後に書いています。

version: 0.2
phases: install: runtime-versions: nodejs: 12 commands: - npm install build: commands: - npm run build - npm run deploy

このファイルをテンプレートの直下に配置して、CodeCommitにプッシュしてやれば
自動でAWS CDKのライブラリによってAWSサービスがデプロイされます。

AWS CodePipeline】
f:id:shotoro:20201220170025p:plain

AWS CloudFormation】
f:id:shotoro:20201220170505p:plain

AWS API Gateway
f:id:shotoro:20201220170245p:plain

AWS Lambda】
f:id:shotoro:20201220170309p:plain

【動作確認】
f:id:shotoro:20201220170804p:plain

気づき

AWS Serverless Application Model(SAM)を経験している身から言うと、yamlでコードを書くより
AWS Cloud Development Kit(CDK)のTypeScriptで書いた方が断然良いことに気づきました。

とにかく、タイポ(入力ミス)やyaml特有の構文エラーに悩まされなくて済みます!

また、「コードの構成管理」や「デプロイの自動化」、「プロジェクト構成の棲み分け」などきっちり決めることができるので
ちゃんとした規約・運用ルールを定めれば、綺麗にかつ分かりやすい運用・開発ができると思います。

今回は、ほんの触りの部分に過ぎない内容かもですが、
本格的にプロジェクトで使うとなったら、環境別のデプロイ方法をどうするかなども含めて、
アーキテクチャを設計してもらうと良いですかね。

最後に

毎度のことですが、新しいことばかりで正直楽しいです!
こういう内容は一度知ってしまえば、いつでも思い出せるしやりたいこともイメージできるので、
アーキテクチャを考えることが多い方は是非一度は触れてみると面白いかもしれません!

以上です!