use codebuild
This commit is contained in:
parent
48d86e4479
commit
4847424d9b
29
buildspec.yml
Normal file
29
buildspec.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
version: 0.2
|
||||||
|
|
||||||
|
phases:
|
||||||
|
install:
|
||||||
|
runtime-versions:
|
||||||
|
nodejs: 18
|
||||||
|
commands:
|
||||||
|
- echo cloning repository...
|
||||||
|
- git clone https://git.falsy.cat/falsycat/imbusy/ .
|
||||||
|
- find
|
||||||
|
|
||||||
|
- echo installing dependencies...
|
||||||
|
- cd frontend && npm ci && cd ..
|
||||||
|
- cd backend && npm ci && cd ..
|
||||||
|
build:
|
||||||
|
commands:
|
||||||
|
- echo building frontend...
|
||||||
|
- cd frontend && npm run build && cd ..
|
||||||
|
|
||||||
|
- echo building backend...
|
||||||
|
- cd backend && npm run build && cd ..
|
||||||
|
post_build:
|
||||||
|
commands:
|
||||||
|
- echo deploying frontend...
|
||||||
|
- aws s3 sync frontend/dist/ s3://$IMBUSY_FE_BUCKET --delete
|
||||||
|
|
||||||
|
- echo deploying backend...
|
||||||
|
- cd backend/dist && zip -r ../../backend.zip . && cd ../..
|
||||||
|
- aws s3 cp backend.zip s3://$IMBUSY_BE_BUCKET
|
@ -7,18 +7,11 @@ import * as common from "./common";
|
|||||||
const tags = common.tags;
|
const tags = common.tags;
|
||||||
const prefix = `${common.prefix}-backend`;
|
const prefix = `${common.prefix}-backend`;
|
||||||
|
|
||||||
console.log("building backend...");
|
|
||||||
esbuild.buildSync({
|
|
||||||
entryPoints: ["../backend/src/index.ts"],
|
|
||||||
outfile: "../backend/dist/index.js",
|
|
||||||
bundle: true,
|
|
||||||
platform: "node",
|
|
||||||
target: "node18",
|
|
||||||
minify: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// ---- program bucket ----
|
||||||
|
export const bucket = new aws.s3.Bucket(`${prefix}-bucket`);
|
||||||
|
|
||||||
// ---- backend lambda ----
|
// ---- api lambda ----
|
||||||
const lambdaRole = new aws.iam.Role(`${prefix}-lambda-role`, {
|
const lambdaRole = new aws.iam.Role(`${prefix}-lambda-role`, {
|
||||||
tags,
|
tags,
|
||||||
assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({
|
assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({
|
||||||
@ -35,9 +28,8 @@ const lambda = new aws.lambda.Function(`${prefix}-lambda`, {
|
|||||||
runtime: "nodejs18.x",
|
runtime: "nodejs18.x",
|
||||||
handler: "index.main",
|
handler: "index.main",
|
||||||
role: lambdaRole.arn,
|
role: lambdaRole.arn,
|
||||||
code: new pulumi.asset.AssetArchive({
|
s3Bucket: bucket.arn,
|
||||||
".": new pulumi.asset.FileArchive("../backend/dist/"),
|
s3Key: "lambda.zip",
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
new aws.cloudwatch.LogGroup(`${prefix}-lambda-log-group`, {
|
new aws.cloudwatch.LogGroup(`${prefix}-lambda-log-group`, {
|
||||||
name: pulumi.interpolate`/aws/lambda/${lambda.name}`,
|
name: pulumi.interpolate`/aws/lambda/${lambda.name}`,
|
||||||
@ -60,7 +52,7 @@ new aws.dynamodb.Table(`${prefix}-db`, {
|
|||||||
|
|
||||||
|
|
||||||
// ---- API Gateway ----
|
// ---- API Gateway ----
|
||||||
const api = new aws.apigatewayv2.Api(`${prefix}-api`, {
|
export const api = new aws.apigatewayv2.Api(`${prefix}-api`, {
|
||||||
tags,
|
tags,
|
||||||
protocolType: "WEBSOCKET",
|
protocolType: "WEBSOCKET",
|
||||||
routeSelectionExpression: "$request.body.action",
|
routeSelectionExpression: "$request.body.action",
|
||||||
@ -105,8 +97,6 @@ new aws.iam.RolePolicy(`${prefix}-api-role-policy`, {
|
|||||||
}`,
|
}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const endpoint = pulumi.interpolate`${api.apiEndpoint}`;
|
|
||||||
|
|
||||||
|
|
||||||
// ---- cognito ----
|
// ---- cognito ----
|
||||||
const userPool = new aws.cognito.UserPool(`${prefix}-cognito-userpool`, {
|
const userPool = new aws.cognito.UserPool(`${prefix}-cognito-userpool`, {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import * as pulumi from "@pulumi/pulumi";
|
import * as pulumi from "@pulumi/pulumi";
|
||||||
|
import * as aws from "@pulumi/aws";
|
||||||
|
|
||||||
export const tags = {
|
export const tags = {
|
||||||
project: pulumi.getProject(),
|
project: pulumi.getProject(),
|
||||||
@ -6,3 +7,5 @@ export const tags = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const prefix = `${tags.project}-${tags.env}`;
|
export const prefix = `${tags.project}-${tags.env}`;
|
||||||
|
|
||||||
|
export const logGroupPrefix = `/falsycat/${tags.project}/${tags.env}/`;
|
||||||
|
79
infra/deployment.ts
Normal file
79
infra/deployment.ts
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import * as pulumi from "@pulumi/pulumi";
|
||||||
|
import * as aws from "@pulumi/aws";
|
||||||
|
|
||||||
|
import * as fs from "fs";
|
||||||
|
|
||||||
|
import * as common from "./common";
|
||||||
|
|
||||||
|
import * as backend from "./backend";
|
||||||
|
import * as frontend from "./frontend";
|
||||||
|
|
||||||
|
const tags = common.tags;
|
||||||
|
const prefix = `${common.prefix}-deployment`;
|
||||||
|
|
||||||
|
|
||||||
|
// ---- role ----
|
||||||
|
const role = new aws.iam.Role(`${prefix}-role`, {
|
||||||
|
tags,
|
||||||
|
assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({ Service: "codebuild.amazonaws.com" }),
|
||||||
|
});
|
||||||
|
new aws.iam.RolePolicyAttachment(`${prefix}-policy-codebuild`, {
|
||||||
|
role: role.name,
|
||||||
|
policyArn: aws.iam.ManagedPolicies.AWSCodeBuildDeveloperAccess,
|
||||||
|
});
|
||||||
|
new aws.iam.RolePolicy(`${prefix}-role-policy`, {
|
||||||
|
role: role.name,
|
||||||
|
policy: pulumi.all([backend.bucket.arn, frontend.bucket.arn]).apply(([be, fe]) => JSON.stringify({
|
||||||
|
Version: "2012-10-17",
|
||||||
|
Statement: [
|
||||||
|
{
|
||||||
|
Effect: "Allow",
|
||||||
|
Action: [
|
||||||
|
"s3:GetObject",
|
||||||
|
"s3:PutObject",
|
||||||
|
"s3:DeleteObject"
|
||||||
|
],
|
||||||
|
Resource: [ `${be}/*`, `${fe}/*`, ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Effect: "Allow",
|
||||||
|
Action: [
|
||||||
|
"s3:ListBucket",
|
||||||
|
],
|
||||||
|
Resource: [ be, fe, ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Effect: "Allow",
|
||||||
|
Action: [
|
||||||
|
"logs:CreateLogGroup",
|
||||||
|
"logs:CreateLogStream",
|
||||||
|
"logs:PutLogEvents",
|
||||||
|
],
|
||||||
|
Resource: "*",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// ---- codebuild ----
|
||||||
|
const codebuild = new aws.codebuild.Project(`${prefix}-codebuild`, {
|
||||||
|
tags,
|
||||||
|
source: {
|
||||||
|
type: "NO_SOURCE",
|
||||||
|
buildspec: fs.readFileSync("../buildspec.yml", "utf-8"),
|
||||||
|
},
|
||||||
|
environment: {
|
||||||
|
computeType: "BUILD_GENERAL1_SMALL",
|
||||||
|
image: "aws/codebuild/standard:7.0",
|
||||||
|
type: "LINUX_CONTAINER",
|
||||||
|
environmentVariables: [
|
||||||
|
{ name: "IMBUSY_BE_BUCKET", value: backend.bucket.bucket, },
|
||||||
|
{ name: "IMBUSY_FE_BUCKET", value: frontend.bucket.bucket, },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
serviceRole: role.arn,
|
||||||
|
artifacts: {
|
||||||
|
type: "NO_ARTIFACTS",
|
||||||
|
},
|
||||||
|
});
|
@ -10,33 +10,18 @@ import * as common from "./common";
|
|||||||
const tags = common.tags;
|
const tags = common.tags;
|
||||||
const prefix = `${common.prefix}-frontend`;
|
const prefix = `${common.prefix}-frontend`;
|
||||||
|
|
||||||
// ---- infra resouces ----
|
// ---- bucket ----
|
||||||
const bucket = new aws.s3.Bucket(`${prefix}-bucket`, {tags});
|
export const bucket = new aws.s3.Bucket(`${prefix}-bucket`, {tags});
|
||||||
|
const bucketOai = new aws.cloudfront.OriginAccessIdentity(`${prefix}-oai`);
|
||||||
const oai = new aws.cloudfront.OriginAccessIdentity(`${prefix}-oai`);
|
|
||||||
|
|
||||||
const bucketPolicy = new aws.s3.BucketPolicy(`${prefix}-bucket-policy`, {
|
|
||||||
bucket: bucket.bucket,
|
|
||||||
policy: pulumi.all([oai.iamArn, bucket.bucket]).apply(([a, b]) => JSON.stringify({
|
|
||||||
Version: "2012-10-17",
|
|
||||||
Statement: [{
|
|
||||||
Effect: "Allow",
|
|
||||||
Principal: {
|
|
||||||
AWS: a,
|
|
||||||
},
|
|
||||||
Action: ["s3:GetObject"],
|
|
||||||
Resource: [`arn:aws:s3:::${b}/*`],
|
|
||||||
}],
|
|
||||||
})),
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// ---- cloudfront ----
|
||||||
export const cloudfront = new aws.cloudfront.Distribution(`${prefix}-cloudfront`, {
|
export const cloudfront = new aws.cloudfront.Distribution(`${prefix}-cloudfront`, {
|
||||||
tags,
|
tags,
|
||||||
origins: [{
|
origins: [{
|
||||||
domainName: bucket.bucketRegionalDomainName,
|
domainName: bucket.bucketRegionalDomainName,
|
||||||
originId: bucket.arn,
|
originId: bucket.arn,
|
||||||
s3OriginConfig: {
|
s3OriginConfig: {
|
||||||
originAccessIdentity: oai.cloudfrontAccessIdentityPath,
|
originAccessIdentity: bucketOai.cloudfrontAccessIdentityPath,
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
enabled: true,
|
enabled: true,
|
||||||
@ -73,23 +58,3 @@ export const cloudfront = new aws.cloudfront.Distribution(`${prefix}-cloudfront`
|
|||||||
cloudfrontDefaultCertificate: true,
|
cloudfrontDefaultCertificate: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// ---- file uploads ----
|
|
||||||
(async () => {
|
|
||||||
const cwd = "../frontend/dist/";
|
|
||||||
|
|
||||||
const stats = await fs.stat(cwd);
|
|
||||||
if (!stats.isDirectory()) {
|
|
||||||
throw new Error("build the frontend firstly");
|
|
||||||
}
|
|
||||||
|
|
||||||
const files = await fg("**/*", {cwd, dot: true});
|
|
||||||
for (const file of files) {
|
|
||||||
new aws.s3.BucketObject(file, {
|
|
||||||
bucket: bucket,
|
|
||||||
source: new pulumi.asset.FileAsset(cwd+file),
|
|
||||||
contentType: mime.getType(file) || "application/octet-stream",
|
|
||||||
key: file,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
@ -4,5 +4,7 @@ import * as aws from "@pulumi/aws";
|
|||||||
import * as backend from "./backend";
|
import * as backend from "./backend";
|
||||||
import * as frontend from "./frontend";
|
import * as frontend from "./frontend";
|
||||||
|
|
||||||
|
import "./deployment";
|
||||||
|
|
||||||
export const frontendDomain = frontend.cloudfront.domainName;
|
export const frontendDomain = frontend.cloudfront.domainName;
|
||||||
export const backendEndpoint = backend.endpoint;
|
export const backendEndpoint = backend.api.apiEndpoint;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user