Skip to content

Commit 4b2669b

Browse files
horsewiniselegant
andauthored
Draft (#9)
* feat: add cdk * feat: add arch fig * initialize terraform & pulumi with golang * add .gitignore for golang * setup pulumi initial resources * add memo * create VPC * create Internet Gateway * add route table associated with Internet Gateway and public subnet for ingress * fix typo * refactor VPC resources * add private subnet and its route table * add VPC endpoint toward S3 and associate it with route table for app * Pulumi: add ECS Cluster * Pulumi: add ECR * Pulumi: add CloudWatch Log Group for app * Pulumi: add Security Group * Pulumi: create ALB and change related resources * Pulumi: aggregate AWS tag settings * Pulumi: add VPC endpoint * Pulumi: add ECS definition & related resources and revise network settings * update architecture diagram * create SSM parameter * Terraform: create VPC * Terraform: create Internet Gateway * Terraform: add public & private subnet * Terraform: add route table associated with Internet Gateway * Terraform: add VPC endpoint towards S3 and associate it with route table for app * Terraform: add Security Group * Terraform: add VPC endpoints as Interface type * Terraform: add ECS Cluster * Terraform: add IAM Role for ECS task execution * Terraform: add ECR repository * Terraform: add CloudWatch logs * Terraform: create ALB and change related resources * Terraform: add ECS definition & related resource * feat: add chap02 sample * at once * at once * feat: chap2 app yml * cfn: vpc and sg * Terraform: separate output def to other files * cfn infra module done * cfn: application layer * cdk: rename * first commit * cdk: at once * update REDOME for handson * fix up README * fix up README * fix up README * Pulumi: verup * cdk: network resources * update REDOME: increase EBS volume size * update REDOME * fix up README a bit * remove unnecessary IAM Role * Pulumi: revise parameter as secret * Terraform: verup to v1.0.0 * update REDOME * update REDOME * cdk: infra and app * update REDOME * cdk: infra and app again * fix: bootstrap command * fix: bootstrap command * cdk: add readme * initialize * cdk and cfn readme * fix up Dockerfile to remove fargate error * Pulumi: add IAM role to access SSM * Pulumi: add VPC endpoint for SSM * update REDOME * cfn: nest at once * cfn: to nested stack * cfn: add appbase * cfn: nested app stack * cfn: done * cfn: remove TODO * cfn: remove TODO * cdk: modify readme * fix: cleanup * fix: cleanup * cdk: fix ssm and readme * fix up README * at once * cdk: remove management stack * cdk: done * cdk: update readme * terraform: review * fix up a bit * fix up a bit for Pulumi chap * pulumi: review * fix up README for app * cdk: doc Co-authored-by: Masaya ARAI <[email protected]> Co-authored-by: Masaya ARAI <[email protected]>
1 parent 4fcd41c commit 4b2669b

File tree

119 files changed

+15790
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+15790
-1
lines changed

README.md

Lines changed: 263 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,263 @@
1-
# iac-story-code
1+
# クラウドネイティブIaCストーリー/サンプルコード
2+
3+
## Overview
4+
5+
本リポジトリでは「比べてわかる!IaCの選び方 ~クラウドネイティブIaCストーリー」の付録である各IaCのサンプルソースコードを提供しています。
6+
また、Cloud9上でサンプルコードを動作させる手順も併せて記載していますので、AWSアカウントをお持ちの方はぜひハンズオン感覚でお試しください。
7+
8+
## サンプルコードの種類
9+
10+
|IaCサービス|言語/フォーマット|対象ディレクトリ|
11+
|-|-|-|
12+
|CloudFormation|YAML|[cloudformation](./cloudformation)|
13+
|CDK|TypeScript|[cdk-typescript](./cdk-typescript)|
14+
|Terraform|HCL|[terraform](./terraform)|
15+
|Pulumi|Go|[pulumi-go](./pulumi-go)|
16+
17+
## サンプルコードの動作環境・バージョン情報
18+
19+
- CloudFormation: 2021年6月時点にAWS マネジメントコンソールから提供されるサービスバージョン
20+
- Template version: 2010-09-09
21+
22+
- AWS CDK: 1.106.1 (build c832c1b)
23+
- Node.js: v14.15.1
24+
25+
- Terraform: v1.0
26+
- tfenv: v2.2.2
27+
- AWS Provider: 3.45.0
28+
- Terragrant: v0.30.3
29+
30+
- Pulumi: v3.4.0
31+
- AWS Provider: v4.7.0
32+
- Go: 1.16.5
33+
34+
35+
## 構築可能なAWS環境
36+
37+
いずれのIaCサービスサンプルコードを実行しても以下のAWSサービスが構築されます。
38+
39+
![サンプルコードで作成されるAWS構成](images/iac-architecture.drawio.svg)
40+
41+
### 作成されるAWSサービス群
42+
43+
- Amazon VPC
44+
- Subnet (パブリック - AZ x 2)
45+
- Subnet (プライベートApp用 - AZ x 2)
46+
- Subnet (プライベートVPC Endpoint用 - AZ x 2)
47+
- Route Table (内部通信用)
48+
- VPC Endpoint(S3, CloudWatch Logs, ECR)
49+
- Security Group(ALB用)
50+
- Security Group(App用)
51+
- Security Group(VPC Endpoint用)
52+
- Internet Gateway
53+
- Elastic Load Balancing
54+
- ALBリスナー
55+
- ターゲットグループ
56+
- AWS IAM
57+
- Role (ECSタスク実行用)
58+
- Policy (ECSタスク実行用)
59+
- AWS Systems Manager パラメータストア
60+
- Amazon ECS
61+
- Cluster
62+
- Service
63+
- Task定義
64+
- Amazon ECR リポジトリ
65+
- Amazon CloudWatch Log Group
66+
67+
## ハンズオン実施に向けて
68+
ここでは、本リポジトリで提供するIaCサービスをハンズオンとして実施するための準備事項を記載します。
69+
70+
### 前提事項
71+
- AWSアカウントを所有していること
72+
- AdministratorAccessポリシー相当のIAMユーザもしくはIAMロールで作業可能なこと
73+
74+
### 事前準備
75+
76+
IaCサービスの実行はAWS Cloud9上で行います。
77+
ここではCloud9の作成と関連するセットアップ手順を記載します。
78+
79+
#### Amazon Cloud9の作成
80+
81+
各IaCサンプルコードを実行するためにCloud9を利用します。
82+
デフォルトで各種言語のランタイムやDocker CLIが利用できるなど、メリットがあります。
83+
早速、Cloud9用のインスタンスから作成します。
84+
85+
1. AWSマネジメントコンソール上部の [サービス] タブより [Cloud9] を選択します。
86+
2. Cloud9ダッシュボードの左側ナビゲーションメニューから [Account environments] を選択し、[Create environment] ボタンを押します。
87+
3. [Step1 Name environment] では、次のように各項目を入力後、 [Next step] ボタンを押します。
88+
89+
|項目名||
90+
|-|-|
91+
|Name|cnis-playground|
92+
|Description|(入力なし)|
93+
94+
4. [Step2 Configure settings] では、次のように各項目を入力・選択後、 [Next step] ボタンを押します。
95+
ネットワークVPC及びサブネットはデフォルトのものを選択してください(デフォルトVPCが存在しない場合、インターネットに接続可能なVPCとサブネットを選択してください)。
96+
97+
|項目名||
98+
|-|-|
99+
|Environment type|Create a new EC2 instance for environment(direct access)|
100+
|Instance type|t3.micro(2 GiB RAM + 1 vCPU)|
101+
|Platform|Amazon Linux2 (recommended)|
102+
|Cost-saving setting|After 30 minutes(default)|
103+
|Network(VPC)|vpc-xxxxxxx(default) ※インターネットに接続可能なVPC|
104+
|Subnet|subnet-xxxxxxx | Default in ap-northeast-1a|
105+
106+
5. [Review] にて入力内容を確認し、 [Create environment] ボタンを押します。
107+
108+
<img src="./images/cloud9-confirm.png">
109+
110+
6. 以下のようにCloud9コンソールが利用可能であることを確認してください。
111+
112+
<img src="./images/cloud9-main.png">
113+
114+
#### IAMユーザーの作成
115+
116+
Cloud9ではマネジメントコンソールにログインしたIAMユーザーの権限で自動的に認証権限が設定される仕組みを持っています。
117+
これは AWS Managed Temporary Credentials(以降「AMTC」と略します) と呼ばれています。
118+
119+
[AWS Managed Temporary Credentials](https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/how-cloud9-with-iam.html#auth-and-access-control-temporary-managed-credentials)
120+
121+
IAMロール等の付与等も不要であるため便利なのですが、以下のような制約があります。
122+
123+
[Actions Supported by AWS Managed Temporary Credentials](https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/how-cloud9-with-iam.html#auth-and-access-control-temporary-managed-credentials-supported)
124+
125+
今回は上記制約を回避するため、AMTCは無効化とし、別な権限からAWSCLIを実行できるようにします。
126+
TerraformやPulumiではIAMユーザーアカウントから生成されるアクセスキーIDとシークレットアクセスキーが環境変数として設定されることを期待して動作します。
127+
そのため、インスタンスプロファイルによるIAMロール付与ではなく、アクセスキーIDの設定を行います。
128+
129+
1. AWSマネジメントコンソールのトップ画面上部の [サービス] タブより [IAM] を 選択。
130+
2. IAMダッシュボードの左側ナビゲーションメニューから [ユーザー] を選択し、表示画面上部の [ユーザーを追加] ボタンを押下。
131+
3. ユーザーを追加画面にて次表の項目を選択後、[次のステップ:アクセス権限] ボタンを 押下。
132+
133+
|項目名||
134+
|-|-|
135+
|ユーザー名|cnis-user|
136+
|アクセスの種類|プログラムによるアクセス|
137+
138+
4. ユーザーを作成画面にて、[既存のポリシーを直接アタッチ]を選択し、[AdministratorAccess] にチェックを入れた後、[次ののステップ:タグ] ボタンを押下。
139+
5. ここではタグの追加はスキップ。[次のステップ:確認] ボタンを押下。
140+
6. 確認画面にて、確認画面に表示された内容を確認し、[ユーザーの作成] ボタンを押下。
141+
7. 成功の旨を確認し、表示されるアクセスキーIDとシークレットアクセスキーの値を控えておく。
142+
 
143+
#### AWSアクセスキーの設定
144+
145+
1. AWS マネジメントコンソールのトップ 画面上部の [サービス] タブより [Cloud9] を選択。
146+
2. Cloud9 ダッシュボードの左側ナビゲーションメニューから [Your environments] を選択し、表示画面中央の cnapp-playground 内 [Open IDE] ボタンを押下。コンソールが表示されるまで待つ。
147+
148+
3. コンソール上で`~/.aws/credentials`を作成し、以下のように入力して保存。
149+
```
150+
[default]
151+
aws_access_key_id=******
152+
aws_secret_access_key=******
153+
```
154+
155+
`aws_access_key_id``aws_secret_access_key`は、先程IAMユーザー作成時に払い出して作成したアクセスキーIDとシークレットアクセスキーを入力する。
156+
157+
4. コンソール上で`~/.aws/config`を作成し、以下のように入力して保存。
158+
```
159+
[profile default]
160+
region = ap-northeast-1
161+
```
162+
163+
以上でAWSアクセスキーの設定は完了です。
164+
実際には、AWSアクセスキーをそのままフラットファイルに記載してしまうのは危険なので、[aws-vault](https://github.com/99designs/aws-vault)等と組み合わせて利用するのが実運用を考えると現実的です。
165+
今回のハンズオンは簡略化のため、credentialsに記載しています。
166+
167+
#### AMTCの無効化
168+
169+
発行したAWSアクセスキーを利用するため、AMTCを無効化します。
170+
171+
1. AWS マネジメントコンソールのトップ 画面上部の [サービス] タブより [Cloud9] を選択。
172+
2. Cloud9 ダッシュボードの左側ナビゲーションメニューから [Your environments] を選択し、表示画面中央の cnapp-playground 内 [Open IDE] ボタンを押下。コンソールが表示されるまで待つ。
173+
3. 画面中央上部のタブの [+] ボタンを押し、[Open Preferences] を選択して新規タブを作成。タブ画面内の左側ナビゲーションメニューから [AWS Settings][Credentials] を選択。
174+
4. 表示される画面上の [AWS managed temporary credentials:] を OFFに設定。
175+
176+
<img src="./images/cloud9-amtc-off.png">
177+
178+
5. 以下のコマンドで作成した`cnis-user`の情報が返却できれば、AMTCではなくアクセスキーID経由でAWSCLIが実行できる状態。
179+
180+
```bash
181+
$ aws iam list-users
182+
{
183+
"Users": [
184+
{
185+
"UserName": "cnis-user",
186+
"Path": "/",
187+
:
188+
},
189+
:
190+
}
191+
```
192+
193+
以上により、Cloud9環境が整いました。
194+
195+
#### EBSボリュームサイズの変更
196+
197+
IaCによってはプロバイダーのダウンロードを行います。
198+
Cloud9のデフォルトボリュームだとサイズが足りないので、別途EBSをアタッチします。
199+
200+
1. AWS マネジメントコンソールのトップ 画面上部の [サービス] タブより [EC2] を選択。
201+
2. EC2ダッシュボードの左側ナビゲーションメニューから [インスタンス] を選択。
202+
3. インスタンス一覧画面から Name 列で [aws-cloud9-cnis-playground-] のインスタンスを選択し、画面下部の [ストレージ] を選択。
203+
4. [vol-**] から始まるボリュームIDを控えておく。
204+
5. EC2ダッシュボードの左側ナビゲーションメニューから [ボリューム] を選択。
205+
6. 手順4.で選択したボリュームID選択し、画面上部の [アクション] → [ボリュームの変更] を選択。
206+
7. ボリュームの変更画面上の [サイズ] を10 → 30 に変更した後、[変更] ボタンを押下。
207+
8. ボリュームを変更してもよいか確認する旨が表示されるので [はい] を選択。
208+
9. ボリュームの変更リクエストが成功しました、と表示されることを確認して[閉じる] ボタンを押し、ボリューム一覧画面の右上の更新ボタンを押してサイズが変更されることを確認。
209+
210+
以上でEBSボリュームサイズの変更作業は完了です。
211+
ディスクサイズ拡張を確実に反映させるため、インスタンスを再起動させておきましょう。
212+
213+
214+
#### 各種ツールのインストール
215+
216+
再びCloud9コンソールに戻り、以下をインストールしておきます。
217+
```
218+
$ sudo yum -y install tree jq
219+
```
220+
221+
### リポジトリの取得
222+
223+
Cloud9上で実行する本リポジトリを取得します。
224+
225+
1. Cloud9 IDEを開き、画面下部のコマンドラインにて以下を入力。
226+
227+
```
228+
$ git clone https://github.com/uma-arai/iac-story-code
229+
Cloning into 'iac-story-code'...
230+
:
231+
Resolving deltas: 100% (172/172), done.
232+
```
233+
234+
2. リポジトリがクローンされていることを確認。
235+
```
236+
$ cd iac-story-code/
237+
$ tree .
238+
```
239+
240+
これで各サンプルコードを実行する準備が出来ました。
241+
242+
## 各IaCサービスのハンズオン
243+
244+
本リポジトリの各IaCサービスディレクトリ配下の`README.md`に従って実施してください。
245+
246+
## 注意事項
247+
248+
- 本リポジトリは不定期にバージョンアップを行います。READMEのバージョン情報を適宜ご参照ください。
249+
- IaCサービス利用により、以下のAWSサービスが作成されます。料金が発生するサービスも含まれており、各IaCサービス用 README.md に従ってリソースの削除をオススメします。
250+
- リソースを作成したまま1ヶ月放置すると、東京リージョン(ap-northeast-1)で**約¥13,000程度請求されてしまう**ので、消し忘れにご注意ください($1=¥110換算、消費税なし)。
251+
252+
253+
## 免責事項
254+
255+
- 本リポジトリ(以降、`iac-story-code`)は利用者ご自身の判断と責任において行われるものとします。
256+
257+
- `iac-story-code`の各種情報等については、慎重に作成、管理し、正確性を保つようには努めていますが、万一記載情報が事実と異なる場合は、Issueを作成していただけると幸いです。
258+
259+
- `iac-story-code`の内容の全部または一部を事前の告知なしに変更する場合があります。
260+
261+
- `iac-story-code`上から入手された情報により発生したあらゆる損害に関して一切の責任を負いません。 ここに掲載する情報およびリンクが設定されている他のサイトから取得された各種情報の利用によって生じたあらゆる損害に関しても一切の責任を負いません。
262+
263+
- `iac-story-code`にに登場するシステム名や製品名は、関係各社の商標または登録商標です。また本書では、™、®、©などのマークは省略しています。

app/Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Multi stage building strategy for reducing image size.
2+
FROM golang:1.16.5-alpine3.13 AS build-env
3+
ENV GO111MODULE=on
4+
RUN mkdir /app
5+
ADD . /app
6+
WORKDIR /app
7+
# Use "Ultimate Packer for eXecutables". ref: https://upx.github.io/
8+
RUN apk add --no-cache --virtual .go-builddeps git gcc make build-base alpine-sdk upx&& \
9+
go mod download && \
10+
go get golang.org/x/lint/golint && \
11+
make validate && \
12+
make build-linux && \
13+
go get github.com/pwaller/goupx && \
14+
goupx main
15+
16+
FROM alpine:3.14
17+
RUN mkdir /app && \
18+
apk add --no-cache tzdata&& \
19+
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
20+
WORKDIR /app
21+
COPY --from=build-env /app/main /app
22+
EXPOSE 80
23+
ENTRYPOINT ["/app/main"]

app/Makefile

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Golang parameter(gofmt: code formatter, go vet/golist: lint tools)
2+
GOCMD=go
3+
GOFMT=go fmt
4+
GOVET=$(GOCMD) vet
5+
GOLINT=golint
6+
GOBUILD=$(GOCMD) build
7+
GOCLEAN=$(GOCMD) clean
8+
GOTEST=$(GOCMD) test
9+
GOGET=$(GOCMD) get
10+
BINARY_NAME=main
11+
BINARY_UNIX=$(BINARY_NAME)_unix
12+
13+
BUILD_PATH=.
14+
APP_PATH=.
15+
16+
all:
17+
make validate
18+
make build
19+
make run
20+
21+
# delete debug symbols by golang option -dlflags "-s -w"
22+
build:
23+
$(GOBUILD) -o $(BUILD_PATH)/$(BINARY_NAME) -ldflags "-s -w" $(APP_PATH)/main.go
24+
validate:
25+
$(GOFMT) ./...
26+
$(GOVET) ./...; $(GOLINT) -set_exit_status ./...
27+
$(GOTEST) -v ./...
28+
clean:
29+
rm -f $(BUILD_PATH)/$(BINARY_NAME)
30+
rm -f $(BUILD_PATH)/$(BINARY_UNIX)
31+
run:
32+
$(BUILD_PATH)/$(BINARY_NAME)
33+
34+
# cross-compile for linux
35+
build-linux:
36+
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 make build
37+

app/README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Demo Web API
2+
3+
## Overview
4+
This app provides demo web application coded by golang. This app is consist of three APIs.
5+
- Healthcheck API
6+
- Hello World API (turn inside the container)
7+
- DB Access API
8+
- Parameter Store Access API
9+
10+
## Prerequisite
11+
- Before start, you should build go runtime with go 1.16.5.
12+
- Download required go module for this app by following command.
13+
```bash
14+
❯ go get golang.org/x/lint/golint
15+
❯ go get
16+
❯ go mod download
17+
```
18+
- Set following env variables to connect DB.
19+
- CNAPP_DB_HOST
20+
- CNAPP_DB_USERNAME
21+
- CNAPP_DB_PASSWORD
22+
- CNAPP_DB_NAME
23+
24+
## How to Build and Deploy
25+
### Golang
26+
```bash
27+
❯ make all
28+
```
29+
### Docker
30+
```bash
31+
❯ docker build -t cnis:latest .
32+
❯ docker images
33+
REPOSITORY TAG IMAGE ID CREATED SIZE
34+
cnis latest cdb20b70f267 58 minutes ago 4.45MB
35+
:
36+
❯ docker run -d -p 80:80 cnis:latest
37+
```
38+
39+
### REST API (after deploy)
40+
```bash
41+
❯ curl http://localhost:80/cnis/v1/helloworld
42+
"Hello world!"
43+
44+
❯ curl http://localhost:80/healthcheck
45+
null
46+
```
47+
48+
## Options
49+
- If you want to deploy this app with SSL signed by self, set env
50+
variables TLS_CERT and TLS_KEY.
51+
52+
## Notes
53+
- We just check this operation only Mac OS (version 10.15).

app/app

11.2 MB
Binary file not shown.

app/domain/model/app.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package model
2+
3+
// App is entity for db result
4+
type App struct {
5+
ID string `json:"id" gorm:"column:id"`
6+
Message string `json:"message" gorm:"column:message"`
7+
}

app/domain/model/error.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package model
2+
3+
// ErrorMessages is entity for error result
4+
type ErrorMessages struct {
5+
Code string `json:"code"`
6+
Message string `json:"message"`
7+
}

0 commit comments

Comments
 (0)