CI / CD tanpa server di AWS



Akan lebih keren jika penyebaran copy-paste adalah sesuatu dari masa lalu, tetapi, sayangnya, semuanya berbeda. Kebetulan pengembang lebih suka metode pengiriman seperti itu. Meski sekarang menulis artikel tentang mengapa ini tidak ramai, tetapi Anda tahu segalanya tanpa saya. Dengan kecenderungan arsitektur tanpa server, jaringan pipa CI / CD memainkan peran penting dalam pengiriman aplikasi. Saya juga menulis tentang mereka di artikel " 3 tips terbaik untuk proyek serverless Anda berikutnya ."


Saya sudah lama tertarik dengan topik CI dan CD, dan untuk pertama kalinya saya menemukannya beberapa tahun yang lalu - terima kasih kepada TeamCity. Saat ini, TeamCity masih digunakan untuk sebagian besar pipa CI / CD kami. TeamCity bekerja dengan baik, saya tidak menentangnya, tetapi saya selalu berusaha untuk meningkatkan pekerjaan. Sebagai contoh, akan lebih baik untuk mengumpulkan pipa dalam bentuk kode - ini adalah salah satu area di mana TeamCity tidak begitu baik.


Saya mempelajari alat integrasi dan pengiriman pada AWS beberapa waktu yang lalu, dan meskipun kami menggunakan CodeDeploy untuk proyek lain yang bekerja pada EC2, saya belum menggunakan proyek tanpa server dengan mereka. Setelah meninjau alat-alat lagi, saya perhatikan ini: sekarang ada fungsi integrasi built-in untuk menggunakan CloudFormation dan Lambda, mungkin berdasarkan SAM AWS; kami menggunakan kerangka serverless - ini menghasilkan template CloudFormation, tetapi tidak bekerja di luar kotak dengan alat AWS.


Persiapan


Saya menggunakan layanan AWS berikut: EC2, Docker, ECR, S3, IAM, CodeBuild, CodePipeline, CloudWatch, CloudTrail. Untuk tetap mengikuti, Anda harus setidaknya pada tingkat dasar memahami apa yang dilakukan masing-masing layanan ini.


Pada dasarnya, saya menulis kode sisi server dalam .NET, dan panduan ini juga bergantung pada platform ini. Tidak ada gambar CodeBuild yang sudah jadi yang memiliki .NET runtime dan NodeJS secara bersamaan (NodeJS diperlukan untuk kerangka serverless). Jika fungsi Lambda Anda ditulis dalam NodeJS, mengonfigurasi pipa penyebaran jauh lebih sederhana, karena ini adalah satu-satunya lingkungan runtime yang diperlukan untuk menginstal gambar Docker (jika kasus Anda, jangan ragu untuk melewatkan sebagian besar manual). Untuk sesaat, ini adalah pengalaman pertama saya dengan wadah, dan saya senang mempelajari sesuatu yang baru.


Saya berani berasumsi bahwa kode Anda ada di repositori tertentu, misalnya, git. Untuk panduan, kami cukup mengunggah ke S3 file yang berisi paket kode untuk penerapan; bagaimana Anda mendapatkannya terserah Anda. Berdasarkan pekerjaan saya, Anda selalu dapat melangkah lebih jauh dengan menghubungkan pipa Anda ke repositori seperti github atau CodeCommit.


1. Buat instance EC2 dan instal Docker


Jalankan instance standar AWS Linux 2 EC2 - ini harus jelas tanpa penjelasan. Masuk dan instal Docker menggunakan perintah:


sudo yum update -y sudo amazon-linux-extras install docker sudo service docker start 

Anda juga perlu menambahkan pengguna ec2 ke grup buruh pelabuhan untuk mengeksekusi perintah Docker tanpa menggunakan sudo:


 sudo usermod -a -G docker ec2-user 

Ketika perintah selesai, keluar dan masuk kembali ke instance EC2 Anda sehingga pengguna ec2 menerima izin baru. Pastikan pengguna ec2 menjalankan perintah Docker tanpa sudo:


 docker info 


Output docker info


2. Buat gambar Docker dan letakkan di ECR


Misalkan langkah sebelumnya berhasil; Langkah selanjutnya adalah membuat gambar Docker yang sesuai dengan ECR. AWS menawarkan gambar dasar untuk CodeBuild di github , dan ini membuatnya mudah untuk membuat gambar Anda sendiri.


Saya juga memposting gambar di github - jika Anda tidak ingin mengikuti langkah-langkah ini untuk membuat sendiri: https://github.com/effectivedigital/serverless-deployment-image


Salin gambar dan pergi ke direktori .NET Core 2.1:


 git clone https://github.com/aws/aws-codebuild-docker-images.git cd aws-codebuild-docker-images cd ubuntu/dot-net/core-2.1/ 

