استقرار و برچسب زدن تصاویر کانتینر ECR در AWS CodePipeline

AWS CodePipeline محبوب ترین یا قوی ترین ابزار خط لوله در آنجا نیست ، اما به راحتی در AWS در دسترس است و برای اکثر سناریوها به خوبی کار می کند. با این حال ، من اغلب مجبور شدم مراحل سفارشی را ایجاد کنم که انتظار داشتم در آنجا ادغام های از پیش ساخته شود. خوشبختانه ، CodePipeline به اندازه کافی انعطاف پذیر است تا از ساخت مراحل خود از طریق AWS CodeBuild و AWS Lambda پشتیبانی کند ، و من دو مثال دارم که انتظار دارم برای بسیاری دیگر مفید باشد که دوست دارم آنها را به اشتراک بگذارم.
نمای کلی خط لوله
برای این سناریو ، تصور کنید که تصاویر کانتینر داریم که قبلاً ساخته شده و به Amazon ECR سوق داده شده است. ما می خواهیم (1) آنها را به آمازون ECS مستقر کنیم و سپس (2) تصویر را برچسب گذاری کنیم تا محیطی را که تصویر در آن اجرا می شود ، نشان دهد.
استقرار از ECR به ECS
اقدام CodePipeline برای استقرار یک ظرف در ECS نیاز به ورودی دارد FileName
از یک فایل JSON با نام کانتینر سرویس هدف و تصویری که باید مستقر شود. متأسفانه ، عملکرد منبع ECR این پرونده را با فرمت صحیح خروجی نمی کند.
در این حالت ، ما باید یک مرحله CodeBuild را بین اقدام منبع و اقدام به کارآیی برای خروج پرونده مورد نیاز در قالب صحیح اضافه کنیم. BuildSpec برای پروژه CodeBuild شامل یک دستور واحد است:
version: 0.2
phases:
build:
commands:
- printf '[{"name":"%s","imageUri":"%s:latest"}]' "$TASK_FAMILY" "$REPOSITORY_URI" > imagedefinitions.json
artifacts:
files: imagedefinitions.json
این پرونده JSON مورد نیاز را می نویسد و آن را به عنوان مصنوعاتی که می تواند در طول اقدام استقرار ارجاع شود ، خروجی می کند.
برچسب زدن تصاویر ECR در CodePipeline
این می تواند ارزشمند باشد که نشان می دهد کدام تصاویر در واقع در محیط شما مستقر شده اند ، به ویژه که به تولید آن ارتقا یافته است. این امر به ابزار مدیریت آسیب پذیری و پرسنل اجازه می دهد تا خطر آسیب پذیری های شناسایی شده در یک تصویر را ارزیابی کنند – اگر تصویر به تولید مستقر شود که یک خطر واقعی در مقایسه با یک تصویر قدیمی است که فقط در ECR بی رنگ است.
ما می توانیم یک تابع Lambda AWS را برای برچسب زدن تصاویر در هنگام ایجاد CodePipeline بسازیم. ابتدا ، پیکربندی Action CodePipeline باید عملکرد پارامترهای مورد نیاز را در UserParameters
میدان
- Name: TagImageWithProd
RunOrder: 3
ActionTypeId:
Category: Invoke
Owner: AWS
Provider: Lambda
Version: "1"
Configuration:
FunctionName:
Fn::ImportValue: !Sub ${PipelineTagStack}-FunctionName
UserParameters: "{\"RepositoryName\": \"#{ImageVariables.RepositoryName}\", \"ImageTag\": \"#{ImageVariables.ImageTag}\" , \"NewImageTag\": \"prod\", \"ImageDigest\": \"#{ImageVariables.ImageDigest}\", \"ImageURI\": \"#{ImageVariables.ImageURI}\"}"
در عملکرد Lambda می توانیم پارامترهای مورد نیاز را از رویداد CodePipeline جدا کنیم.
codepipeline_job_id = event["CodePipeline.job"]["id"]
user_parameters = json.loads(
event["CodePipeline.job"]["data"]["actionConfiguration"]["configuration"][
"UserParameters"
]
)
image_uri = user_parameters["ImageURI"]
repository_name = user_parameters["RepositoryName"]
image_tag = user_parameters["ImageTag"]
new_image_tag = user_parameters["NewImageTag"]
برای برچسب زدن تصویر با استفاده از ECR Putimage API ، با این حال ، ما به مانیفست تصویر نیز احتیاج خواهیم داشت. بنابراین ابتدا ما این را بازیابی می کنیم که با استفاده از ECR Batch Image دریافت کنید.
image_manifest = ecr_client.batch_get_image(
repositoryName=repository_name,
imageIds=[
{
"imageTag": image_tag,
}
],
)["images"][0]["imageManifest"]
اکنون ما هر آنچه را که لازم داریم داریم و می توانیم تصویر را در ECR برچسب گذاری کنیم.
ecr_client.put_image(
repositoryName=repository_name,
imageTag=new_image_tag,
imageManifest=image_manifest,
)
و در آخر ، فراموش نکنید که به CodePipeline بگویید که عمل شما موفق شده است (یا شکست خورده است) ، یا خط لوله حدود 15 دقیقه منتظر خواهد ماند.
codepipeline_client.put_job_success_result(jobId=codepipeline_job_id)
codepipeline_client.put_job_failure_result(
jobId=codepipeline_job_id,
failureDetails={
"type": "JobFailed",
"message": "Error tagging image",
},
)
اگرچه من ترجیح می دادم این اقدامات بدون کار اضافی در دسترس باشد ، اما انعطاف پذیری AWS دوباره باعث می شود بدون مشکل زیاد کار کند.