Quay lại

Triển khai Và Tự động Hóa Quản lý Cơ Sở Hạ Tầng Với Ansible Trên AWS EC2 Chuyên mục Devops    2024-05-14    3 Lượt xem    3 Lượt thích    comment-3 Created with Sketch Beta. 0 Bình luận

Triển khai Và Tự động Hóa Quản lý Cơ Sở Hạ Tầng Với Ansible Trên AWS EC2

Việc triển khai và quản lý cơ sở hạ tầng là một phần không thể thiếu đối với sự thành công của các dự án. AWS (Amazon Web Services) cung cấp một nền tảng mạnh mẽ cho việc xây dựng và vận hành các ứng dụng, trong đó EC2 (Elastic Compute Cloud) là dịch vụ cung cấp các máy ảo đám mây linh hoạt và mạnh mẽ.

Trong quá trình triển khai và quản lý các EC2 instance trên AWS, việc sử dụng các công cụ tự động hóa như Ansible là một lựa chọn thông minh và hiệu quả. Ansible, một công cụ tự động hóa cấu hình và triển khai mã nguồn mở, cung cấp một cách tiếp cận đơn giản và linh hoạt để quản lý cơ sở hạ tầng của bạn.

Trong bài này, chúng ta sẽ tìm hiểu về cách Ansible có thể được sử dụng để:

  • Triển khai và cấu hình EC2 instances trên AWS một cách tự động và nhất quán.
  • Tự động hóa quá trình cài đặt và cập nhật phần mềm trên các EC2 instances.
  • Quản lý tài nguyên một cách hiệu quả và linh hoạt bằng cách sử dụng các script và template được định nghĩa trước.

Hãy cùng mình khám phá cách Ansible có thể trở thành một công cụ quan trọng trong hệ thống của chúng ta, giúp chúng ta đạt được mục tiêu tự động hóa và tối ưu hóa quản lý cơ sở hạ tầng trên AWS EC2!

Chúng ta đưa ra giả định rằng chúng ta có 3 servers : Staging, Production, Jenkin, về cơ bản trên những server này đều thiết lập giống nhau, và lập lại rất nhiều việc cài cắm, thay vì chúng ta phải vào từng server để thiết lập thì chúng ta có thể sử dụng 1 server Ansible để chúng ta có thể quản lý cơ sở hạ tầng nếu bạn cty nào muốn tiếp cận chi phí có thể gộp chung Ansible vào server Jenkins chẳng hạn để dùng chung luôn, trong tương lại khi dự án nhiều hơn thì chúng ta không cần phải mất quá nhiều thời gian cho việc set up nữa, hãy cùng mình đi vào một ví dụ build một application để có một cái nhìn cụ thể cách mà Ansible hoạt động nhé!

Cấu Hình Ansible Cho Server Jenkin

Các bạn cần phải vào lại server Ansible và sau đó cài đặt ansible, mình đang sử dụng ubuntu 20.04

# Cài đặt trên Ubuntu
apt-add-repository -y ppa:ansible/ansible
apt-get update
apt-get install -y ansible
-------------------------------------------
python3 --version
sudo apt install python3-pip
pip3 install boto3

Hoặc các bạn có thể xem trên trang Doc của Ansible để xem chi tiết và cài đặt. Bước tiếp theo chúng ta sẽ Config Ansible.

cd /etc/ansible/
vim ansible.cfg

Thêm cấu hình dưới đây để sử dụng plugins ec2 thay vì mặc định sử dụng host:

[defaults]

inventory = ./ansible_plugins
enable_plugins = aws_ec2
host_key_checking = False

Chúng ta cần phải tạo 1 IAM role với quyền admin hoặc 1 quyền phù hợp để gắn vào server Jenkin, để cho phép Ansible có thể lấy thông tin của các instances, thay vì sử dụng access key và secret key credential IAM user.

Sau đó, chúng ta sẽ tạo một thư mục mới và tạo tệp yml đại diện cho Ansible dynamic inventory (mã code tiếp theo cho phép chúng ta thu thập thông tin từ EC2 instance một cách linh hoạt). 

mkdir ansible_plugins
cd ansible_plugins
vim production_aws_ec2.yml

