使用Vagrant + Ansible来启动和配置多个EC2实例

一条指令就能建立理想的环境,真是太令人开心了!我非常高兴!

开发环境和生产环境等有各种用途,但是在同时建立、运行和删除多个服务器时,Vagrant和配置管理工具非常方便。虽然有很多选择,如Chef、Puppet等,但为了方便地创建和使用定义文件,我们这次选择使用Ansible。

这次我们将启动5个实例,它们都是运行着相同应用程序但参考不同数据库的。我们将从已完成部署的AMI启动实例,并为每个主机更改配置文件。

创建一个Vagrantfile文件

请安装vagrant-aws插件,因为我们将使用EC2。

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  access_key = ENV['AWS_ACCESS_KEY']
  access_secret = ENV['AWS_SECRET_KEY']
  config.vm.box = "dummy"
  config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"


  config.vm.define :ap1 do |ap1|
    ap1.vm.provider :aws do |aws, override|
      aws.access_key_id = access_key
      aws.secret_access_key = access_secret
      aws.keypair_name = "AWS_KEYPAIR_NAME"
      aws.region = "ap-northeast-1"
      aws.ami = "ami-xxxxxx"
      aws.user_data = "#!/bin/bash\nexport TARGET_ENV=test;"
      aws.availability_zone = "ap-northeast-1a"
      aws.instance_type = "m1.small"
      aws.security_groups = ["aws_security_group"]
      override.ssh.username = "aws_user"
      override.ssh.private_key_path = "~/.ssh/aws_private_key"
      aws.tags = {
        'Name' => 'ap01',
      }
    end
    ap1.vm.provision "ansible" do |ansible|
      ansible.groups = {
        "ap1" => ["ap1"]
      }
      ansible.extra_vars = {
        "db_host" => db_host,
        "db_name" => "db_01"
      }
      ansible.playbook = "playbook.yaml"
    end
  end

  config.vm.define :ap2 do |ap2|
    ap2.vm.provider :aws do |aws, override|
      aws.access_key_id = access_key
      aws.secret_access_key = access_secret
      aws.keypair_name = "AWS_KEYPAIR_NAME"
      aws.region = "ap-northeast-1"
      aws.ami = "ami-xxxxxx"
      aws.user_data = "#!/bin/bash\nexport TARGET_ENV=test;"
      aws.availability_zone = "ap-northeast-1a"
      aws.instance_type = "m1.small"
      aws.security_groups = ["aws_security_group"]
      override.ssh.username = "aws_user"
      override.ssh.private_key_path = "~/.ssh/aws_private_key"
      aws.tags = {
        'Name' => 'ap02',
      }
    end
    ap2.vm.provision "ansible" do |ansible|
      ansible.groups = {
        "ap2" => ["ap2"]
      }
      ansible.extra_vars = {
        "db_host" => db_host,
        "db_name" => "db_02"
      }
      ansible.playbook = "playbook.yaml"
    end
  end

  config.vm.define :ap3 do |ap3|
    ap3.vm.provider :aws do |aws, override|
      aws.access_key_id = access_key
      aws.secret_access_key = access_secret
      aws.keypair_name = "AWS_KEYPAIR_NAME"
      aws.region = "ap-northeast-1"
      aws.ami = "ami-xxxxxx"
      aws.user_data = "#!/bin/bash\nexport TARGET_ENV=test;"
      aws.availability_zone = "ap-northeast-1a"
      aws.instance_type = "m1.small"
      aws.security_groups = ["aws_security_group"]
      override.ssh.username = "aws_user"
      override.ssh.private_key_path = "~/.ssh/aws_private_key"
      aws.tags = {
        'Name' => 'ap03',
      }
    end
    ap3.vm.provision "ansible" do |ansible|
      ansible.groups = {
        "ap3" => ["ap3"]
      }
      ansible.extra_vars = {
        "db_host" => db_host,
        "db_name" => "db_03"
      }
      ansible.playbook = "playbook.yaml"
    end
  end

  config.vm.define :ap4 do |ap4|
    ap4.vm.provider :aws do |aws, override|
      aws.access_key_id = access_key
      aws.secret_access_key = access_secret
      aws.keypair_name = "AWS_KEYPAIR_NAME"
      aws.region = "ap-northeast-1"
      aws.ami = "ami-xxxxxx"
      aws.user_data = "#!/bin/bash\nexport TARGET_ENV=test;"
      aws.availability_zone = "ap-northeast-1a"
      aws.instance_type = "m1.small"
      aws.security_groups = ["aws_security_group"]
      override.ssh.username = "aws_user"
      override.ssh.private_key_path = "~/.ssh/aws_private_key"
      aws.tags = {
        'Name' => 'ap04',
      }
    end
    ap4.vm.provision "ansible" do |ansible|
      ansible.groups = {
        "ap4" => ["ap4"]
      }
      ansible.extra_vars = {
        "db_host" => db_host,
        "db_name" => "db_04"
      }
      ansible.playbook = "playbook.yaml"
    end
  end

  config.vm.define :ap5 do |ap5|
    ap5.vm.provider :aws do |aws, override|
      aws.access_key_id = access_key
      aws.secret_access_key = access_secret
      aws.keypair_name = "AWS_KEYPAIR_NAME"
      aws.region = "ap-northeast-1"
      aws.ami = "ami-xxxxxx"
      aws.user_data = "#!/bin/bash\nexport TARGET_ENV=test;"
      aws.availability_zone = "ap-northeast-1a"
      aws.instance_type = "m1.small"
      aws.security_groups = ["aws_security_group"]
      override.ssh.username = "aws_user"
      override.ssh.private_key_path = "~/.ssh/aws_private_key"
      aws.tags = {
        'Name' => 'ap05',
      }
    end
    ap5.vm.provision "ansible" do |ansible|
      ansible.groups = {
        "ap5" => ["ap5"]
      }
      ansible.extra_vars = {
        "db_host" => db_host,
        "db_name" => "db_05"
      }
      ansible.playbook = "playbook.yaml"
    end
  end

end

创建一个手册

我們要創建Ansible的配置定義文件playbook。由於可以用yaml編寫,所以不需要去學習新的DSL,這是一大優勢!!

---
- name: Setup ecs
  hosts: all
  remote_user: aws_user
  sudo: yes
  tasks:

    - name: upload config
      template: src=config.ini dest=/var/www/Application/common/config/config.ini

    - name: start httpd
      service: name=httpd state=restarted enabled=yes

准备一个模板

使用模板来设置配置文件,并通过Vagrantfile的ansible.extra_values分别赋予不同的值。因此,

database.host   = {{ db_host }}
database.name   = {{ db_name }}

在被{{}}包围的部分会展开变量。

文件的位置安排

这次就是这样了。

├── Vagrantfile
├── config.ini
└── playbook.yaml

根据规模的不同,可以采用Ansible最佳实践。

开始,结束

然后,在Vagrantfile所在的位置执行vagrant up –provide aws。要删除环境,使用vagrant destroy。如果需要,可以添加-f选项。

结束

我对于Vagrant和Ansible的协作方式阅读了文档,但仍然不太明白,因此为了自己整理了一下。果然,Ansible还是方便易用且实用的。

广告
将在 10 秒后关闭
bannerAds