Buka Dockerfile di editor teks pilihan Anda:


 nano Dockerfile 

Tambahkan perintah untuk menginstal NodeJS dan kerangka tanpa server di akhir perintah lain yang sudah tersedia di Dockerfile. Saya mendapat sebagian besar perintah ini dari gambar NodeJS Docker di repositori AWS yang sama:


 # Install Node Dependencies ENV NODE_VERSION="10.14.1" # gpg keys listed at https://github.com/nodejs/node#release-team RUN set -ex \ && for key in \ 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \ B9AE9905FFD7803F25714661B63B535A4C206CA9 \ 77984A986EBC2AA786BC0F66B01FBB92821C587A \ 56730D5401028683275BD23C23EFEFE93C4CFFFE \ 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \ FD3A5288F042B6850C66B31F09FE44734EB7990E \ 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \ C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \ DD8F2338BAE7501E3DD5AC78C273792F7D83545D \ 4ED778F539E3634C779C87C6D7062848A1AB005C \ A48C2BEE680E841632CD4E44F07496B3EB3C1762 \ ; do \ gpg - keyserver hkp://p80.pool.sks-keyservers.net:80 - recv-keys "$key" || \ gpg - keyserver hkp://ipv4.pool.sks-keyservers.net - recv-keys "$key" || \ gpg - keyserver hkp://pgp.mit.edu:80 - recv-keys "$key" ; \ done RUN set -ex \ && wget "https://nodejs.org/download/release/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz" -O node-v$NODE_VER$ && wget "https://nodejs.org/download/release/v$NODE_VERSION/SHASUMS256.txt.asc" -O SHASUMS256.txt.asc \ && gpg - batch - decrypt - output SHASUMS256.txt SHASUMS256.txt.asc \ && grep " node-v$NODE_VERSION-linux-x64.tar.gz\$" SHASUMS256.txt | sha256sum -c - \ && tar -xzf "node-v$NODE_VERSION-linux-x64.tar.gz" -C /usr/local - strip-components=1 \ && rm "node-v$NODE_VERSION-linux-x64.tar.gz" SHASUMS256.txt.asc SHASUMS256.txt \ && ln -s /usr/local/bin/node /usr/local/bin/nodejs \ && rm -fr /var/lib/apt/lists/* /tmp/* /var/tmp/* RUN npm set unsafe-perm true CMD [ "node" ] # Install Serverless Framework RUN set -ex \ && npm install -g serverless 

Sekarang kami mengumpulkan dan memberi tag pada gambar:


 docker build -t aws/codebuild/dot-net . 

Setelah menyelesaikan perakitan, jalankan gambar - pastikan semuanya bekerja dan kerangka kerja server diinstal dengan benar:


 docker run -it --entrypoint sh aws/codebuild/dot-net -c bash sls -v 


Menjalankan sls -v di dalam sebuah wadah baru


Kemudian buat repositori dalam ECR menggunakan AWS CLI. Setelah menjalankan perintah, repositori baru akan ditampilkan di konsol AWS:


 aws ecr create-repository --repository-name codebuild-dotnet-node 


AWS CLI Respon untuk Membuat Repositori di ECR



Sekarang tandai gambar aws / codebuild / dot-net yang dibuat sebelumnya dengan value repositoryUri dari langkah sebelumnya:


 docker tag aws/codebuild/dot-net <ACCOUNTID>.dkr.ecr.ap-southeast-2.amazonaws.com/codebuild-dotnet-node 

Jalankan perintah get-login untuk mendapatkan baris perintah otentikasi login buruh pelabuhan untuk registri kontainer:


 aws ecr get-login --no-include-email 


Jalankan perintah login buruh pelabuhan yang dikeluarkan oleh perintah get-login selama langkah terakhir.


 docker login -u AWS -p eyJwYXlsb2FkIjoiNGZnd0dSaXM1L2svWWRLMmhJT1c0WWpOZEcxamJFeFJOK2VvT0Y5[...] https://<ACCOUNTID>.dkr.ecr.ap-southeast-2.amazonaws.com 

Jika login berhasil, letakkan gambar buruh pelabuhan di repositori yang dibuat di ECR. Ini mungkin memakan waktu beberapa menit (tergantung pada ukuran gambar yang selesai).


 docker push <ACCOUNTID>.dkr.ecr.ap-southeast-2.amazonaws.com/codebuild-dotnet-node 


Docker di EC2 menciptakan gambar kami



Gambar buruh pelabuhan di ECR


