เขียน aws cdk ในการเชื่อมต่อ git codcommit เพื่อทำ ci/cd aws glue ประมาณ 3 jobs
ตัวอย่างการใช้ AWS CDK สำหรับการเชื่อมต่อ Git CodeCommit และสร้าง CI/CD pipeline สำหรับ AWS Glue ที่ประกอบด้วย 3 jobs:
- สร้างไฟล์
cdk.json
ที่รากของโปรเจคของคุณ (ถ้ายังไม่มี) และตั้งค่าคำสั่งเริ่มต้นสำหรับ CDK:
{
"app": "npx ts-node --prefer-ts-exts infra/app.ts"
}
- สร้างไดเรกทอรี
infra
และสร้างไฟล์infra/app.ts
ดังนี้:
import * as cdk from 'aws-cdk-lib';
import { PipelineStack } from './pipeline-stack';
const app = new cdk.App();
new PipelineStack(app, 'PipelineStack');
- สร้างไฟล์
infra/pipeline-stack.ts
ที่มีโค้ดต่อไปนี้:
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as codecommit from 'aws-cdk-lib/aws-codecommit';
import * as codepipeline from 'aws-cdk-lib/aws-codepipeline';
import * as codepipeline_actions from 'aws-cdk-lib/aws-codepipeline-actions';
import * as glue from 'aws-cdk-lib/aws-glue';
import * as iam from 'aws-cdk-lib/aws-iam';
export class PipelineStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Create a CodeCommit repository
const repo = new codecommit.Repository(this, 'GlueJobsRepo', {
repositoryName: 'glue-jobs-repo',
});
// Create a CodePipeline
const pipeline = new codepipeline.Pipeline(this, 'GlueJobsPipeline', {
pipelineName: 'glue-jobs-pipeline',
});
// Add source stage to the pipeline
const sourceOutput = new codepipeline.Artifact();
const sourceAction = new codepipeline_actions.CodeCommitSourceAction({
actionName: 'CodeCommit_Source',
repository: repo,
output: sourceOutput,
});
pipeline.addStage({
stageName: 'Source',
actions: [sourceAction],
});
// Add deploy stage to the pipeline
const deployAction = new codepipeline_actions.AwsLambdaInvokeAction({
actionName: 'Deploy_Glue_Jobs',
lambda: this.createDeploymentFunction(),
userParameters: {
glueJobNames: ['job1', 'job2', 'job3'],
},
});
pipeline.addStage({
stageName: 'Deploy',
actions: [deployAction],
});
}
private createDeploymentFunction(): lambda.Function {
// Create an IAM role for the Lambda function
const role = new iam.Role(this, 'DeploymentFunctionRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
role.addToPolicy(
new iam.PolicyStatement({
actions: [
'glue:CreateJob',
'glue:UpdateJob',
'glue:DeleteJob',
'glue:GetJob',
],
resources: ['*'],
})
);
// Create the Lambda function
return new lambda.Function(this, 'DeploymentFunction', {
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'index.handler',
code: lambda.Code.fromAsset(path.join(__dirname, 'deployment-function')),
role: role,
});
}
}
- สร้างไดเรกทอรี
infra/deployment-function
และสร้างไฟล์infra/deployment-function/index.js
ที่มีโค้ดต่อไปนี้:
const AWS = require('aws-sdk');
const glue = new AWS.Glue();
exports.handler = async (event) => {
const jobNames = event.userParameters.glueJobNames;
for (const jobName of jobNames) {
await createOrUpdateGlueJob(jobName);
}
};
async function createOrUpdateGlueJob(jobName) {
try {
await glue.getJob({ JobName: jobName }).promise();
console.log(`Updating Glue job: ${jobName}`);
// Update the job with new settings
} catch (error) {
if (error.code === 'EntityNotFoundException') {
console.log(`Creating Glue job: ${jobName}`);
// Create the job with initial settings
} else {
throw error;
}
}
}
- ติดตั้ง dependencies ของ CDK และ TypeScript ด้วยคำสั่ง:
npm install aws-cdk-lib constructs typescript ts-node
- สั่งให้ CDK สร้าง stack ด้วยคำสั่ง:
npx cdk deploy
โค้ดด้านบนจะสร้าง CodeCommit repository และ CodePipeline ที่มี 2 stages: Source และ Deploy. ในขั้นตอนการ Deploy, Lambda function จะถูกเรียกใช้เพื่อสร้างหรืออัปเดต Glue jobs ตามที่ระบุใน userParameters
. คุณสามารถปรับแต่งโค้ดใน createOrUpdateGlueJob
เพื่อกำหนดค่าต่าง ๆ สำหรับ Glue jobs ของคุณ.
แล้ว code ของแต่ละ job ที่มี .py นั้นต้องเก็บไว้ที่ไหน
คุณสามารถเก็บไฟล์ .py
ของแต่ละ job ในโฟลเดอร์ที่อยู่ใน CodeCommit repository ที่เราสร้างขึ้นก่อนหน้านี้ (ชื่อว่า glue-jobs-repo
) โดยสามารถจัดระเบียบโค้ดของ Glue jobs ตามโครงสร้างโฟลเดอร์ที่คุณต้องการ ตัวอย่างเช่น:
glue-jobs-repo/
├── job1/
│ └── job1.py
├── job2/
│ └── job2.py
└── job3/
└── job3.py
เมื่อคุณมีโค้ดของ Glue jobs ใน repository แล้ว คุณต้องปรับแต่ง Lambda function ใน infra/deployment-function/index.js
เพื่ออ่านไฟล์ .py
และส่งค่าให้กับ Glue jobs ที่ถูกสร้างหรืออัปเดต คุณสามารถทำได้ดังนี้:
- ใน
infra/pipeline-stack.ts
, ปรับแต่งuserParameters
ในAwsLambdaInvokeAction
โดยเพิ่มพารามิเตอร์jobScriptPaths
:
const deployAction = new codepipeline_actions.AwsLambdaInvokeAction({
actionName: 'Deploy_Glue_Jobs',
lambda: this.createDeploymentFunction(),
userParameters: {
glueJobNames: ['job1', 'job2', 'job3'],
jobScriptPaths: ['job1/job1.py', 'job2/job2.py', 'job3/job3.py'], // Add this line
},
});
- ใน
infra/deployment-function/index.js
, ปรับแต่งฟังก์ชันhandler
ให้รับพารามิเตอร์jobScriptPaths
และส่งค่าให้กับฟังก์ชันcreateOrUpdateGlueJob
:
exports.handler = async (event) => {
const jobNames = event.userParameters.glueJobNames;
const jobScriptPaths = event.userParameters.jobScriptPaths;
for (let i = 0; i < jobNames.length; i++) {
await createOrUpdateGlueJob(jobNames[i], jobScriptPaths[i]);
}
};
- ปรับแต่งฟังก์ชัน
createOrUpdateGlueJob
ในinfra/deployment-function/index.js
เพื่อรับพารามิเตอร์jobScriptPath
และใช้ค่านี้เมื่อสร้างหรืออัปเดต Glue job:
async function createOrUpdateGlueJob(jobName, jobScriptPath) {
// ... (existing code)
// Replace the existing try block with the following:
try {
await glue.getJob({ JobName: jobName }).promise();
console.log(`Updating Glue job: ${jobName}`);
// Update the job with new settings and script path
await glue.updateJob({
JobName: jobName,
JobUpdate: {
Command: {
ScriptLocation: `s3://your-bucket-name/${jobScriptPath}`,
},
},
}).promise();
} catch (error) {
if (error.code === 'EntityNotFoundException') {
console.log(`Creating Glue job: ${jobName}`);
// Create the job with initial settings and script path
await glue.createJob({
Name: jobName,
Role: 'your-glue-job-role-arn',
Command: {
Name: 'glueetl',
ScriptLocation: `s3://your-bucket-name/${jobScriptPath}`,
},
}).promise();
} else {
throw error;
}
}
}
อย่าลืมแทนที่ 'your-bucket-name'
และ 'your-glue-job-role-arn'
ด้วยชื่อของ S3 bucket และ ARN ของ IAM role ที่ใช้กับ Glue jobs ของคุณ
เมื่อคุณทำตามขั้นตอนด้านบนแล้ว โค้ดของ Glue jobs จะถูกอ่านจากไฟล์ .py
ใน CodeCommit repository และส่งค่าให้กับ Glue jobs ที่ถูกสร้างหรืออัปเดต