이제 마이크로 프론트엔드 서비스를 깃헙 action을 가지고 AWS에 배포를 자동화할 수 있도록 파이프라인을 구축해보도록 하자.
먼저 프로젝트마다 웹팩의 배포 환경을 설정해줘야 한다.
const { merge } = require("webpack-merge");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const commonConfig = require("./webpack.common");
const packageJson = require("../package.json");
const domain = process.env.PRODUCTION_DOMAIN;
const prodConfig = {
mode: "production",
output: {
filename: "[name].[contenthash].js",
publicPath: "/container/latest/",
},
plugins: [
new ModuleFederationPlugin({
name: "container",
remotes: {
marketing: `marketing@${domain}/marketing/remoteEntry.js`,
},
shared: packageJson.dependencies,
}),
],
};
module.exports = merge(commonConfig, prodConfig);
그리고 package.js 에서 빌드 커맨드를 설정해주자.
"build": "webpack --config config/webpack.prod.js"
위와 똑같은 과정을 remote 프로젝트에도 설정을 해줘야한다.
const { merge } = require("webpack-merge");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const packageJson = require("../package.json");
const commonConfig = require("./webpack.common");
const prodConfig = {
mode: "production",
output: {
filename: "[name].[contenthash].js",
},
plugins: [
new ModuleFederationPlugin({
name: "marketing",
filename: "remoteEntry.js",
exposes: {
"./MarketingApp": "./src/bootstrap",
},
shared: packageJson.dependencies,
}),
],
};
module.exports = merge(commonConfig, prodConfig);
npm run build 커맨드를 통해 dist폴더가 잘 생성되는지 확인해볼 필요가 있다. 이제 프로젝트 레포에 소스를 푸시할 때마다 자동 배포가 되도록 설정을 해보자.
프로젝트 최상단에 아래와 같이 폴더를 생성하고 코드를 추가하자.
# container actions
name: deploy-container
on:
# container 폴더안에 있는 내용이 변경이 main 브랜치에 push 되었을 떄 발동 된다.
push:
branches:
- main
paths:
- "container/**"
# container안에서 아래의 jobs에 해당하는 작업들이 이루어지며
defaults:
run:
working-directory: container
# aws s3에 해당하는 명령어들 추가
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npm install
- run: npm run build
- uses: shinyinc/action-aws-cli@v1.2
- run: aws s3 sync dist s3://${{ secrets.AWS_S3_BUCKET_NAME }}/container/latest
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ap-northeast-2
이제 깃헙 actions를 실행할 때 필요한 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_S3_BUCKET_NAME 를 IAM을 통해 발급받자.
그리고 container 폴더 내용을 조금 수정하고 push해보면 github actions가 성공적으로 도는것을 볼 수 있다. 하지만 새로운 소스를 올려도 배포된 소스가 최신화가 안되는 현상이 발생한다. 이를 해결하기 위해선 Cloudfront가 새로운 소스가 업데이트 될 때마다 index.html의 변화를 확인해서 업데이트하게 invalidations 옵션을 활성화 시켜줘야 한다.
아래 aws invalidtaions 설정을 추가해주도록 하자.
# container actions
name: deploy-container
on:
# container 폴더안에 있는 내용이 변경이 main 브랜치에 push 되었을 떄 발동 된다.
push:
branches:
- main
paths:
- "container/**"
# container안에서 아래의 jobs에 해당하는 작업들이 이루어지며
defaults:
run:
working-directory: container
# aws s3에 해당하는 명령어들 추가
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npm install
- run: npm run build
env:
PRODUCTION_DOMAIN: ${{ secrets.PRODUCTION_DOMAIN }}
- uses: shinyinc/action-aws-cli@v1.2
- run: aws s3 sync dist s3://${{ secrets.AWS_S3_BUCKET_NAME }}/container/latest
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ap-northeast-2
- run: aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_DISTRIBUTION_ID }} --paths "/container/latest/index.html"
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ap-northeast-2
이걸로 컨테이너의 설정은 완성되었다. 이제 컨텐츠를 보여줄 수 있게 마케팅 프로젝트도 자동배포화를 설정해주자.
# marketing actions
name: deploy-marketing
on:
# marketing 폴더안에 있는 내용이 변경이 main 브랜치에 push 되었을 떄 발동 된다.
push:
branches:
- main
paths:
- "marketing/**"
# marketing안에서 아래의 jobs에 해당하는 작업들이 이루어지며
defaults:
run:
working-directory: marketing
# aws s3에 해당하는 명령어들 추가
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npm install
- run: npm run build
- uses: shinyinc/action-aws-cli@v1.2
- run: aws s3 sync dist s3://${{ secrets.AWS_S3_BUCKET_NAME }}/marketing/latest
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ap-northeast-2
- run: aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_DISTRIBUTION_ID }} --paths "/marketing/latest/remoteEntry.js"
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ap-northeast-2
const { merge } = require("webpack-merge");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const packageJson = require("../package.json");
const commonConfig = require("./webpack.common");
const prodConfig = {
mode: "production",
output: {
filename: "[name].[contenthash].js",
publicPath: "/marketing/latest/",
},
plugins: [
new ModuleFederationPlugin({
name: "marketing",
filename: "remoteEntry.js",
exposes: {
"./MarketingApp": "./src/bootstrap",
},
shared: packageJson.dependencies,
}),
],
};
module.exports = merge(commonConfig, prodConfig);