Dưới đây là cấu hình YAML dành cho dynamic inventory plugin của Ansible cho Amazon EC2. Dưới đây là các phần chính của tập tin cấu hình:

  1. Plugin và cài đặt thông số: Đầu tiên, nó xác định plugin sẽ được sử dụng là aws_ec2, cho phép Ansible tự động lấy thông tin về các EC2 instances từ AWS. Các thông số khác như aws_access_key và aws_secret_key có thể được cung cấp tại đây, nhưng chúng đã được comment lại trong tập tin này, vì Ansible có thể tự động tìm kiếm thông tin xác thực từ các nguồn khác nhau.

  2. Regions và filters: Cấu hình plugin để chỉ lấy thông tin về các EC2 instances đang chạy trong một hoặc nhiều khu vực (regions) cụ thể. Filters được sử dụng để chỉ lấy các instances có trạng thái running.

  3. Keyed groups: Đây là cách mà plugin tổ chức các EC2 instances thành các nhóm dựa trên các thuộc tính của chúng, như tags, kiến trúc, loại instance, vùng đặt, image ID, hypervisor, hoặc các nhóm bảo mật (security groups). Các nhóm này có thể được sử dụng sau này trong playbook của Ansible.

  4. Hostnames và compose: Xác định thứ tự ưu tiên cho các biến hostname, như địa chỉ IP, tên miền DNS, tên tag của EC2 instance (nếu có), hoặc địa chỉ IP riêng. Phần compose được sử dụng để xác định các biến cụ thể mà Ansible sử dụng để kết nối với các EC2 instances

Nó còn nhiều cấu hình lắm các bạn xem thêm ở đây Link.

# aws ec2 ansible dynamic inventory plugin
plugin: aws_ec2
#set aws_access_key and secret_key.
#aws_access_key: AWS_ACCESS_KEY
#aws_secret_key: AWS_SECRET_KEY
# set the regions. 
regions: 
  - ap-southeast-1
# - us-east-2
# set strict to False    
# if True this will make invalid entries 
# a fatal error
strict: False
filters:
  instance-state-name: running
keyed_groups:
  #  each aws ec2 instance has it own instance tags. create  
  #  a tag variable from those tags for ansible to use. 
  #  if the ec2 tag Name had the value cygnusx1 the tag 
  #  variable would be: 
  #  tag_Name_cygnusx1
  #  if a tag existed for an aws instance as  
  #  Applications with the value of Oracle the  
  #  variable would be:
  #  tag_Applications_Oracle
  - key: tags
    prefix: tag
  #
  # the following keyed groups are from the aws url:
  # https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html#options   
  # below are some of the variable that can be used.  
  # an example for instance_type: 
  # aws_instance_type_t2_micro
  - key: architecture
    prefix: arch
  - key: tags.Applications
    separator: ''
  - key: instance_type
    prefix: aws_instance_type
  - key: placement.region
    prefix: aws_region
  - key: image_id
    prefix: aws_image
  - key: hypervisor
    prefix: aws_hypervisor
  - key: 'security_groups|json_query("[].group_id")'
    prefix: 'security_groups'
hostnames:
# a list in order of precedence for hostname variables.
# 
  - ip-address
  - dns-name
  - tag:Name
  - private-ip-address
compose:
# use if you need to connect via the ec2
# private ip address. 
#
# this is needed for example in a 
# corporate / company environment where ec2 
# instances don't use a public ip address
#
#  ansible_host: private_ip_address

Sau đó thì chạy lệnh sau để test xem Ansible đã lấy được các thông tin Instance hay chưa:

ansible-inventory -i /etc/ansible/ansible_plugins/aws_ec2.yml --list

Nếu các bạn thấy thông tin instance đã được hiển thị theo điều kiện lọc trong file production_aws_ec2.yml thì các bạn đã kết nối thành công.

Để Jenkin có thể kết nối (SSH) vào server Staging hay Production chúng ta cần phải tạo ra một file key.pem để lưu private key của các Insances này.

cd /etc/ansible
mkdir pem
nano pem/key.pem
#chown jenkins:root pem/key.pem

Sau đó chúng ta sang server production hoặc staging để lấy private key và lưu vào file key.pem này (có thể lấy file .pem lúc ban đầu khi chúng ta tạo instance) hoặc tạo ra 1 user có đủ permisson để có thể cài đặt những packages sau đó hãy copy private key của user đó vào đây.

-----BEGIN RSA PRIVATE KEY-----
MIIE…
-----END RSA PRIVATE KEY-----

Sau đó thì chạy test xem nó đã SSH vào được server chưa bằng lệnh sau:

ansible aws_ec2 -i /etc/ansible/ansible_plugins/aws_ec2.yml -m ping --private-key=/etc/ansible/pem/key.pem -u ubuntu

Các bạn nhìn thấy kết quả như này là Ok

Hoặc chúng ta có thể test là đứng từ server Ansible thử install git cho server Production như sau:

ansible aws_ec2 -i /etc/ansible/ansible_plugins/aws_ec2.yml -m apt -a 'name=git state=present' --private-key=/etc/ansible/pem/key.pem -u ubuntu --become

Sang server staging hoặc production ta sẽ thấy GIT đã được install.Ok vậy là đã thiết lập xong Ansible

Cấu Hình Ansible Playbooks

Bước 1 : Tạo playbook-staging-run.yml

cd /etc/ansible/
mkdir playbook
nano /etc/ansible/playbook/playbook-staging-run.yml

