Skip to content

Commit

Permalink
feature/add-markdownlint
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryosuke Tomita committed Jan 13, 2024
1 parent 7c8775a commit a46b18f
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 153 deletions.
12 changes: 11 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ repos:
rev: v2.12.0
hooks:
- id: hadolint
#args: [--trusted-registry, grc.io, ./react-app/Dockerfile]
# args: [--trusted-registry, grc.io, ./react-app/Dockerfile]
args: [./Dockerfile]
files: Dockerfile$
# ESLint
Expand All @@ -30,3 +30,13 @@ repos:
hooks:
- id: prettier
files: \.[jt]sx?$ # *.js, *.jsx, *.ts and *.tsx

# Markdown linter
# けっこう厳しいのでVSCodeのExtensionsで見てクリティカルな部分だけ直すでもいいかも
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.38.0
hooks:
- id: markdownlint
files: '.*\.md$'
types: [file]
args: [--disable, MD010, --disable, MD013]
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ RUN npm install && npm run build

# Product Image
FROM public.ecr.aws/eks-distro-build-tooling/eks-distro-minimal-base-nginx:latest-al23
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf

# Change owner to allow non-root users to start the service
USER root
Expand All @@ -17,6 +15,9 @@ RUN mkdir -p /var/log/nginx \
&& touch /run/nginx.pid \
&& chown -R nginx:nginx /run/nginx.pid

COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf

