AWS+Goでの環境構築
DBでユーザ作成
- DBで特定のデータベースだけ操作できるユーザを作成する
go installでマイグレーション適用
# マイグレーションツール
$ go install golang.org/x/tools/gopls@latest
# マイグレーション適用
$ /home/ec2-user/go/bin/mysqldef -u [user] -p [password] -h sample-app-db.cluster-aaaa.ap-northeast-1.rds.amazonaws.com -P 3306 point_app < ./_tools/mysql/schema.sql
CI/CDの構築
今回はdocker imageのビルドおよびECRへの登録はGitHubActionで行い、ECRからDocker Imageを取得してきて、コンテナを際デプロイするのはAWSのcodepipelineに任せる
参考
GitHub Action
- GitHubからECRにアクセスするためのIAMユーザの作成
IAM->ユーザ->ユーザ作成よりユーザを作成する
「AWS 認証情報タイプを選択」では「アクセスキー - プログラムによるアクセス」のみを選択する
ポリシーは、該当のECRにアクセスできるポリシーをアタッチする
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListImagesInRepository",
"Effect": "Allow",
"Action": [
"ecr:ListImages"
],
"Resource": [
"arn:aws:ecr:ap-northeast-1:<アカウントID>:repository/point-app-backend"
]
},
{
"Sid": "GetAuthorizationToken",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*"
},
{
"Sid": "ManageRepositoryContents",
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
],
"Resource": [
"arn:aws:ecr:ap-northeast-1:<アカウントID>:repository/point-app-backend"
]
}
]
}
作成したらAWS_SECRET_ACCESS_KEY, AWS_SECRET_KEYが表示されるのでメモする。
- workflowsの作成
mainブランチにマージされたら、dockerイメージをビルドECRに登録するworkflowを示す。
該当リポジトリの.github/workflows/aws.yml
を作成する
name: Deploy to Amazon ECR
on:
push:
branches:
- main
env:
AWS_REGION: ap-northeast-1 # set this to your preferred AWS region, e.g. us-west-1
ECR_REPOSITORY: point-app-backend # file, e.g. .aws/task-definition.json
permissions:
contents: read
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
# タグをlatestとコミットidをつけてビルド
docker image build --target deploy -t $ECR_REGISTRY/$ECR_REPOSITORY:latest -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
# ECRにpush
docker image push -a $ECR_REGISTRY/$ECR_REPOSITORY
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
-
github secretsの登録
プロジェクトのsettings->secretsを押してRepository secretsを作成をクリック。先ほどメモしたAWS_SECRET_ACCESS_KEY, AWS_SECRET_KEYをそれぞれ登録する。 -
コミットPRして完了
タグを切った時にそれをビルドする方法は以下参照
参考
CodePipeline
ECRが登録されたらそれをトリガーにECSにデプロイするCDをCodePipelineにより実現します。
- appspecファイルとタスク定義ファイルの用意
タスク定義jsonは、ECS->タスク定義->jsonよりコピーしてもってくる。ただ、 イメージは以下の様にIMAGE1_NAME
として置き換える。
{
"executionRoleArn": "arn:aws:iam::[aws_account_id]:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"logConfiguration": {
"logDriver": "awslogs",
"secretOptions": null,
"options": {
"awslogs-group": "/ecs/sbcntr-backend-def",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
},
"portMappings": [
{
"hostPort": 80,
"protocol": "tcp",
"containerPort": 80
}
],
"cpu": 256,
"readonlyRootFilesystem": true,
"environment": [],
"secrets": [
{
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:[aws_account_id]:secret:[mysql_secret_alias]:host::",
"name": "DB_HOST"
},
{
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:[aws_account_id]:secret:[mysql_secret_alias]:dbname::",
"name": "DB_NAME"
},
{
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:[aws_account_id]:secret:[mysql_secret_alias]:password::",
"name": "DB_PASSWORD"
},
{
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:[aws_account_id]:secret:[mysql_secret_alias]:username::",
"name": "DB_USERNAME"
}
],
"memory": null,
"memoryReservation": 512,
"image": "<IMAGE1_NAME>",
"essential": true,
"name": "app"
}
],
"memory": "1024",
"taskRoleArn": null,
"family": "sbcntr-backend-def",
"requiresCompatibilities": ["FARGATE"],
"networkMode": "awsvpc",
"cpu": "512"
}
version: 1
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: <TASK_DEFINITION>
LoadBalancerInfo:
ContainerName: "app"
ContainerPort: 80
-
1のファイルをS3に登録
appspec.yamlとtaskdef.jsonをzipにする
S3->パケット作成をしてrootに先ほどのzipファイルを保存する -
codepipilineの設定
codepipelineより新たに作成を選択。
名前とロールを入れて次へ
ECRを選び該当のリポオジトリを選択。画像タグはlatestにして、latestが変更されるとトリガーとなる。
ビルドはスキップ。
デプロイはとりあえず以下で登録。
登録が完了すると再度編集を押す。
Sourceを編集を押して、アクションの追加を押す。
先ほどの登録した設定を呼び出すアクションを以下の様に追加する。
次にDeployを編集し、入力アーティファクトを追加して、タスク定義とappspecファイルの読み込み先を変更する
以上で準備完了。