Meine eigenen DevOps: Erstellen eines Nur-Cloud-CI für eine Webanwendung

Hallo Habr! Heute werden wir am Beispiel eines unserer Projekte ein wenig über DevOps und Selbstorganisation sprechen.





Beginnen wir mit einem Satz, dem die Hälfte der Entwickler in der Branche nicht zustimmt: "Jeder Entwickler sollte sein eigenes DevOps sein." Jemand ist der Meinung, dass eine separate dedizierte Person dies tun sollte, damit sich der Entwickler nur um die Qualität des Codes kümmern muss. Einige Leute neigen dazu, über die Codebereitstellungs-Pipeline genauso nachzudenken wie über den Code selbst. Ich glaube, dass ein Entwickler in der modernen Realität des Marktes und einer Fülle von Tools / Kenntnissen in der Lage sein sollte, eine Pipeline für die schnelle und vorhersehbare Lieferung eines Artefakts an die von ihm benötigte Umgebung einzurichten und zu warten. Im Gegensatz zu mobilen Entwicklern, bei denen Infrastruktur- und Anwendungsbereitstellungsprobleme weitgehend vom Anbieter (Google und Apple) gelöst werden, sollten Backend- und Webentwickler, wenn sie nicht Eigentümer sind, zumindest an Codebereitstellungspraktiken interessiert sein.





Und wir sprechen nicht über die Einrichtung einiger großer und umständlicher Build-Systeme, für die normalerweise eine ganze Personaleinheit geopfert wird. Nein. DevOps ist keine Person, sondern ein System täglicher kleiner Gewohnheiten, die auf Selbstorganisation beruhen. Ein Konzept, das von unten nach oben wächst und nicht von oben oder von der Seite. Und wenn Sie als Entwickler den Fluss von Artefakten (das amerikanische Lieblingskonzept "Value Stream") um einen kleinen Prozentsatz beschleunigen konnten, dann herzlichen Glückwunsch - dies ist bereits der DevOps-Weg. Wir empfehlen Ihnen, das DevOps-Handbuch von Gene Kim zu lesen - das beste Buch zum Verständnis dieses Konzepts (Link am Ende des Artikels).





In diesem Artikel präsentieren wir Ihnen eine kleine Geschichte der Geburt von DevOps in unserem Team, die es uns ermöglicht hat, die Entwicklung des Projekts zu beschleunigen. Diese Geschichte gilt sowohl für einen Einzelentwickler als auch für ein großes Team.





WHO

- . , :





  • 3





  • 2 , QX (QA experience)





web- Angular 9.0, .





Atlassian, " ":





  • Jira





  • Bitbucket





  • CI Bitbucket Pipelines





  • Confluence.





Bitbucket $4/, 1500 Bitbucket Pipelines. . 90 Gitlab CI, Gitlab .





. , CI Docker- .





DevOps QX (QA experience) . Jira, Bitbucket Bitrise.io -, . : , №30 №170, Jira- №500. -, -









  • -









, - .

. , master ( trunk-based development master



).





.





- web . - , - . , , . CI web , . , , "" . , , (Kubernetes OpenShift, ), . .





: ? : Heroku, AWS, Netlify, Surge . AWS S3. , , S3 - S3 . AWS.





AWS?





  • . AWS , S3 2 :





    • ~ 2





    • ~ 12





    • - ~ 5





    • = 13 Mb





  • AWS API CLI. "Surge" , Amazon AWS. , CLI Heroku , Heroku Dynos .





  • AWS.





Amazon, EC2 . Docker Hub Elastic Container Registry, $100 . -, . .





№1: S3

, S3 bucket . (bitbucket-pipelines.yml), (html/css/js/img) S3 bucket. AWS CLI, , , Bitbucket Pipes ( Github actions), Pipe S3 bucket. : , - web.s3-website.ap-northeast-2.amazonaws.com.





AWS "Enable static hosting" . bucket .