Kemudian kita dapat membuka akses ke gambar dari ECR ke siapa pun. Izin harus diblokir di lingkungan kerja, tetapi dalam contoh ini kita akan membukanya. Buka tab izin di konsol AWS, pilih "Ubah kebijakan JSON" dan masukkan elemen berikut ke dalam kebijakan:


 { "Version": "2008-10-17", "Statement": [ { "Sid": "EnableAccountAccess", "Effect": "Allow", "Principal": "*", "Action": [ "ecr:BatchCheckLayerAvailability", "ecr:BatchGetImage", "ecr:DescribeImages", "ecr:DescribeRepositories", "ecr:GetAuthorizationToken", "ecr:GetDownloadUrlForLayer", "ecr:GetRepositoryPolicy", "ecr:ListImages" ] } ] } 

3. Buat saluran pipa


Sudah waktunya untuk mengumpulkan pipa. Untuk menyederhanakan proses, membuatnya multi-deployable, dan tetap berpegang pada bentuk arsitektur serverless yang membawa malapetaka, saya membangun sebuah pipa menggunakan kerangka serverless. Anda dapat mencapai hasil yang sama dengan membangun di CloudFormation.


Saya tidak akan menyalin seluruh sumber dari file serverless.yml saya - menyalinnya dari github: https://github.com/effectivedigital/serverless-deployment-pipeline


Lihat templat tanpa server untuk melihat apa yang akan dilakukan, tetapi, singkatnya, ia mengatur item berikut:


  • 3 segmen S3
  • Kebijakan 1 segmen
  • 3 peran IAM
  • 1 proyek CodeBuild
  • 1 pipeline CodePipeline
  • 1 acara CloudWatch
  • 1 jejak CloudTrail

Kemudian perbarui DockerImageArn untuk gambar Anda di ECR. Jika Anda ingin membuat paket penempatan dengan nama selain Deployment.zip , maka perbarui DeploymentFilename :


 DockerImageArn: <ACCOUNTID>.dkr.ecr.ap-southeast-2.amazonaws.com/codebuild-dotnet-node:latest DeploymentFilename: Deployment.zip 

Itu saja, pipa siap untuk ditempatkan. Jalankan perintah penyebaran tanpa server dan tunggu sampai dikonfigurasi:


 sls deploy -v 


Membuat kerangka kerja serverless menumpuk CloudFormation



Dibuat oleh pipeline kerangka kerja serverless CodePipeline



Dibuat oleh proyek kerangka serverless proyek CodeBuild


4. Tambahkan buildSpec.yml ke aplikasi Anda


Ketika CodePipeline mendeteksi perubahan pada file penyebaran di S3, itu memberitahu CodeBuild untuk memulai dan mencoba membangun dan menggunakan aplikasi. Namun, CodeBuild juga harus tahu perintah apa yang harus dijalankan untuk membangun dan menyebarkan aplikasi, dan buildSpec.yml berisi instruksi yang akan diikuti CodeBuild.


Saya membuat aplikasi "Hello world" yang sangat sederhana yang mencakup contoh file buildSpec.yml yang dapat Anda gunakan: https://github.com/effectivedigital/serverless-deployment-app
Atau buat file buildSpec.yml di aplikasi yang ada dan isi sesuai dengan instruksi di bawah ini:


 version: 0.2 phases: pre_build: commands: - chmod a+x * build: commands: - ./build.sh post_build: commands: - sls deploy -v -s $STAGE 

5. Pemeriksaan saluran pipa


Sekarang semuanya siap untuk peluncuran pertama pipa Anda. Buat paket yang disebut Deployment.zip , itu harus mencakup semua file untuk aplikasi tanpa server Anda dan file buildSpec.yml.


Setelah beberapa saat, CloudTrail harus mendaftarkan acara PutObject dan mengaktifkan aturan acara CloudWatch, yang kemudian mengaktifkan pemicu CodePipeline.



Deployment.zip boot ke S3



CodePipeline diluncurkan, build aktif


Jika kita beralih ke detail langkah AWS CodeBuild, kita dapat melihat proses pembuatan dan penerapan:



CodeBuild akan menerima output dari build dan deploy image Docker



Penempatan berhasil!


Aplikasi baru yang digunakan oleh pipeline kami juga muncul di CloudFormation:



Anda dapat menguji titik akhir API yang dibuat dalam aplikasi sederhana kami (URL dalam output CodeBuild atau di Gateway API) dan pastikan bahwa aplikasi tersebut berhasil bekerja:



Tukang pos untuk menelepon API


Kesimpulan singkat


CodePipeline memungkinkan Anda untuk membuat pipa CI / CD yang skalabel, fleksibel, dan murah.Ini membantu untuk memecahkan beberapa masalah yang terkait dengan saluran pipa tradisional yang dibuat di server.
Saya ingin melangkah lebih jauh dan menambahkan pengujian unit setelah penyebaran ke dalam campuran, tetapi topik ini layak mendapatkan artikel terpisah - dan ini adalah kesempatan untuk membaca kami di masa depan!

Source: https://habr.com/ru/post/id440756/


All Articles