Kiểm tra xem nó chạy một container mới có tên là dinhhongson/laravel-app với cổng 80 - chỉ trên có trên instance có tag type: “staging”) các bạn nhớ đặt theo quy tắc name mà chúng ta đã quy định trong aws_ec2.yml

- hosts: tag_Name_staging
  become: yes
  remote_user: ubuntu
  name: Upgrade all packages and set up project
  tasks:
    - name: Update all packages
      apt:
        update_cache: yes
        upgrade: dist

    - name: Install Docker dependencies
      apt:
        name:
          - apt-transport-https
          - ca-certificates
          - curl
          - gnupg-agent
          - software-properties-common
        state: present

    - name: Add Docker GPG key
      apt_key:
        url: https://download.docker.com/linux/ubuntu/gpg
        state: present

    - name: Add Docker repository
      apt_repository:
        repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable
        state: present

    - name: Update apt cache
      apt:
        update_cache: yes

    - name: Install Docker
      apt:
        name: docker-ce
        state: present

    - name: Start Docker service
      systemd:
        name: docker
        state: started
        enabled: yes

    - name: Add admin user
      user:
        name: ubuntu
        groups: docker
        append: yes

    - name: Install Python pip
      apt:
        name: python3-pip
        state: present

    - name: Install docker-py
      pip:
        name: docker-py

    - name: Run laravel container
      docker_container:
        name: laravel-app
        image: dinhhongson/laravel-app:v1
        state: started
        exposed_ports: "80"
        published_ports: "80:80"

Bước tiếp theo tạo : playbook-staging-acceptance.yml

Playbook này cho phép thực hiện kiểm tra acceptance trên container đang chạy trong môi trường staging.

nano /etc/ansible/playbook/playbook-staging-acceptance.yml

Sau đó thì put đoạn code test sau vào:

- hosts: tag_type_staging
  become: yes
  remote_user: ubuntu
  tasks: 
    - name: Run acceptance tests
      command: docker exec -it laravel-app bash -c './vendor/bin/codecept run';
      register: atesting
    - debug: msg="{{ atesting.stdout }}"

Bước 3: playbook-staging-stop.yml

Playbook này cho phép dừng container và xóa image docker.

nano /etc/ansible/playbook/playbook-staging-stop.yml

Sau đó put đoạn config sau:

- hosts: tag_type_staging
  become: yes
  remote_user: ubuntu
  tasks: 
    - name: Delete laravel containers
      docker_container:
        name: laravel-app
        force_kill: true
        keep_volumes: false
        state: absent
     - name: Remove image
      docker_image:
        state: absent
        name: dinhhongson/laravel-app

Bước 4: Cấu hình playbook-production-run.yml cho production

Playbook này cho phép cài đặt phần mềm cần thiết bên trong môi trường production, chạy version mới của dự án laravel (chạy một container mới).

nano /etc/ansible/playbook/playbook-production-run.yml

kiểm tra xem nó chạy container dinhhongson/laravel-app mới trong cổng 80 - chỉ trên instance có tag type: “ production”):

- hosts: tag_type_production
  become: yes
  remote_user: ubuntu
  name: Upgrade all packages
  tasks: 
    - name: Update all
      apt: name=* state=latest
    - name: install docker
      apt: name=docker state=latest
    - name: Start docker service
      systemd:
        state: started
        name: docker
    - name: Add admin user
      user:
        name: admin
        groups: docker
        append: yes
    - name: install python-pip
      apt: name=python-pip state=present
    - name: install docker-py
      pip: name=docker-py
    - name: Delete laravel containers
      docker_container:
        name: laravel-app
        force_kill: true
        keep_volumes: false
        state: absent
    - name: Remove image
      docker_image:
        state: absent
        name: dinhhongson/laravel-app
    - name: Run laravel container
      docker_container: 
        name: laravel-app 
        image: dinhhongson/laravel-app
        state: started 
        exposed_ports: "80"
        published_ports: "80:80"

Bước 5: Cấu hình playbook-production-acceptance.yml

Playbook này cho phép thực hiện các thử nghiệm trên container đang chạy trong môi trường production.

- hosts: tag_Name_production
  become: yes
  remote_user: ubuntu
  tasks: 
    - name: Run smoke tests
      command: docker exec -it laravel8cdpart2 bash -c 'vendor/bin/codecept run';
      register: stesting
    - debug: msg="{{ stesting.stdout }}"

Ok vậy là là mình đã hoàn thành việc thiết lập cũng như cấu hình có server staging và production các bạn chỉ cần chạy lệnh sau cho từng playbook của bạn. 

ssh-agent sh -c 'ssh-add /etc/ansible/pem/key.pem && ansible-playbook /etc/ansible/playbook/test-playbook-staging.yml'

Bình luận (0)

Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough

Bài viết liên quan

Learning English Everyday