Cách run Ansible-Playbook bằng AWS Systems Manager (những bạn hay dùng Ansible không nên bỏ qua sự tiện lợi này!)

ansible_aws-systems-manager

Hiện tại AWS đã support việc chạy ansible playbook thông qua aws systems manager. ( https://aws.amazon.com/vi/about-aws/whats-new/2019/09/now-use-aws-systems-manager-to-execute-complex-ansible-playbooks/?nc1=f_ls )

Các bạn có thể tham khảo các ví dụ về Best Practices của Ansible Playbook ở đây để viết playbook cho riêng mình và chạy các playbook đấy trên EC2. Sau đây mình sẽ hướng dẫn chi tiết về cách run Ansible Playbook trên EC2 mà mình đã làm.

Lúc trước mình có viết một playbook về dựng FTPS server (vsftpd) nên hôm nay mình sẽ dùng playbook đấy để tạo một FTPS server trên EC2 thông qua AWS Systems Manager.

Đầu tiên mình sẽ chuẩn bị một chút trước khi vào nội dung chính

Các bạn cần làm trước một số việc sau:

  1. Cài sẵn ansible vào server bất kỳ (server mà bạn dùng để chạy câu lệnh ansible để build EC2) bằng pip
  2. TIếp theo là cho chạy AWS Configure để server có thể kết nối với resources trên AWS
  3. Cài thêm weareinteractive/vsftpd bằng Ansible Galaxy ($ ansible-galaxy install weareinteractive.vsftpd) → trong thư mục roles (biến môi trường: roles_path) thì các bạn sẽ thấy weareinteractive.vsftpd hay weareinteractive.openssl được load sẵn về
  4. Chuẩn bị các playbook như bên dưới
  5. Chạy trước playbook1 để tạo ec2 instance (dành cho việc build FTPS server) thông qua câu lệnh “$ ansible-playbook aws-ftps.yml” ※chú ý là việc tạo ec2 mình phải chạy thủ công không dùng Systems Manager (lí do là chỉ dùng được Systems Manager khi đã có ec2 instance)!!!
#
# Playbook1 for creating an ec2 instance
#
# ansible-playbook aws-ftps.yml
- hosts: localhost
  connection: local
  gather_facts: False
  become: False
  vars:
    region: ap-northeast-1
    ipaddress: XXX.XXX.XXX.XXX/32 # ⇒⇒⇒ replace by your ip to access to ec2
    key_name: ec2-ftps
  tasks:
    - ec2_key:
        region: "{{ region  }}"
        name: "{{ key_name  }}" # ⇒⇒⇒ replace by your secret-key
      register: _key
    - copy:
        content: "{{ _key.key.private_key }}"
        dest: "~/.ssh/{{ _key.key.name }}.pem"
        mode: 0600
      when: _key.changed
    - ec2_vpc_net:
        region: "{{ region }}"
        name: vpc-ftps
        cidr_block: 10.0.0.0/16
      register: _vpc
    - ec2_vpc_igw:
        region: "{{ region }}"
        vpc_id: "{{ _vpc.vpc.id }}"
      register: _igw
    - ec2_vpc_subnet:
        region: "{{ region }}"
        vpc_id: "{{ _vpc.vpc.id }}"
        cidr: 10.0.0.0/24
      register: _subnet
    - ec2_vpc_route_table:
        region: "{{ region }}"
        vpc_id: "{{ _vpc.vpc.id }}"
        tags:
          Name: Public
        subnets:
          - "{{ _subnet.subnet.id }}"
        routes:
          - dest: 0.0.0.0/0
            gateway_id: "{{ _igw.gateway_id  }}"
      register: _public_route_table
    # Security Group
    - ec2_group: 
        region: "{{ region }}"
        vpc_id: "{{ _vpc.vpc.id }}"
        name: sg_ssh
        description: sg-ssh
        rules:
          - proto: tcp
            from_port: 22
            to_port: 22
            cidr_ip: "{{ ipaddress }}"
      register: _group_ssh
    - ec2_group: 
        region: "{{ region }}"
        vpc_id: "{{ _vpc.vpc.id }}"
        name: sg_ftps
        description: sg-ftps
        rules:
          - proto: tcp
            from_port: 21
            to_port: 21
            cidr_ip: "{{ ipaddress }}"
          - proto: tcp
            from_port: 50000
            to_port: 50010
            cidr_ip: "{{ ipaddress }}"
      register: _group_ftps
    - ec2_instance:
        name: "ftps"
        key_name: "{{ key_name }}"
        vpc_subnet_id: "{{ _subnet.subnet.id }}"
        instance_type: t3.micro
        image_id: ami-0c3fd0f5d33134a76
        security_groups:
          - "{{ _group_ssh.group_id}}"
          - "{{ _group_ftps.group_id}}"
        network:
          assign_public_ip: true
      register: _instance
    - ec2_eip:
        region: "{{ region }}"
        device_id: "{{ item }}"
      loop: "{{ _instance.instance_ids }}"
      register: _eip
    - debug:
        msg: "Allocated IP is {{ _eip.results[0].public_ip }}"
        

※Chú ý là Playbook1 tạo ec2 instance ở trên mình có định nghĩa 2 parameter trong vars là “ipaddress” và “key_name” các bạn có thể thay đổi 2 parameter này cho phù hợp với môi trường của bạn!!!

Còn Playbook2 để dựng FTPS server ở dưới này thì có nội dung chính như sau:
   ● openssl_self_signed: nội dung của self-signed certificate
   ● vsftpd_users: user/password dùng để connect tới FTPS server
   ● vsftpd_config: nội dung của vsftpd.conf thì mình giữ nguyên. Protocol thì các bạn có thể thay đổi tùy thích
   ● pasv_address: cái này là EIP mà bạn đã tạo

#
# Playbook2 for building a FTPS server (vsftpd) on ec2 instance
#
# ansible-playbook vsftpd-ftps.yml
- hosts: all
  vars:
    # Create self-signed certificate
    openssl_keys_path: /etc/pki/tls/private
    openssl_certs_path: /etc/pki/tls/private
    openssl_csrs_path: /etc/pki/tls/private
    openssl_default_key_owner: root
    openssl_default_key_group: root
    openssl_default_cert_owner: root
    openssl_default_cert_group: root
    openssl_generate_csr: yes
    openssl_self_signed:
      - name: ftp.blogchiase.info
        subject:
           C: JP
           ST: Tokyo
           L: Chiyoda-ku
           O: Blogchiase,Inc.
           CN: ftp.blogchiase.info
           emailAddress: [email protected]
    # Add a FTP User
    vsftpd_users:
       - username: ftpuser
         name: FTP User
         password: "{{ 'ftpuser' | password_hash('sha256', 'mysecretsalt') }}" # Change Password  
    # vsFTPD settings
    vsftpd_config:
      anonymous_enable: NO
      local_enable: YES
      write_enable: YES
      allow_writeable_chroot: YES
      dirmessage_enable: NO
      ascii_upload_enable: YES
      ascii_download_enable: YES
      chroot_local_user: YES
      tcp_wrappers: NO
      connect_from_port_20: NO
      xferlog_std_format: NO
      pasv_enable: YES
      pasv_addr_resolve: YES
      pasv_address: AAA.AAA.AAA.AAA # Change to assigned ElasticIp address
      pasv_min_port: 50000
      pasv_max_port: 50010
      use_localtime: YES
      force_dot_files: YES
      # userlist_deny: NO
      listen: YES
      listen_ipv6: NO
      # FTP(s) settings
      ssl_enable: YES
      ssl_sslv2: NO
      ssl_sslv3: NO
      ssl_tlsv1: YES
      ssl_tlsv1_1: YES
      ssl_tlsv1_2: YES
      force_local_data_ssl: YES
      force_local_logins_ssl: YES
      # log_ftp_protocol: YES
    # ssl key
    vsftpd_key_file: "ftp.blogchiase.info.key"
    # ssl cert
    vsftpd_cert_file: "ftp.blogchiase.info.crt"
  roles:
    - weareinteractive.openssl
    - weareinteractive.vsftpd
    

Bước 1: mình sẽ tạo file zip của playbook2

Khi tạo file zip của playbook2 thì các bạn nhớ zip luôn các thư mục trong ./roles folder. Thì ở đây mình tạo file zip là “ansible-vsftpd.zip”. Cấu trúc thư mục trong file zip đã tạo là như sau:

.
├── roles
│   ├── weareinteractive.openssl
│   │   ├── CHANGELOG.md
│   │   ├── defaults
│   │   │   └── main.yml
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── meta
│   │   │   ├── main.yml
│   │   │   └── readme.yml
│   │   ├── README.md
│   │   ├── tasks
│   │   │   ├── cacert.yml
│   │   │   ├── config.yml
│   │   │   ├── create_dir.yml
│   │   │   ├── install.yml
│   │   │   ├── main.yml
│   │   │   ├── manage.yml
│   │   │   └── vars.yml
│   │   ├── templates
│   │   │   └── etc
│   │   │       └── ssl
│   │   │           └── openssl.cnf.j2
│   │   ├── tests
│   │   │   └── main.yml
│   │   └── vars
│   │       ├── default.yml
│   │       ├── redhat.yml
│   │       ├── suse.yml
│   │       └── ubuntu.yml
│   └── weareinteractive.vsftpd
│       ├── CHANGELOG.md
│       ├── defaults
│       │   └── main.yml
│       ├── handlers
│       │   └── main.yml
│       ├── LICENSE
│       ├── Makefile
│       ├── meta
│       │   ├── main.yml
│       │   └── readme.yml
│       ├── README.md
│       ├── tasks
│       │   ├── config.yml
│       │   ├── install.yml
│       │   ├── main.yml
│       │   ├── manage.yml
│       │   └── service.yml
│       ├── templates
│       │   └── etc
│       │       └── vsftpd.conf.j2
│       ├── tests
│       │   └── main.yml
│       ├── Vagrantfile
│       └── vars
│           ├── Debian.yml
│           └── RedHat.yml
└── vsftpd-ftps.yml

Bước 2: đẩy file zip đã tạo lên S3

Tải tập tin zip đã tạo lên S3 vào bucket của bạn. (bạn nên để public hoặc thiết lập quyền truy cập của bucket cho phù hợp). Sau đấy lưu lại đường dẫn đến file zip đã up lên. Ở đây mình đã up file lên theo đường dẫn như sau: "https://pub-devio-blog-qroltosd.s3-ap-northeast-1.amazonaws.com/ansible/ansible-vsftpd.zip"

Bước 3: run command trên AWS Systems Manager

◎Chọn document

Chọn “AWS-ApplyAnsiblePlaybooks” từ mục “Run Command” của “AWS Systems Manager” như hình sau.

image-2

◎Chọn parameter

Chọn parameter như bên dưới:
   Source Type: chỉ định S3
   Source Info: chỉ định path bằng URL của zip file mà đã lưu trên S3
   Install Dependencies: chỉ định True để install ansible và các package cần thiết
   Playbook File: chỉ định playbook mình muốn chạy (trường hợp này là vsftpd-ftps.yml)

image-3

◎Chọn target

Chọn instance được chỉ định trong Roles của playbook (chú ý là instance này cũng đã được gắn role của Systems Manager, cho phép Systems Manager chạy lệnh trên instance đấy).

ssm-instances

◎Thực hiện

Bấm nút Run để thực hiện chạy lệnh Ansible trong playbook

image-4

Kết quả chạy lệnh

1) Install ansible

Khi thực hiện chạy lệnh thành công các bạn sẽ thấy những đoạn log như bên dưới trong lịch sử chạy lệnh.

Installed:
ansible.noarch 0:2.8.4-1.el7

2) Download playbook cần chạy từ S3

Complete!
Running Ansible in /var/lib/amazon/ssm/i-072e8030071378e13/document/orchestration/1fd1ace2-e2e1-4bdb-9615-7afffb677d70/downloads
Archive: ./ansible-vsftpd.zip
creating: roles/
creating: roles/weareinteractive.openssl/
extracting: roles/weareinteractive.openssl/.ansible-lint
inflating: roles/weareinteractive.openssl/.clog.toml

3) Run ansible-playbook mà đã download

IPLAY [all] *********************************************************************
 
TASK [Gathering Facts] *********************************************************
<<phần phía sau mình xin lược bớt>>

Thử connect đến FTPS server vừa tạo

Khi connect thì cần chú ý những điểm sau:
   1) Kiểm tra lại protocol mà client support
   2) Vì sử dụng self-signed certificate nên phía client không cần check certificate (nên disable)
   3) connect bằng passive mode

コメントを残す

メールアドレスが公開されることはありません。