🐟
[AWS Copilot] Backend Service with VPCEndpoint: 手順書
これは何
-
[AWS Copilot] Backend Service with VPCEndpoint
の構築・削除手順書です。
AWS構成図
Figure1:AWS構成図
リポジトリ
環境情報
OS
Mac (Mojave 10.14.6)
VSCode
バージョン: 1.64.0 (Universal)
コミット: 5554b12acf27056905806867f251c859323ff7e9
日付: 2022-02-03T04:20:17.224Z (2 日前)
Electron: 13.5.2
Chromium: 91.0.4472.164
Node.js: 14.16.0
V8: 9.1.269.39-electron.0
OS: Darwin x64 18.7.0
aws-valut
$aws-vault --version
v6.4.0
aws-cli
$aws --version
aws-cli/2.1.21 Python/3.7.4 Darwin/18.7.0 exe/x86_64 prompt/off
aws-cdk
$node -v
v14.17.3
$npm --version
6.14.13
$cdk --version
2.8.0 (build 8a5eb49)
aws copilot
$docker --version
docker version 20.10.12, build e91ed57
$copilot -v
copilot version: v1.14.0
構築手順
1. VPCの構築
- CDKを用いてCopilotにインポートするVPCを構築します。
command
cd aws-copilot-backend-without-natgateway/resources/cdk
cdk deploy VPCStack --profile sample_profile
result
✅ VPCStack
✨ Deployment time: 235.87s
Stackファイル詳細
- VPC本体の他、各種VPCエンドポイントを定義します。 [1]
- 今回の検証ではパブリックサブネットは不要のため、プライベートサブネットのみ構築するようにしています。
vpc-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { GatewayVpcEndpointAwsService, InterfaceVpcEndpointAwsService, SubnetType, Vpc } from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';
export class VPCStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const vpc = new Vpc(this, 'sample-vpc', {
cidr: '10.0.0.0/16',
subnetConfiguration: [
{
cidrMask: 24,
// NATGateway無しでプライベートサブネットを構築するタイプ
subnetType: SubnetType.PRIVATE_ISOLATED,
name: 'private-1',
}
]
})
vpc.addInterfaceEndpoint('cloud-watch-logs', {
service:InterfaceVpcEndpointAwsService.CLOUDWATCH_LOGS
})
vpc.addInterfaceEndpoint('ecr-dkr', {
service:InterfaceVpcEndpointAwsService.ECR_DOCKER
})
vpc.addInterfaceEndpoint('ecr-api', {
service: InterfaceVpcEndpointAwsService.ECR
})
vpc.addGatewayEndpoint('s3', {
service: GatewayVpcEndpointAwsService.S3
})
vpc.addGatewayEndpoint('dynamodb', {
service: GatewayVpcEndpointAwsService.DYNAMODB
})
}
}
2. Applicationの構築 (copilot app init)
-
copilot app init
を実行し、初期設定を行います。
command
cd aws-copilot-backend-without-natgateway/resources
export AWS_PROFILE=sample_profile
copilot app init
[result] app init
Application name: my-app
✔ Created the infrastructure to manage services and jobs under application my-app.
✔ The directory copilot will hold service manifests for application my-app.
Recommended follow-up action:
- Run `copilot init` to add a new service or job to your application.
3. Environmentの構築 (copilot env init)
-
vpcId
とsubnetId
をAWS CLIを使って取得します。
command
cd aws-copilot-backend-without-natgateway/scripts
bash get-network-config.sh sample_profile
[result] get-network-config.sh
vpc-xxx
subnet-yyy,subnet-zzz
-
copilot env init
を実行します。 -
import-vpc-id
とimport-private-subnets
オプションを用いて先ほど作ったネットワーク環境をベースにリソースを構築するようにします。
command
copilot env init --import-vpc-id vpc-xxx --import-private-subnets subnet-yyy,subnet-zzz
[result] copilot env init
Environment name: dev
Credential source: [profile sample_profile]
Note: No existing subnets were found in VPC vpc-xxx.
If you proceed without at least two public subnets, you will not be able to deploy Load Balanced Web Services in this environment.
✔ Linked account 012345678910 and region us-east-1 to application my-app.
✔ Proposing infrastructure changes for the my-app-dev environment.
- Creating the infrastructure for the my-app-dev environment. [create complete] [58.0s]
- An IAM Role for AWS CloudFormation to manage resources [create complete] [14.3s]
- An ECS cluster to group your services [create complete] [11.3s]
- An IAM Role to describe resources in your environment [create complete] [11.9s]
- A security group to allow your containers to talk to each other [create complete] [6.7s]
✔ Created environment dev in region us-east-1 under application my-app.
3. Service定義の作成 (copilot svc init)
-
copilot svc init
を実行し、Service
定義を作成します。
command
cd aws-copilot-backend-without-natgateway/resources
copilot svc init
[result] copilot svc init
$copilot svc init
Note: It's best to run this command in the root of your workspace.
Service name: backend-api
Service type: Backend Service
Dockerfile: Enter custom path for your Dockerfile
Dockerfile: ../backend/api/Dockerfile
✔ Wrote the manifest for service backend-api at backend-api/manifest.yml
Your manifest contains configurations like your container size and port (:3000).
✔ Created ECR repositories for service backend-api.
Recommended follow-up actions:
- Update your manifest backend-api/manifest.yml to change the defaults.
- Run `copilot svc deploy --name backend-api --env test` to deploy your service to a test environment.
- プライベートサブネットに
Fargate
を構築するためmanifast.yml
を書き換えます。
manifast.yml
# You can override any of the values defined above by environment.
#environments:
# test:
# count: 2 # Number of tasks to run for the "test" environment.
network:
vpc:
placement: 'private'
[result] tree
|--.workspace
|--backend-api
| |--manifest.yml
4. ストレージ アドオンの追加 (copilot storage init)
-
copilot storage init
を実行します。 - 実行に成功すると
DynamoDB
のCloudFormation
テンプレートが生成されます。
command
cd aws-copilot-backend-without-natgateway/resources
copilot storage init
[result]copilot storage init
Only found one workload, defaulting to: backend-api
Storage type: DynamoDB
Storage resource name: creatures
Partition key: name
Partition key datatype: String
Sort key? No
✔ Wrote CloudFormation template at backend-api/addons/creatures.yml
Recommended follow-up actions:
- Update backend-api's code to leverage the injected environment variable CREATURES_NAME.
For example, in JavaScript you can write:
```
const storageName = process.env.CREATURES_NAME
```
- Run `copilot deploy --name backend-api` to deploy your storage resources.
- 作成したテーブルをアプリケーションで利用したい場合は、払い出された環境変数を組み込むことで利用できます。
process.env.CREATURES_NAME
[result] tree
|--.workspace
|--backend-api
| |--addons
| | |--creatures.yml #add
| |--manifest.yml
5. カスタムリソース アドオンの追加
カスタムリソースの追加
-
CloudFormation
のテンプレートをaddons
ディレクトリ配下に追加するとcopilot
のデプロイ対象として自動的に検出されます。 - この仕組みを使って
APIGateway(HTTP)
を構築します。
command
cd aws-copilot-backend-without-natgateway/resources/copilot/backend-api/addons
touch apigateway.yml
カスタムパラメータの追加
- 今回は
APIGateway
の統合先としてcopilot
側で自動構築されるCloudMap
を使います。 - そのため、
copilot svc deploy
にて生成される親Stackからパラメータ経由でARN
を受け取れるようにします。
command
cd aws-copilot-backend-without-natgateway/resources/copilot/backend-api/addons
touch addons.parameters.yml
addons.parameters.yml
Parameters:
DiscoveryServiceArn: !GetAtt DiscoveryService.Arn
apigateway.yml
Parameters:
App:
Type: String
Description: Your application's name.
Env:
Type: String
Description: The environment name your service, job, or workflow is being deployed to.
Name:
Type: String
Description: The name of the service, job, or workflow being deployed.
DiscoveryServiceArn: # add
Type: String
Description: The arn of aws cloudmap.
- 最終的なディレクトリ構成は以下のようになります。
[result] tree
|--.workspace
|--backend-api
| |--addons
| | |--addons.parameters.yml # add
| | |--apigateway.yml # add
| | |--creatures.yml
| |--manifest.yml
6. Serviceのデプロイ (copilot svc deploy)
-
copilot svc deploy
で定義したリソースをAWS環境にデプロイします。
command
cd aws-copilot-backend-without-natgateway/resources
copilot svc deploy
[result] copilot svc deploy
✔ Proposing infrastructure changes for stack my-app-dev-backend-api
- Creating the infrastructure for stack my-app-dev-backend-api [create complete] [388.1s]
- An Addons CloudFormation Stack for your additional AWS resources [create complete] [257.5s]
- An IAM ManagedPolicy for your service to access the creatures db [create complete] [14.5s]
- An Amazon DynamoDB table for creatures [create complete] [34.2s]
- Service discovery for your services to communicate within the VPC [create complete] [3.8s]
- Update your environment's shared resources [create complete] [35.8s]
- An IAM Role for the Fargate agent to make AWS API calls on your behalf [create complete] [13.9s]
- A CloudWatch log group to hold your service logs [create complete] [3.8s]
- An ECS service to run and maintain your tasks in the environment cluster [create complete] [89.5s]
Deployments
Revision Rollout Desired Running Failed Pending
PRIMARY 3 [completed] 1 1 0 0
- An ECS task definition to group your containers and run them on ECS [create complete] [4.4s]
- An IAM role to control permissions for the containers in your tasks [create complete] [15.3s]
✔ Deployed service backend-api.
Recommended follow-up action:
- You can access your service at backend-api.dev.my-app.local:3000 with service discovery.
7. Cognitoの構築
- CDKにて構築します。
command
cd aws-copilot-backend-without-natgateway/resources/cdk
cdk deploy CognitoStack --profile sample_profile
[result] cdk deploy CognitoStack
CognitoStack: creating CloudFormation changeset...
✅ CognitoStack
✨ Deployment time: 61.12s
Stack ARN:
arn:aws:cloudformation:us-east-1:012345678910:stack/CognitoStack/0ccb4520-8c16-11ec-adce-0aede6841373
✨ Total time: 70.16s
8. API実行
設定ファイルの更新
env.sh
# CognitoUser Data
readonly EMAIL=test@example.com
readonly USER_NAME=TBD
# AWS Environment
readonly REGION= #here
readonly CLIENT_ID= #here
readonly USER_POOL_ID= #here
readonly IDENTITY_POOL_ID= #here
readonly COGNITO_USER_POOL=cognito-idp.${REGION}.amazonaws.com/${USER_POOL_ID}
認証ユーザの作成
command
cd aws-copilot-backend-without-natgateway/scripts
bash create-user.sh sample_profile
EMAIL:test@example.com
PASSWORD:password
USER_NAME:sample-sub
クレデンシャルの生成
command
cd aws-copilot-backend-without-natgateway/scripts
bash get-credential.sh sample_profile password
{
"IdentityId": “xxx”,
"Credentials": {
"AccessKeyId": “***”,
"SecretKey": “***”,
"SessionToken": “***”,
"Expiration": "2022-02-13T01:32:10+09:00"
}
}
POST MAN経由でAPIを実行
- APIGatewayコンソールからエンドポイントを確認します。
- 認証モードを
AWS Signature
にして先ほど払い出した一時クレデンシャル情報を入力します。
- APIを実行します。
Verification
- データがDynamoDBに追加できていることを確認します。
削除手順
1. Cognitoの削除
設定ファイルの更新
env.sh
# CognitoUser Data
readonly EMAIL=test@example.com
readonly USER_NAME=sample-sub # here
# AWS Environment
readonly REGION=xxx
readonly CLIENT_ID=xxx
readonly USER_POOL_ID=xxx
readonly IDENTITY_POOL_ID=${REGION}:xxx
readonly COGNITO_USER_POOL=cognito-idp.${REGION}.amazonaws.com/${USER_POOL_ID}
認証ユーザの削除
command
cd aws-copilot-backend-without-natgateway/scripts
bash delete-user.sh sample_profile
[result] bash delete-user.sh
echo "USER:sample-sub is deleted."
CognitoStackの削除
command
cd aws-copilot-backend-without-natgateway/resources/cdk
cdk destroy CognitoStack --profile sample_profile
[result] cdk destory CognitoStack
Are you sure you want to delete: CognitoStack (y/n)? y
CognitoStack: destroying...
✅ CognitoStack: destroyed
2. Serviceの削除
command
cd aws-copilot-backend-without-natgateway/resources
copilot svc delete
[result] copilot svc delete
Only found one service, defaulting to: backend-api
Sure? Yes
✔ Deleted service backend-api from environment dev.
✔ Deleted resources of service backend-api from application my-app.
✔ Deleted service backend-api from application my-app.
Recommended follow-up action:
- Run `copilot pipeline update` to update the corresponding pipeline if it exists.
3. Environmentの削除
command
cd aws-copilot-backend-without-natgateway/resources
copilot env delete
[result] copilot env delete
Only found one environment, defaulting to: dev
Sure? Yes
✔ Deleted environment dev from application my-app.
4. Applicationの削除
command
cd aws-copilot-backend-without-natgateway/resources
copilot app delete
5. VPCの削除
command
cd aws-copilot-backend-without-natgateway/resources/cdk
cdk destroy VPCStack --profile sample_profile
[result] cdk destroy VPCStack
Are you sure you want to delete: VPCStack (y/n)? y
VPCStack: destroying...
✅ VPCStack: destroyed
Discussion