# Use 8080 instead of 80 to avoid the `nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)` when using ECS.
EXPOSE 8080
USER nginx
Expand Down
194 changes: 113 additions & 81 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,81 +1,99 @@
# INDEX
- [ABOUT](#ABOUT)
- [ENVIRONMENT](#ENVIRONMENT)
- [PREPARING](#PREPARING)
- [HOW TO USE](#HOW-TO-USE)
- [MEMO](#MEMO)
******
# DevSecOps demo React application for AWS ECS on Fargate

## INDEX

# ENVIRONMENT
- AWS
- Github Actions
- node:20
******
- [ABOUT](#about)
- [ENVIRONMENT](#environment)
- [PREPARING](#preparing)
- [HOW TO USE](#how-to-use)
- [Error Log](#error-log)

---

## ABOUT

# ABOUT
Sample for DevSecOps environment.
If you need help or questions, please contact [twitter](https://twitter.com/sigma5736394841), issues.
## AWS

## ENVIRONMENT

- AWS
- GitHub Actions
- node:20

---

### AWS

- app-infrastructure-roles
![app-infrastructure-roles](./doc/fig/cfn/app-infrastructure-roles.png)
![app-infrastructure-roles](./doc/fig/cfn/app-infrastructure-roles.png)
- app-infrastructure
![app-infrastructure](./doc/fig/cfn/app-infrastructure.png)
![app-infrastructure](./doc/fig/cfn/app-infrastructure.png)
- environment
![env](./doc/fig/cfn/env.png)
![env](./doc/fig/cfn/env.png)
- service
![svc](./doc/fig/cfn/svc.png)
![svc](./doc/fig/cfn/svc.png)
- pipeline
![pipeline](./doc/fig/cfn/pipeline.png)
******
![pipeline](./doc/fig/cfn/pipeline.png)

---

### Automation Tools

## Automation Tools
See [./doc/tools_doc](./doc/tools_doc)
### local

#### local tools

- pre-commit,git-secret
### GitHub Actions

#### Using on GitHub Actions

- semgrep
- jest
- trivy(dependency check)

### AWS CodePipeline
#### AWS CodePipeline

- trivy(image scan)
******

---

## PREPARING

# PREPARING
## AWSの設定
copilot cliを使って環境構築を行う。
### appの作成
- 名前は任意だが,自分はreact-appとした
- ここで必用なIAMロールの一部やKMSのキーやCodePipelineに使うS3やそのポリシーが作成されている。
### AWS Settings

copilot cli を使って環境構築を行う。

#### Create app

- 名前は任意だが,自分は react-app とした
- ここで必用な IAM ロールの一部や KMS のキーや CodePipeline に使う S3 やそのポリシーが作成されている。

```shell
copilot app init
cat ./copilot/.workspace
application: react-app
```
### development用のenvironmentとserviceをまとめて作成する。
- amd64を指定しないとなぜかビルドエラーになる。
- 名前は任意だが,dev-envとdev-svcとした。
- TypeはLoad Balancerを選択した。

#### development 用のと production 用の 2 つの environment と service を作成する

- amd64 を指定しないとビルドエラーになる。
- 名前は任意だが,dev-env,dev-svc と prod-env,prod-svc とした。
- Type は Load Balancer を選択した。

```shell
DOCKER_DEFAULT_PLATFORM=linux/amd64 copilot init
```

- copilot/以下のファイルを編集することで設定を変更できる。
- 新しいVPCや,ECSのCluster,Load Balancerや権限周りが作成される。

### production用のenvironmentとserviceをまとめて作成する。
- vpcをいくつも作りたくない場合はenvironment単体で作成すると既存リソースの使用が選択できる(VPC含めて完全新規にしたいなら上の手順を繰り返す)
> [!NOTE]
> production と development で共通の VPC を使う場合には以下のようにして`copilot env init`単体で作成する
```shell
copilot env init # prod-envと命名してcopilot-react-app-dev-vpcを選択する。
```
<!-- markdownlint-disable MD033 -->
<details>
<summary>see detail</summary>
- 新しい VPC や,ECS の Cluster,Load Balancer や権限周りが作成される。

```shell
copilot env init
Expand Down Expand Up @@ -105,70 +123,79 @@ Default environment configuration? No, I'd like to import existing resources
Which VPC would you like to use? [Use arrows to move, type to filter]
> vpc-xxxxxxxxxxxxxxxxx (copilot-react-app-dev-env)
```
</details>
- environmentをデプロイ
- environment をデプロイ
```shell
copilot env deploy
```
- prod用のserviceを作成してデプロイする。
この際に間違えてdev-svcやdev-envを選ばないように注意する。
- service をデプロイする。
> [!WARNING]
> この際に間違えて dev-svc や dev-env を選ばないように注意する。
```shell
DOCKER_DEFAULT_PLATFORM=linux/amd64 copilot svc init
DOCKER_DEFAULT_PLATFORM=linux/amd64 copilot svc init # サービス作成済みなら実行しない。
copilot svc deploy
```
- ブラウザからアクセスできるか試してみる。
```shell
copilot svc show # urlが出てくるので
copilot svc show # urlが出てくるのでそこにアクセスする
```
### CodePipeline の作成
### CodePipelineの作成
- 名前は任意だが,自分はreact-app-pipelineとした。
- 名前は任意だが,自分は react-app-pipeline とした。
```shell
copilot pipeline init
```
- [manifest.yml](./copilot/pipelines/react-app-pipeline/manifest.yml)を編集してdevelopmentでサービス開始後にユーザが承認した後にproductionにデプロイされるようにする。
- [manifest.yml](./copilot/pipelines/react-app-pipeline/manifest.yml)を編集して development でサービス開始後にユーザが承認した後に production にデプロイされるようにする。
```yaml
requires_approval: true
```
requires_approval: true
```
- 先にgithubに設定ファイルをアップロードしてからpipelineをデプロイする
- 先に github に設定ファイルをアップロードしてから pipeline をデプロイする
```shell
git add .
git commit -m "add pipeline"
git push
copilot pipeline deploy
```
- ACTION REQUIREDが出るのでURLにアクセスし,pendingになっているpipelineとGitHubを接続する設定を追加する。
- 一度pipelineをデプロイすると以後,指定したGitHubのブランチにマージされるたびにCode Pipelineを通してデプロイが進むようになる。
#### CodePipelineにimage scanを追加する
- [./copilot/pipelines/react-app-pipeline/buildspec.yml](./copilot/pipelines/react-app-pipeline/buildspec.yml)を編集してtrivyによるimage scanを追加する。
```
- ACTION REQUIRED が出るので URL にアクセスし,pending になっている pipeline と GitHub を接続する設定を追加する。
- 一度 pipeline をデプロイすると以後,指定した GitHub のブランチにマージされるたびに Code Pipeline を通してデプロイが進むようになる。
#### CodePipeline に image scan を追加する
- [./copilot/pipelines/react-app-pipeline/buildspec.yml](./copilot/pipelines/react-app-pipeline/buildspec.yml)を編集して trivy による image scan を追加する。
```yaml
install:
commands:
- echo "install trivy"
- rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.48.0/trivy_0.48.0_Linux-64bit.rpm
- echo "install trivy"
- rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.48.0/trivy_0.48.0_Linux-64bit.rpm
```
```
# Run trivy scan on the docker images.
- trivy image --vuln-type os --no-progress --format table -o container-scanning-report.txt --severity CRITICAL,HIGH $(jq -r '.Parameters.ContainerImage' ./infrastructure/dev-svc-dev-env.params.json)
- cat container-scanning-report.txt
```yaml
# Run trivy scan on the docker images.
- trivy image --vuln-type os --no-progress --format table -o container-scanning-report.txt --severity CRITICAL,HIGH $(jq -r '.Parameters.ContainerImage' ./infrastructure/dev-svc-dev-env.params.json)
- cat container-scanning-report.txt
```
<details>
<summary>buildspec.ymlの解説</summary><div>
- ./infrastructureをビルドによって作成しており,この中にECRのイメージが書いてあるのでこれをjqコマンドで抜き出している。
- trivyに関する詳細は[./doc/tools_doc/trivy.md]を確認。
```
```shell
cat ./infrastructure/dev-svc-dev-env.params.json
{
"Parameters": {
Expand All @@ -182,13 +209,14 @@ xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/react-app/dev-svc:xxxxxx-xxxxx-xxxx-
```
</div></details>
******
---
## その他の設定
- ローカルでのセットアップが必用なのはgit-secretsとpre-commitくらい
- [pre-commitのドキュメント](./doc/tools_doc/pre-commit.md)
- [git-secretsのドキュメント](./doc/tools_doc/git-secret.md)
- ローカルでのセットアップが必用なのは git-secrets と pre-commit くらい
- [pre-commit のドキュメント](./doc/tools_doc/pre-commit.md)
- [git-secrets のドキュメント](./doc/tools_doc/git-secret.md)
```shell
cd devsecops-demo-aws-ecs
Expand All @@ -197,21 +225,25 @@ pre-commit install
git secrets --install
git secrets --register-aws # awsのクレデンシャル検知ルールを登録
```
- VSCodeのExtensionsもお好みで。Dockerのhadolintはおすすめ。
- GitHub Actionsがスキャン結果のファイルをアップロードできるように権限をつける。詳細は[semgrepのyaml](./.github/workflows/react-semgrep.yaml)を参照。
******
- VSCode の Extensions もお好みで。Docker の hadolint はおすすめ。
- GitHub Actions がスキャン結果のファイルをアップロードできるように権限をつける。詳細は[semgrep の yaml](./.github/workflows/react-semgrep.yaml)を参照。
---
## HOW TO USE
1. [PREPARING](#preparing)の設定を先にやる。
2. commit 時には pre-commit と git-secret が作動
3. push 時には GitHub Actions により SAST(semgrep),UnitTest(jest),Dependency Check(trivy)が実行される。
4. master ブランチにマージしたり master に push した時に CodePipeline によって AWS へリポジトリがクローンされ,ビルド(image scan を含む),development へのデプロイが始まる。
5. development で問題がなければ CodePipeline 上で承認し,production へデプロイ
---
# HOW TO USE
1. [PREPARING](#PREPARING)の設定を先にやる。
2. commit時にはpre-commitとgit-secretが作動
3. push時にはGitHub ActionsによりSAST(semgrep),UnitTest(jest),Dependency Check(trivy)が実行される。
4. masterブランチにマージしたりmasterにpushした時にCodePipelineによってAWSへリポジトリがクローンされ,ビルド(image scanを含む),developmentへのデプロイが始まる。
5. developmentで問題がなければCodePipeline上で承認し,productionへデプロイ
******
## Error Log
### nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)
# MEMO
## nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)
- [ECSの仕様で非特権ユーザを使用したコンテナでは80番ポートが使えないっぽい](https://repost.aws/questions/QU1bCV9wT4T5iBrrP1c2ISfg/container-cannot-bind-to-port-80-running-as-non-root-user-on-ecs-fargate) --> つまり,localのdockerで80でサービスが起動できてもECSだと権限エラーになる。このため,コンテナで開放するportは8080としている(ALBに対して8080がマッピングされているためブラウザからは80でアクセスできる)。
- [ECS の仕様で非特権ユーザを使用したコンテナでは 80 番ポートが使えないっぽい](https://repost.aws/questions/QU1bCV9wT4T5iBrrP1c2ISfg/container-cannot-bind-to-port-80-running-as-non-root-user-on-ecs-fargate) --> つまり,local の docker で 80 でサービスが起動できても ECS だと権限エラーになる。このため,コンテナで開放する port は 8080 としている(ALB に対して 8080 がマッピングされているためブラウザからは 80 でアクセスできる)。
6 changes: 3 additions & 3 deletions doc/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
### Change Description
# Change Description

## Reference

### Reference
- [Issue link]()
- [Issue link](example.com) <!-- replace to issue link -->
11 changes: 9 additions & 2 deletions doc/tools_doc/git-secret.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# git secrets

- パスワードのシークレットと思われる文字列を検知する。
- pre-commitを使って実装されているらしい。
- pre-commit を使って実装されているらしい。

## 環境構築

```shell
Expand All @@ -12,7 +14,11 @@ ls
sudo make install
git secrets # 動作確認
```

---

## 使用方法

- プロジェクトに移動して以下を実行

```shell
Expand All @@ -21,4 +27,5 @@ git secrets --register-aws # awsのクレデンシャル検知ルールを登録
git secrets --list # 設定を確認
git secrets --scan # スキャン
```
- また,コミットしようとした際にもscanが実行されており,特定の文字列が検知されるとコミットできなくなる。

- また,コミットしようとした際にも scan が実行されており,特定の文字列が検知されるとコミットできなくなる。
Loading

0 comments on commit a46b18f

Please sign in to comment.