Mỗi khi bắt đầu một project mới, chúng ta cần phải làm tất cả AWS infrastructure trên nhiều môi trường (Dev-Stag-Prod) với nhiều microservices (Django, Lumen, docker, Wordpress…) + CI/CD tự động hóa hoàn toàn. Vì vậy, tôi đã phát triển ra Vodo Stack để code có thể tái sử dụng với nhiều projects khác nhau. Thứ duy nhất tôi cần là AWS Acess Key và một lệnh make để tạo ra AWS infrastructure stack và CI/CD một cách đầy đủ.Vd:
[root@puppet vodo]# make create-vodo-stack aws_profile=natrol.vn project_name=bauda aws_region=ap-southeast-1
[root@puppet vodo]# make create-vodo-stack aws_profile=blahblah.vn project_name=tequila aws_region=ap-southeast-2
Chi tiết yêu cầu sau khi chạy lệnh make:
Để làm tất cả những điều trên phải mất tầm 1 đến 2 tháng trong nhiều môi trường khác nhau.. Đó cũng là lí do vì sao tôi đã thực hiện Vodo Stack để làm việc được nhanh hơn 😊
Có nhiều tools kết hợp cùng nhau để đáp ứng đầy đủ các yêu cầu (Ansible, Terraform, Puppet, Chef…) là cái mà sử dụng các tags map với các roles để triển khai chúng. (Vd: roles: jenkins, ansible, lumen,django, base). Với cá nhân tôi, thì Chef/Ansible +Terraform là công nghệ hiện đại được ưu tiên số 1 nhưng cậu con trai bé nhỏ của tôi lại thích chương trình puppet kids nên tôi đã sử dụng Puppet cùng với một chút sự trợ giúp của Ansible (một ngôi sao trẻ đấy J). Sau đây là một số lí do tại sao lại kết hợp Puppet + Ansible:
Sau đó, dựa trên các roles (lấy từ AWS Tag), agent sẽ được triển khai cùng với các puppet modules phù hợp. Nhưng puppetlabs.aws module thì không được hỗ trợ đầy đủ cho tất cả các AWS API. Vì thế, tôi đã phải sử dụng aws cli cho việc autoscaling và ELB. Và đây là một lỗi mà tôi đã tạo ra cho module auto-scale trong quá trình tạo ra playbook.
https://github.com/puppetlabs/puppetlabs-aws/issues/502
ansible-playbook invoke_puppet.yml -e env={puppet-environment} role=${any_role} deployment_env={dev-or-staging-or-prod}
` dựa trên nhánh trigger bởi bitbucket.Tôi tách ra làm 3 phần
Tôi đã lên kế hoạch tái sử dụng code cho những dynamic project, vì vậy chúng ta cần chuyển các tham số tới puppet modules. Tôi giả định rằng tất cả chúng ta đã biết sử dụng Puppet modules. Tôi tạo một Makefile:
[root@puppet vodo]# cat Makefile
create-vodo-stack:
export AWS_PROFILE=$(aws_profile); export FACTER_project_name=$(project_name); export FACTER_aws_region=$(aws_region); export FACTER_domain_name=$(domain_name); \
puppet apply — hiera_config=/etc/puppetlabs/puppet/hiera.yaml — modulepath=`pwd`/modules -e ‘include tepco’ — environment=vodo
[root@puppet vodo]# tree modules/tepco/
modules/tepco/
├── files
│ ├── ec2_block_device_mapping.json
│ ├── ec2_trusted_policy_iam_roles.json
│ └── tepco_deploy_log.log
├── manifests
│ ├── create_tepco_applications_loadbalancer.pp
│ ├── create_tepco_autoscaling_group.pp
│ ├── create_tepco_bastion.pp
│ ├── create_tepco_iam_roles.pp
│ ├── create_tepco_jenkins.pp
│ ├── create_tepco_jenkins_slaves.pp
│ ├── create_tepco_key_pair.pp
│ ├── create_tepco_nat_gateway.pp
│ ├── create_tepco_puppet_master.pp
│ ├── create_tepco_routetable.pp
│ ├── create_tepco_security_group.pp
│ ├── create_tepco_stack.pp
│ ├── create_tepco_wordpress.pp
│ ├── create_test_template.pp
│ ├── init.pp
│ └── tepco_stack_information.pp
└── templates
├── tepco-bastion-user-data-init-script.erb
├── tepco-node-user-data-init-script.erb
└── tepco-puppet-master-user-data-init-script.erb
3 directories, 22 files
Với Makefile phía trên, chúng ta có thể tái sử dụng code với nhiều project khác nhau với AWS Account khác nhau
[root@puppet vodo]# make create-vodo-stack aws_profile=natrol.vn project_name=electronic aws_region=ap-southeast-1 domain_name=natrol.vn
export AWS_PROFILE=natrol.vn; export FACTER_project_name=electronic; export FACTER_aws_region=ap-southeast-1; export FACTER_domain_name=natrol.vn; \
puppet apply --hiera_config=/etc/puppetlabs/puppet/hiera.yaml --modulepath=`pwd`/modules -e 'include tepco' --environment=vodo
Hãy kiểm tra việc triển khai phối hợp với file init.pp trên các modules tepco:
[root@puppet vodo]# cat modules/tepco/manifests/init.pp
class tepco {
# Variable definition:
$random_id=generate('/bin/date', '+%s')
$init_env=hiera('tepco.env','NA') # dev-staging-prod
$init_role=hiera('tepco.environment_name','NA') # puppet-master role
$init_domain=hiera('tepco.domain','NA') # Domain name
$init_project_name=hiera('tepco.name','NA') # Each domain have multiple project
$init_subnet_type=hiera('tepco.subnet_type','NA')
$init_region=hiera('tepco.region','NA')
$init_iam_role_name="Puppet-Master-Roles-IAM-S3-EC2"
$roles=hiera('vodo.tag_app','NA') # Get full roles jenkins,wordpress,puppet-master,jenkins-slaves,bastion
notify {"INIT Notify":
message => "env=${init_env} role=${init_role} domain=${init_domain} project=${init_project_name} subnet_type=${init_subnet_type} region=${init_region} iam_role=${init_iam_role_name}",
}
# Include roles:
include tepco::create_tepco_stack
include tepco::create_tepco_nat_gateway
include tepco::create_tepco_routetable
include tepco::create_tepco_security_group
include tepco::create_tepco_key_pair
include tepco::create_tepco_iam_roles
include tepco::create_tepco_puppet_master
#include tepco::create_tepco_wordpress
#include tepco::create_tepco_jenkins
#include tepco::create_tepco_jenkins_slaves
include tepco::create_test_template
include tepco::create_tepco_bastion
include tepco::create_tepco_applications_loadbalancer
include tepco::create_tepco_autoscaling_group
include wordpress::tepco_stack_information
}
Từ tất cả cả các include ở trên, chúng ta có thể thấy create_tepco_stack (VPC-Subnets-Internet-Gateway) sau đó là Nat Gateway, Routetable, Sercuritygroup rồi đến các IAM roles.
Mẫu create_tepco_stack (VPC, 4 subnet, internet gateway cùng với VPC)
class tepco::create_tepco_stack inherits tepco{
# Run on all environment get variable init_env from init.pp
$init_env.each |Integer $index, String $env_value| {
$init_bucket="${env_value}.${init_role}.${init_domain}"
$init_vpc="vpc-${env_value}-${init_project_name}"
$init_subnet="subnet-${env_value}-${init_project_name}"
exec {"create s3://${init_bucket}":
path => ['/bin/','/usr/bin',],
unless => "aws s3 ls | grep ${init_bucket}",
command => "aws s3 mb s3://${init_bucket}",
}
exec {"copy puppet installation file to s3://${init_bucket}/Puppet_Novatti_Installation":
path => ['/bin','/usr/bin','/sbin',],
cwd => '/etc/puppetlabs/code/environments/vodo',
command => "aws s3 sync Puppet_Novatti_Installation/ s3://${init_bucket}/Puppet_Novatti_Installation/",
#unless => "aws s3 ls s3://${init_bucket}/Puppet_Novatti_Installation/ | grep puppet",
require => Exec["create s3://${init_bucket}"],
}
ec2_vpc {"${init_vpc}":
ensure => present,
region => "${init_region}",
cidr_block => hiera("tepco.vpc.${env_value}",'NA'),
tags => {
env => "${env_value}" ,
},
}
$init_subnet_type.each |Integer $index1, String $type_value| {
ec2_vpc_subnet { "${env_value}-subnet-${type_value}-${init_project_name}":
ensure => present,
region => hiera('tepco.region','NA'),
cidr_block => hiera("tepco.subnet_range.${env_value}.${type_value}",'NA'),
availability_zone => hiera("tepco.az.${type_value}"),
vpc => "${init_vpc}",
tags => {
env => "${env_value}",
},
require => Ec2_vpc["${init_vpc}"],
}
}
ec2_vpc_internet_gateway {"create-${env_value}-igw-${init_project_name}":
name => "${env_value}-igw-${init_project_name}",
region => "${init_region}",
vpc => "vpc-${env_value}-${init_project_name}",
require => Ec2_vpc["${init_vpc}"],
}
}
}
Bây giờ, mỗi môi trường đã có 1 puppet, làm sao để EC2 có thể kết nối vào puppet động đó thậm chí cả khi puppet IP đã đổi ở mỗi môi trường. Chúng ta cần một user-data script trong khi tạo ra EC2 để cài đặt các gói cơ bản và một bootstrap script để kết nối EC2 vào puppet. Puppet có một external facter key=value thông qua script, chúng ta có thể sử dụng để lấy tag từ Puppet và gán vào Puppet Facter:
https://www.puppetcookbook.com/posts/what-are-external-facts.html
[root@puppet centos]# cat /opt/puppetlabs/facter/facts.d/node_facter.sh
#!/usr/bin/perl
#Build Up Facts for Factor
$instance_id = `curl -s http://169.254.169.254/latest/meta-data/instance-id`;
chomp $instance_id;
print "ec2_tag_instance_id=$instance_id\n";
$region_id = `curl -s http://169.254.169.254/latest/dynamic/instance-identity/document|grep region|awk -F '\"' '{print \$4}'`;
chomp $region_id;
print "ec2_tag_region_id=$region_id\n";
$region_id_full = `curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`;
chomp $region_id_full;
print "ec2_tag_region_id_full=$region_id_full\n";
$server_role = `aws ec2 describe-tags --filters "Name=resource-id,Values=$instance_id" "Name=key,Values=role" --profile=dev --region=$region_id --output=text | cut -f5`;
chomp $server_role;
print "ec2_tag_server_role=$server_role\n";
$init = `aws ec2 describe-tags --filters "Name=resource-id,Values=$instance_id" "Name=key,Values=init" --region=$region_id --output=text | cut -f5`;
chomp $init;
print "ec2_tag_init=$init\n";
...
Trong site.pp of puppet, chúng ta thiết lập playbook dựa trên ec2_tag_role_server giống như bên dưới
node default {
# This is where you can declare classes for all nodes.
# Example:
# class { 'my_class': }
}
case $::ec2_tag_server_role {
"puppet-master" : {
#include vodo_stack::install
#include vodo_stack::test
#include wordpress::docker_deploy
include wordpress::tepco_stack_information
}
"wordpress": {
include wordpress
include jenkins::minion
}
"jenkins": {
include jenkins::install
include jenkins::minion
}
"bastion": {
include base
}
"jenkins-slaves": {
include base
include jenkins::minion
}
}
Vậy nên, căn bản là để kết nối EC2 với một role cụ thể với puppet, chúng ta sẽ làm theo luồng hướng dẫn dưới đây:
+ Tạo EC2 động với các tags ở launch configuration
tags => {
domain => hiera('tepco.domain'),
role => "${role_lc}",
env => 'vodo',
init => 'yes',
deployment_env => "${env_value}",
project_name => "${init_project_name}",
},
Sau đó, trong user-data script, chúng ta sẽ tìm thấy puppet master thích hợp cho môi trường đó.
puppet_master_ip=$(/usr/bin/aws --region=<%= @init_region %> ec2 describe-instances --filter "Name=instance-state-code,Values=16" "Name=tag:init,Values=yes" "Name=tag:role,Values=<%= @init_role %>" "Name=tag:deployment_env,Values=<%= @env_value ? @env_value : 'dev' %>" "Name=tag:env,Values=vodo" --query "Reservations[0].Instances[0].PrivateIpAddress" --output text)
Và thêm to /etc/hosts:
echo "${puppet_master_ip} puppet.<%= @init_domain %> puppet" > /etc/hosts
Sau đó, chúng ta tạo ra một daemon để khởi động init_puppet:
$cmd = "/opt/puppetlabs/bin/puppet apply /etc/puppetlabs/code/host_config.pp >> /tmp/huy_puppet.log 2>&1 ";
system($cmd);
$cmd = "/opt/puppetlabs/bin/puppet agent --server $puppet_server --waitforcert 60 --test >> /tmp/join_puppet.log 2>&1 ";
system($cmd);
Chúng ta đặt 1 jenkin-slaves (Ansible) vào ssh song song với Application Server và chạy dòng lệnh puppet agent -t sau khi nhận được web-hook từ jenkins. Lệnh nhập vào Jenkins build: `ansible-playbook invoke_puppet.yml -e env={puppet-environment} -e role=${any_role} -e deployment_env={dev-or-staging-or-prod}
Ansible playbook invoke_puppet.yml:
---
- name: Run command puppet on instance
hosts: "tag_role_{{role}}:&tag_env_{{env}}:&tag_deployment_env_{{deployment_env}}"
gather_facts: no
become: yes
tasks:
- name: Run command puppet on instance {{role}}-{{env}}-{{deployment_env}}
shell: >
/opt/puppetlabs/bin/puppet agent -t
register: puppet_agent_cmd
failed_when: puppet_agent_cmd.rc == 1 or puppet_agent_cmd.rc > 2
Bởi vì puppet luôn trả về exit-code = 2 nếu có gì thay đổi, nhưng với Ansible exit-code = 2 có nghĩa là code failed. Jenkins sẽ báo build fail vì vấn đề này. Vì vậy, ở file invoke_puppet.yml chúng ta cần ngăn Ansible trả về exit code và thay bằng exit_code=0
Log test chạy Ansible playbook invoke_puppet.yml
[root@dev-vodo-jenkins-1522226856 ansible]# ansible-playbook invoke_puppet.yml -e role=wordpress -e env=vodo -e deployment_env=dev
PLAY [Run command puppet on instance]
**************************************************************
**************************************************************
***************************
TASK [Run command puppet on instance wordpress-vodo-dev]
**************************************************************
**************************************************************
********
changed: [172.21.201.243]
changed: [172.21.201.90]
changed: [172.21.200.239]
PLAY RECAP
****************************************************************
****************************************************************
******************************************************
172.21.200.239 : ok=1 changed=1 unreachable=0 failed=0
172.21.201.243 : ok=1 changed=1 unreachable=0 failed=0
172.21.201.90 : ok=1 changed=1 unreachable=0 failed=0
Cuối cùng, Log cho Jenkins webhook và trigger Slave-Jenkins:
=============================
Started by upstream project "xedap/dev-xedap-master-trigger" build number 6
originally caused by:
Started by BitBucket push by local-huy
Started by BitBucket push by local-huy
Building remotely on dev-slaves-jenkins-ansible (slaves dev xedap ansible) in workspace /home/centos/jenkins/workspace/xedap/dev-xedap-master-pipeline
> git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
> git config remote.origin.url git@bitbucket.org:vododevops/xedap.git # timeout=10
Fetching upstream changes from git@bitbucket.org:vododevops/xedap.git
> git --version # timeout=10
using GIT_SSH to set credentials dev-xedap-read-only-key-bitbucket
> git fetch --tags --progress git@bitbucket.org:vododevops/xedap.git +refs/heads/*:refs/remotes/origin/*
> git rev-parse refs/remotes/origin/master^{commit} # timeout=10
> git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision 7042eb287be05bb97e3c48ddca1c2b8870be771d (refs/remotes/origin/master)
> git config core.sparsecheckout # timeout=10
> git checkout -f 7042eb287be05bb97e3c48ddca1c2b8870be771d
Commit message: "Merged in staging (pull request #13)"
> git rev-list --no-walk d0426ee799caf9ff91dfea699eb883c5bd9357d3 # timeout=10
[dev-xedap-master-pipeline] $ /bin/sh -xe /tmp/jenkins7293139606918007223.sh
+ echo 7042eb287be05bb97e3c48ddca1c2b8870be771d
7042eb287be05bb97e3c48ddca1c2b8870be771d
+ echo origin/master
origin/master
+ cd /opt/ansible
+ ansible-playbook invoke_puppet.yml -e role=jenkins -e env=vodo -e deployment_env=dev
PLAY [Run command puppet on instance]
****************************************
TASK [Run command puppet on instance jenkins-vodo-dev]
*************************
changed: [172.21.200.178]
PLAY RECAP
*********************************************************************
172.21.200.178 : ok=1 changed=1 unreachable=0 failed=0
+ cd /opt/ansible
+ ansible-playbook invoke_puppet.yml -e role=wordpress -e env=vodo -e deployment_env=dev
PLAY [Run command puppet on instance]
****************************************
TASK [Run command puppet on instance wordpress-vodo-dev]
***********************
changed: [172.21.200.6]
PLAY RECAP
*********************************************************************
172.21.200.6 : ok=1 changed=1 unreachable=0 failed=0
Finished: SUCCESS
Bây giờ chúng ta đã hoàn toàn là một DevOps lười biếng rồi đấy, mỗi lần bắt đầu một project mới thì sẽ không cần tốn quá nhiều thời gian để thiết kế hay build AWS infrastructure nữa (Public,private subnet, internet gateway, nat gateway, routeable, Elastic Loadbalancer, AutoScale, CI/CD …) ngoại trừ một số thứ đặc trưng hơn chúng ta sẽ thêm vào playbook mới. Chúng ta sẽ tiết kiệm được thời gian làm những công việc khác như cải thiện năng suất, bảo mật, phân tích kinh doanh… Stack phổ biến thường được xây dựng với 1 lệnh make và khoảng 5~7p chạy:
[root@puppet vodo]# make create-vodo-stack aws_profile=natrol.vn project_name=electronic aws_region=ap-southeast-1 domain_name=natrol.vn
export AWS_PROFILE=natrol.vn; export FACTER_project_name=electronic; export FACTER_aws_region=ap-southeast-1; export FACTER_domain_name=natrol.vn; \
puppet apply --hiera_config=/etc/puppetlabs/puppet/hiera.yaml --modulepath=`pwd`/modules -e 'include tepco' --environment=vodo
Warning: The function 'hiera' is deprecated in favor of using 'lookup'. See https://docs.puppet.com/puppet/4.10/reference/deprecated_language.html
(file & line not available)
Warning: /etc/puppetlabs/puppet/hiera.yaml: Use of 'hiera.yaml' version 3 is deprecated. It should be converted to version 5
(in /etc/puppetlabs/puppet/hiera.yaml)
Notice: Compiled catalog for puppet.novattitma.com in environment vodo in 0.74 seconds
Notice: env=[dev] role=puppet-master domain=natrol.vn project=electronic subnet_type=[public-1a, public-1b, private-1a, private-1b] region=ap-southeast-1 iam_role=Puppet-Master-Roles-IAM-S3-EC2
Notice: /Stage[main]/Tepco/Notify[INIT Notify]/message: defined 'message' as 'env=[dev] role=puppet-master domain=natrol.vn project=electronic subnet_type=[public-1a, public-1b, private-1a, private-1b] region=ap-southeast-1 iam_role=Puppet-Master-Roles-IAM-S3-EC2'
Notice: /Stage[main]/Tepco::Create_tepco_stack/Exec[copy puppet installation file to s3://dev.puppet-master.natrol.vn/Puppet_Novatti_Installation]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_stack/Ec2_vpc[vpc-dev-electronic]/ensure: created
Notice: /Stage[main]/Tepco::Create_tepco_stack/Ec2_vpc_subnet[dev-subnet-public-1a-electronic]/ensure: created
Notice: /Stage[main]/Tepco::Create_tepco_stack/Ec2_vpc_subnet[dev-subnet-public-1b-electronic]/ensure: created
Notice: /Stage[main]/Tepco::Create_tepco_stack/Ec2_vpc_subnet[dev-subnet-private-1a-electronic]/ensure: created
Notice: /Stage[main]/Tepco::Create_tepco_stack/Ec2_vpc_subnet[dev-subnet-private-1b-electronic]/ensure: created
Notice: /Stage[main]/Tepco::Create_tepco_stack/Ec2_vpc_internet_gateway[create-dev-igw-electronic]/ensure: created
Notice: /Stage[main]/Tepco::Create_tepco_nat_gateway/Exec[create-nat-gateway-dev-electronic-and-elastic-ip]/returns: executed successfully
Notice: Please wait in 60 seconds
Notice: /Stage[main]/Tepco::Create_tepco_nat_gateway/Notify[Wait for nat-gateway-dev UP]/message: defined 'message' as 'Please wait in 60 seconds'
Notice: /Stage[main]/Tepco::Create_tepco_nat_gateway/Exec[create-tag-nat-gateway-dev]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_routetable/Ec2_vpc_routetable[create-dev-routetable-electronic-private]/ensure: created
Notice: /Stage[main]/Tepco::Create_tepco_routetable/Ec2_vpc_routetable[create-dev-routetable-electronic-public]/ensure: created
Notice: /Stage[main]/Tepco::Create_tepco_routetable/Exec[associate-subnet-public-dev]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_routetable/Exec[associate-subnet-private-dev]/returns: executed successfully
Notice: Please wait in 60 seconds
Notice: /Stage[main]/Tepco::Create_tepco_routetable/Notify[Wait for route-table-is-configured]/message: defined 'message' as 'Please wait in 60 seconds'
Notice: /Stage[main]/Tepco::Create_tepco_routetable/Exec[create private route table nat gateway dev]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_security_group/Ec2_securitygroup[sg_dev_electronic_allow_all]/ensure: created
Notice: /Stage[main]/Tepco::Create_tepco_key_pair/Exec[copy-dev-electronic_id_rsa-to-S3]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_puppet_master/Ec2_instance[dev-puppet-master-electronic]/ensure: changed absent to running
Notice: Waiting in 30 seconds
Notice: /Stage[main]/Tepco::Create_tepco_puppet_master/Notify[Wait-dev-puppet-master-electronic-up]/message: defined 'message' as 'Waiting in 30 seconds'
Notice: /Stage[main]/Tepco::Create_tepco_puppet_master/Exec[Wait-dev-puppet-master-electronic-Running]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_test_template/File[test template wordpress dev]/content: content changed '{md5}eb7a9da73bf9f5aecb3ad65e88b345b0' to '{md5}5c6d137c14c9bbc41f4c4f73ea93b731'
Notice: /Stage[main]/Tepco::Create_tepco_bastion/Ec2_instance[dev-bastion-electronic]/ensure: changed absent to running
Notice: /Stage[main]/Tepco::Create_tepco_applications_loadbalancer/Exec[create-dev-elb-wordpress]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_applications_loadbalancer/Exec[create-dev-target-group-elb-wordpress]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_applications_loadbalancer/Exec[register-listen-to-target-group-dev-elb-wordpress]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_applications_loadbalancer/Exec[set-security-group-to-dev-elb-wordpress]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_applications_loadbalancer/Exec[create-dev-elb-jenkins]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_applications_loadbalancer/Exec[create-dev-target-group-elb-jenkins]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_applications_loadbalancer/Exec[register-listen-to-target-group-dev-elb-jenkins]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_applications_loadbalancer/Exec[set-security-group-to-dev-elb-jenkins]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_autoscaling_group/Exec[dev-lc-electronic-wordpress]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_autoscaling_group/Exec[dev-asg-electronic-wordpress]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_autoscaling_group/Ec2_scalingpolicy[dev-asg-policy-electronic-wordpress]/ensure: created
Notice: /Stage[main]/Tepco::Create_tepco_autoscaling_group/Exec[dev-lc-electronic-jenkins]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_autoscaling_group/Exec[dev-asg-electronic-jenkins]/returns: executed successfully
Notice: /Stage[main]/Tepco::Create_tepco_autoscaling_group/Ec2_scalingpolicy[dev-asg-policy-electronic-jenkins]/ensure: created
Notice: Applied catalog in 318.59 seconds
Thêm một module mới TersForm để giảm sử dụng aws cli trong việc tạo ra AWS Infrastructure
Puppet: kiểm soát các nguồn tài nguyên, CM, deploy dựa trên role:
+ Ansible: trigger parallel ssh EC2
+ Terraform: triển khai AWS Infrastructure (để che đi Puppet AWS Module bị thiếu)
Huy Ngo - Technical Consultant tại TMA Solutions