- step:
      name: Build and deploy webadmin PR version into AWS for QA
      caches:
        - node
      script:
        #  
        - apk update && apk add git
        - npm install
        # 
        - npm run build:admin
        - cd dist/admin
        #   S3
        - pipe: atlassian/aws-s3-deploy:0.2.4
          variables:
            AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
            AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
            AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
            S3_BUCKET: $S3_WEBADMIN_BUCKET_NAME
            DELETE_FLAG: 'true'
            LOCAL_PATH: $(pwd)
            ACL: 'public-read'

      
      



: - . .





:





  • -





  • QX -





№2: S3 bucket

S3 bucket . , - S3 jsn-web-manar



jsn-web-michael



. bitbucket-pipelines.yml



step - S3 PR .





: , - , , . :





  1. - . 3 -, . , . , , Chrome , - S3 .





  2. . - , , -, -. "" S3 . version-under-test .





  3. . git author name . , . , Bitbucket Pipelines Jira account, commit git author. , "Manar Kurmanov" "Dark Lord" 2 - .





️ .





:





  • -





  • QX -





№3: web

- footer :





, timestamp. - - , Jira- .





bitbucket-pipelines.yml





- step:
    name: Build PR version
    caches:
      - node
    script:
      # initial configuration
      - apk update && apk add git
      - npm install
      # preparing site footer text
      - TIMESTAMP_FILE="./src/app/some/folder/copyright.timestamp.html"
      - GIT_AUTHOR=$(git log -n 1 --format=format:'%an')
      - PR_URL="$BITBUCKET_GIT_HTTP_ORIGIN/pull-requests/$BITBUCKET_PR_ID"
      - BRANCH_TEXT="PR branch <a href=\\"$PR_URL\\">$BITBUCKET_BRANCH</a><br>"
      - echo $BRANCH_TEXT >> $TIMESTAMP_FILE
      - echo "Author $GIT_AUTHOR<br>" >> $TIMESTAMP_FILE
      - echo "Built at $(TZ=UTC-6 date '+%d-%m-%Y %H:%M') <br>" >> $TIMESTAMP_FILE
      - echo "</small>" >> $TIMESTAMP_FILE
      - cat $TIMESTAMP_FILE > src/app/target/folder/copyright.component.html
      # building artefacts
      - npm run build
    artifacts:
      paths:
        #     Build Step 
        - dist/web/**

      
      



, +100 QX, . . , 3 - S3 . ? , - S3 . Pipelines, Rerun.





, - . .





:





  • -





  • QX -





№4:

AWS API . :





  • S3 .





  • , - .









Bitbucket Pipes, AWS S3. Bitbucket Pipelines, CI , cloud-first Docker . aws-cli, AWS CLI (curl, sed, xargs).





bitbucket-pipelines.yml



. NOTE: AWS S3, .





- step:
    name: Deploy PR version into AWS bucket for QA
    image:
      name: amazon/aws-cli
    script:
      # 1.    aws cli   
      - aws configure set aws_access_key_id=$AWS_ACCESS_KEY_ID aws_secret_access_key=$AWS_SECRET_ACCESS_KEY
      # 2.     
      - export BUCKET_NAME=web-pullrequest-$BITBUCKET_PR_ID
      # 3.   AWS     ,     
      - if [ -z $(aws s3 ls | grep $BUCKET_NAME) ]; then aws s3api create-bucket --bucket $BUCKET_NAME --acl public-read --region ap-northeast-2 --create-bucket-configuration LocationConstraint=ap-northeast-2; fi
      # 4.      
      - aws s3api put-bucket-website --website-configuration "{\\"ErrorDocument\\":{\\"Key\\":\\"error.html\\"},\\"IndexDocument\\":{\\"Suffix\\":\\"index.html\\"}}" --bucket $BUCKET_NAME
      # 5.   
      - aws s3 rm s3://$BUCKET_NAME --recursive 
      # 5.     html/css/js
      - aws s3 cp dist/web s3://$BUCKET_NAME --acl public-read --recursive
      # 6.            
      - export PR_API_URL=https://api.bitbucket.org/2.0/repositories/$BITBUCKET_REPO_FULL_NAME/pullrequests/$BITBUCKET_PR_ID/comments
      - export BUCKET_PUBLIC_URL=http://$BUCKET_NAME.s3-website.ap-northeast-2.amazonaws.com
      - curl $PR_API_URL -u $CI_BB_USERNAME:$CI_BB_APP_PASSWORD --request POST --header 'Content-Type:application/json' --data "{\\"content\\":{\\"raw\\":\\"[http://$BUCKET_NAME.s3-website.ap-northeast-2.amazonaws.com](http://$BUCKET_NAME.s3-website.ap-northeast-2.amazonaws.com)\\"}}"

      
      



CI App-specific password. Atlassian , .





- .





" - S3 . ?" - . , 25 AWS - .





-.





- step:
    name: Remove dangling s3 buckets left after PR merges
    image:
        name: amazon/aws-cli
    script:
      # 1.   10  MERGED  
      - export API_URL="<https://api.bitbucket.org/2.0/repositories/$BITBUCKET_REPO_FULL_NAME/pullrequests?state=MERGED>"
      - curl "$API_URL" -u $CI_BB_USERNAME:$CI_BB_APP_PASSWORD > pr_list.json
      # 2.  ,  - 
      - aws s3 ls | grep -o '[a-zA-Z\\-]\\+pullrequest\\-[0-9]\\+' > buckets.txt
			- set +e
      #      -,   MERGED
      # (AWS API       )
      - echo "$(cat pr_list.json | grep -o '"id":\\s[0-9]\\+')" | sed 's/[^0-9]//g' | xargs -I{} grep {} buckets.txt | xargs -I{} aws s3 rm s3://{} --recursive
      #      -,   MERGED
      - echo "$(cat pr_list.json | grep -o '"id":\\s[0-9]\\+')" | sed 's/[^0-9]//g' | xargs -I{} grep {} buckets.txt | xargs -I{} aws s3api delete-bucket --bucket {}
      
      



:









  • QX - . ? , X (QX, DevX, HX) -





, .





#1: CORS

API (.amazonaws.com) (*.somebank.com), - CORS (cross origin resource sharing) . , , . , API api.server.com server.com. GET another.com "pre-flight" , "same-origin-policy".





, S3 API, Headers.





Access-Control-Allow-Origin: <http://bucket.s3-website.amazonaws.com>
# 
Access-Control-Allow-Origin: *

      
      



Cross Origin.





#2:

№4 :





aws s3 rm s3://$BUCKET_NAME --recursive 
      
      



AWS. , 4 .





, - 1 . 3 , - . , AWS API.





! S3 bucket aws-s3-deploy



pipe, , DELETE_FLAG



. bucket . #1 2 . .





#      S3   DELETE_FLAG
- pipe: atlassian/aws-s3-deploy:0.2.4
    variables:
      AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
      AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
      AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
      S3_BUCKET: $S3_WEBADMIN_BUCKET_NAME
      DELETE_FLAG: 'true' #    
      LOCAL_PATH: $(pwd)
      ACL: 'public-read'

      
      



, DevOps . , CI/CD, .





Die endgültige Version bitbucket-pipelines.yml



kann im Github-Repository angezeigt werden .





Lesematerial

  • Bitbuckets CI / CD-Tutorial - Tauchen Sie ein in das Tool





  • CORS-Unterstützung im Spring Boot





  • http://www.yamllint.com/ - hier können Sie die YAML-Struktur überprüfen, wenn dieses Tool nicht verfügbar ist





  • DevOps-Handbuch - zum Verständnis des Konzepts anhand von Beispielen. Wir empfehlen es sehr.








All Articles