使用terraform创建阿里ecs用ansible完成主机配置

文章目录

使用terraform创建ecs用ansible完成ecs的provision

  • 本文目标就是是用terraform创建ecs包括security group,disk,vpc,vswtich,然后用ansible来初始化和配置创建好的ecs
  • 本文只是创建了一个单机ecs,后续的文章会有load balance出现

terrorm 创建ecs

  • 什么是terraform

    1. terraform是云工具,也就是针对云平台的
    2. terraform是在云平台上管理资源的,就是一个云资源编排工具
    3. terraform目标是"Write, Plan, and create Infrastructure as Code", 基础架构即代码。具体的说就是可以用代码来管理维护 IT 资源,把之前需要手动操作的一部分任务通过程序来自动化的完成,这样的做的结果非常明显:高效、不易出错。
  • Terraform 核心功能

    1. 基础架构即代码(Infrastructure as Code)
    2. 执行计划(Execution Plans)
    3. 资源图(Resource Graph)
    4. 自动化变更(Change Automation)
  • terraform安装

    1. 下载https://www.terraform.io/downloads.html
    2. 设置环境变量(省略)
  • 创建terraform 配置文件

    1. main.tf
      1     provider "alicloud" {
      2     access_key = "xxx"
      3     secret_key = "xxx"
      4     region     = "ap-southeast-1"
      5     #version    = "~> 1.5.0"
      6     }
      7     data "alicloud_instance_types" "instance_type" {
      8     instance_type_family = "ecs.n1"
      9     cpu_core_count       = "1"
     10     memory_size          = "2"
     11     }
     12
     13     resource "alicloud_security_group" "group" {
     14     name        = var.short_name
     15     description = "New security group"
     16     vpc_id      = alicloud_vpc.vpc.id
     17     }
     18
     19     resource "alicloud_key_pair" "alicloud_key_pair" {
     20     key_name   = "terraform_test"
     21     public_key = "${file(var.ssh_key_public)}"
     22     }
     23     resource "alicloud_security_group_rule" "allow_http_80" {
     24     type              = "ingress"
     25     ip_protocol       = "tcp"
     26     nic_type          = var.nic_type
     27     policy            = "accept"
     28     port_range        = "80/80"
     29     priority          = 1
     30     security_group_id = alicloud_security_group.group.id
     31     cidr_ip           = "0.0.0.0/0"
     32     }
     33
     34     resource "alicloud_security_group_rule" "allow_https_443" {
     35     type              = "ingress"
     36     ip_protocol       = "tcp"
     37     nic_type          = var.nic_type
     38     policy            = "accept"
     39     port_range        = "443/443"
     40     priority          = 1
     41     security_group_id = alicloud_security_group.group.id
     42     cidr_ip           = "0.0.0.0/0"
     43     }
     44     resource "alicloud_security_group_rule" "allow_ssh_22" {
     45     type              = "ingress"
     46     ip_protocol       = "tcp"
     47     nic_type          = var.nic_type
     48     policy            = "accept"
     49     port_range        = "22/22"
     50     priority          = 1
     51     security_group_id = alicloud_security_group.group.id
     52     cidr_ip           = "0.0.0.0/0"
     53     }
     54
     55
     56     resource "alicloud_disk" "disk" {
     57     availability_zone = alicloud_instance.instance[0].availability_zone
     58     category          = var.disk_category
     59     size              = var.disk_size
     60     count             = var.number
     61     }
     62
     63     resource "alicloud_vpc" "vpc" {
     64     cidr_block = "172.16.0.0/12"
     65     }
     66
     67     data "alicloud_zones" "zones_ds" {
     68     available_instance_type = data.alicloud_instance_types.instance_type.instance_types[0].id
     69     }
     70
     71     resource "alicloud_vswitch" "vswitch" {
     72     vpc_id            = alicloud_vpc.vpc.id
     73     cidr_block        = "172.16.0.0/24"
     74     availability_zone = data.alicloud_zones.zones_ds.zones[0].id
     75     }
     76     resource "alicloud_instance" "instance" {
     77     instance_name   = "${var.short_name}-${var.role}-${format(var.count_format, count.index + 1)}"
     78     host_name       = "${var.short_name}-${var.role}-${format(var.count_format, count.index + 1)}"
     79     image_id        = var.image_id
     80     instance_type   = data.alicloud_instance_types.instance_type.instance_types[0].id
     81     count           = var.number
     82     security_groups = alicloud_security_group.group.*.id
     83     vswitch_id      = alicloud_vswitch.vswitch.id
     84
     85     internet_charge_type       = var.internet_charge_type
     86     internet_max_bandwidth_out = var.internet_max_bandwidth_out
     87
     88     password = var.ecs_password
     89
     90     instance_charge_type          = "PostPaid"
     91     system_disk_category          = "cloud_efficiency"
     92     security_enhancement_strategy = "Deactive"
     93     key_name = alicloud_key_pair.alicloud_key_pair.key_name
     94     data_disks {
     95         name        = "disk1"
     96         size        = "20"
     97         category    = "cloud_efficiency"
     98         description = "disk1"
     99     }
    100     tags = {
    101         role = var.role
    102         dc   = var.datacenter
    103     }
    104
    105     resource "alicloud_disk_attachment" "instance-attachment" {
    106     count       = var.number
    107     disk_id     = alicloud_disk.disk.*.id[count.index]
    108     instance_id = alicloud_instance.instance.*.id[count.index]
    109     }
    
    1. outputs.tf
     1 output "hostname_list" {
     2 value = join(",", alicloud_instance.instance.*.instance_name)
     3 }
     4
     5 output "ecs_ids" {
     6 value = join(",", alicloud_instance.instance.*.id)
     7 }
     8
     9 output "ecs_public_ip" {
    10 value = join(",", alicloud_instance.instance.*.public_ip)
    11 }
    12
    13 output "tags" {
    14 value = jsonencode(alicloud_instance.instance.*.tags)
    15 }
    
    1. variables.tf
     1 variable "number" {
     2 default = "1"
     3 }
     4
     5 variable "count_format" {
     6 default = "%02d"
     7 }
     8
     9 variable "image_id" {
    10 default = "ubuntu_18_04_64_20G_alibase_20190624.vhd"
    11 }
    12
    13 variable "role" {
    14 default = "work"
    15 }
    16
    17 variable "datacenter" {
    18 default = "beijing"
    19 }
    20
    21 variable "short_name" {
    22 default = "hi"
    23 }
    24
    25 variable "ecs_type" {
    26 default = "ecs.n4.small"
    27 }
    28
    29 variable "ecs_password" {
    30 default = "Test12345"
    31 }
    32
    33 variable "internet_charge_type" {
    34 default = "PayByTraffic"
    35 }
    36
    37 variable "internet_max_bandwidth_out" {
    38 default = 5
    39 }
    40
    41 variable "disk_category" {
    42 default = "cloud_efficiency"
    43 }
    44
    45 variable "disk_size" {
    46 default = "40"
    47 }
    48
    49 variable "nic_type" {
    50 default = "intranet"
    51 }
    52 variable "ssh_key_public" {
    53 default     = "~/.ssh/id_rsa.pub"
    54 description = "Path to the SSH public key for accessing cloud instances. Used for creating AWS keypair."
    55 }
    56
    57 variable "ssh_key_private" {
    58 default     = "~/.ssh/id_rsa"
    59 description = "Path to the SSH public key for accessing cloud instances. Used for creating AWS keypair."
    60 }
    
    1. versions.tf
    1 terraform {
    2 required_version = ">= 0.12"
    3 }
    

用ansible部署docker容器

  • ansible介绍

    1. Ansible是一个开源配置管理工具,可以使用它来自动化任务,部署应用程序实现IT基础架构。Ansible可以用来自动化日常任务,比如,服务器的初始化配置、安全基线配置、更新和打补丁系统,安装软件包等。Ansible架构相对比较简单,仅需通过SSH连接客户机执行任务即可
  • ansible安装

    1 yum install ansible -y
    
  • 更新配置

    1 vi /etc/ansible/ansible.cfg
    2
    3 host_key_checking = False
    
  • 创建ansible playbook 模板代码

     1  ---
     2    - hosts: docker
     3      remote_user: root
     4      become: yes
     5      become_method: sudo
     6      vars:
     7        container_name: "nginx"
     8        container_image: "nginx:latest"
     9        registry_url: "docker.io/library"
    10        working_dir: "/data/nginx"
    11
    12      tasks:
    13        - name: remove container
    14          docker_container:
    15            name: "{{ container_name }}"
    16            state: absent
    17            timeout: 600
    18        - name: create working_dir directory
    19          file:
    20            path: "{{ item }}"
    21            state: directory
    22          with_items:
    23            - "{{ working_dir }}"
    24
    25        - name: create container
    26          docker_container:
    27            name: "{{ container_name }}"
    28            image: "{{registry_url}}/{{ container_image }}"
    29            privileged: yes
    30            timeout: 600
    31            restart_policy: always
    32            ports:
    33              - "80:80"
    
  • 在terraform的ecs的instance 中使用provisoner 来支持ansible

     1  provisioner "remote-exec" {
     2      # Install Python for Ansible
     3      inline = ["apt update;apt install python -y;rm -rf /usr/bin/python;apt install python3-pip -y;rm -rf /usr/local/bin/pip;ln -s /usr/bin/pip3 /usr/local/bin/pip;pip install docker;apt install docker.io -y;"]
     4      connection {
     5      host = "${self.public_ip}"
     6      type        = "ssh"
     7      user        = "root"
     8      private_key = "${file(var.ssh_key_private)}"
     9      }
    10  }
    11  provisioner "local-exec" {
    12  command = "echo '[docker]' > ./myinventory;echo '${self.public_ip}' >> ./myinventory"
    13  }
    14  provisioner "local-exec" {
    15      command = "ansible-playbook -u root -i myinventory --private-key ${var.ssh_key_private} -T 300 provision.yml"
    16  }
    

执行 terraform

1  terraform int
2  terraform plan
3  terraform apply