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:
- 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
- TIếp theo là cho chạy AWS Configure để server có thể kết nối với resources trên AWS
- 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ề
- Chuẩn bị các playbook như bên dưới
- 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: hogefuga@blogchiase.tokyo # 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.

◎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)

◎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).

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

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