はじめに
これまでに投稿した記事の続きです。フロントエンドとバックエンドを別にしてデプロイしてきましたが、最終的にまとめてデプロイしました。詰まったことも併せて簡単にまとめてみます。
詰まったポイント
①フロントとAPI Gatewayの疎通
PostmanからAPI Gatewayにパラメータを送信してデータ操作ができることは確認済みなので、あとはフロントとAPI Gatewayの疎通を確認します。
そのためにまずはフロントでaxiosのアクセス先がAPI Gatewayのエンドポイントになっていることを確認します。
const getTodos = async () => {
try {
const res = await axios.get('https://hogehoge/dev/todos');
const backendResponse: Response = res.data;
if (backendResponse.status === 200) {
setTodos(backendResponse.todos);
} else {
console.error('Failed to get todos:', backendResponse);
}
} catch (error) {
console.error('Failed to get todos:', error);
}
};
②バックエンドのcors設定
headers.merge!({
'Access-Control-Allow-Origin': 'https://hogehoge.cloudfront.net',
'Access-Control-Allow-Credentials': true,
'Access-Control-Expose-Headers': 'Content-Disposition,X-Suggested-Filename',
'Content-Security-Policy': "default-src 'self'"
})
③serverless.ymlのcors設定
functions:
app:
events:
- http:
path: /
method: ANY
cors: &cors
origin: https://hogehoge.cloudfront.net
④デプロイ前にフロントはビルドする
これを忘れていてしばらく時間を費やしました。axios箇所にエンドポイントを指定してもFailed to load resource: net::ERR_CONNECTION_REFUSEDというエラーが発生します。これはビルドしていないために変更点が反映されずlocalhostにアクセスしているということが原因でした…。
動作確認
画面にアクセスしたとき
適当にToDoをつくります
画面でデータ操作できることが確認できました!
DynamoDBにも操作が反映されています。
最終的なserverless.yml
service: qiita-test
frameworkVersion: '3'
provider:
name: aws
runtime: ruby2.7
timeout: 300
region: ap-northeast-1
deploymentBucket:
name: qiita-test-bucket
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:*
Resource:
- arn:aws:dynamodb:ap-northeast-1:${aws:accountId}:table/*
- Effect: 'Allow'
Action:
- s3:GetObject
- s3:PutObject
- s3:ListBucket
- s3:DeleteObject
- s3:GetObjectTagging
- s3:PutBucketPolicy
Resource:
- arn:aws:s3:::${Bucket}
- arn:aws:s3:::${Bucket}/*
ecr:
scanOnPush: true
images:
lambda_docker:
path: ./backend
custom:
deploymentBucket:
blockPublicAccess: true
s3Sync:
- bucketName: ${self:service}-dev
localDir: reactapp/build
functions:
app:
timeout: 30
image:
name: lambda_docker
events:
- http:
path: /
method: ANY
cors: &cors
origin: https://hogehoge.cloudfront.net
headers:
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
- X-Amz-Security-Token
- X-Amz-User-Agent
- Access-Control-Allow-Headers
- Access-Control-Allow-Origin
- Time-Zone
- Cache-Control
allowCredentials: false
- http:
path: /{proxy+}
method: ANY
cors: *cors
resources:
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:service}-dev
WebsiteConfiguration:
IndexDocument: index.html
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
CorsConfiguration:
CorsRules:
- AllowedMethods:
- GET
- HEAD
AllowedOrigins:
- '*'
BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref Bucket
PolicyDocument:
Statement:
- Action:
- s3:GetObject
Effect: Allow
Resource: !Sub arn:aws:s3:::${Bucket}/*
Principal:
Service: cloudfront.amazonaws.com
Condition:
StringEquals:
AWS:SourceArn: !Sub arn:aws:cloudfront::${aws:accountId}:distribution/${Distribution}
Distribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
DefaultCacheBehavior:
TargetOriginId: ${self:service}-dev
ForwardedValues:
QueryString: false
ViewerProtocolPolicy: https-only
Enabled: true
DefaultRootObject: index.html
Origins:
- Id: ${self:service}-dev
DomainName: !GetAtt Bucket.RegionalDomainName
S3OriginConfig:
OriginAccessIdentity: ''
OriginAccessControlId: !GetAtt CloudFrontOriginAccessControl.Id
CloudFrontOriginAccessControl:
Type: AWS::CloudFront::OriginAccessControl
Properties:
OriginAccessControlConfig:
Description: Default Origin Access Control
Name: !Ref AWS::StackName
OriginAccessControlOriginType: s3
SigningBehavior: always
SigningProtocol: sigv4
Outputs:
URL:
Value: !Sub "https://${Distribution.DomainName}"
DistributionId:
Value: !Ref Distribution
plugins:
- serverless-deployment-bucket
- serverless-s3-sync
おわりに
ようやく一区切りつきました。今回は予めタスクを作って時間を測り、再現性を高める試みをしていたのですが、デプロイ周りで色々詰まってしまいました。次はアプリの内容にこだわってみたいです。まだまだ学ぶことが多いので頑張ります。