Skip to content

Latest commit

 

History

History
328 lines (318 loc) · 8.51 KB

terraform.md

File metadata and controls

328 lines (318 loc) · 8.51 KB

可以创建AWS/openstack/Azure等,一个开源的云平台管理工具,假如你用了Azure/openstack等混杂云环境,可以考虑用这个,官方文档非常的简洁。下边例子是创建VPC/subnet/若干个EC2,后端的subnet的ec2通过nat-box上网并且安装puppet/zabbix的yum repo。不多说了,

talk is cheap, show me the code.

注意provisioner有个问题:创建EIP和remote-exec, 由于remote-exec需要EIP,但terraform会等remote-exec执行完才得到eip,这显然是不可能的,需要depends_on来指定先后顺序和用null_resource, 这这里也有说明。

  
# variables
provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}
resource "aws_vpc" "demo" {
cidr_block = "10.0.0.0/16"
tags {
  Name = "demo"
}
}
resource "aws_subnet" "public" {
vpc_id = "${aws_vpc.demo.id}"
cidr_block = "10.0.10.0/24"
tags {
  Name = "demo-public"
}
}
resource "aws_subnet" "private" {
vpc_id = "${aws_vpc.demo.id}"
cidr_block = "10.0.80.0/24"
tags {
  Name = "demo-private"
}
}
resource "aws_internet_gateway" "default" {
vpc_id = "${aws_vpc.demo.id}"
tags {
  Name = "default-IGW"
}
}
resource "aws_route_table" "internet_access" {
vpc_id = "${aws_vpc.demo.id}"
route {
  cidr_block = "0.0.0.0/0"
  gateway_id = "${aws_internet_gateway.default.id}"
}
tags {
  Name = "igw"
}
}
resource "aws_route_table_association" "public" {
subnet_id = "${aws_subnet.public.id}"
route_table_id = "${aws_route_table.internet_access.id}"
}
resource "aws_route_table" "private" {
vpc_id = "${aws_vpc.demo.id}"
route {
  cidr_block = "0.0.0.0/0"
  instance_id = "${aws_instance.nat.id}"
}
}
resource "aws_route_table_association" "private" {
subnet_id = "${aws_subnet.private.id}"
route_table_id = "${aws_route_table.private.id}"
}
resource "aws_elb" "web" {
name = "pcf-elb"
subnets = ["${aws_subnet.private.id}"]
security_groups = ["${aws_security_group.elb.id}"]
listener {
  instance_port = 80
  instance_protocol = "http"
  lb_port = 80
  lb_protocol = "http"
}
health_check {
  healthy_threshold = 2
  unhealthy_threshold = 2
  timeout = 3
  target = "HTTP:80/"
  interval = 30
}
# The instance is registered automatically
# instances = ["${aws_instance.web.id}"]
cross_zone_load_balancing = true
idle_timeout = 400
connection_draining = true
connection_draining_timeout = 400
tags {
  Name = "test-pcf"
}
}
/*
 resource "aws_lb_cookie_stickiness_policy" "default" {
 name = "lbpolicy"
 load_balancer = "${aws_elb.web.id}"
 lb_port = 80
 cookie_expiration_period = 600
 } */
resource "aws_security_group" "elb" {
name = "example_elb"
description = "Nothing more"
vpc_id = "${aws_vpc.demo.id}"
# HTTP access from anywhere
ingress {
  from_port = 80
  to_port = 80
  protocol = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
}
# outbound internet access
egress {
  from_port = 0
  to_port = 0
  protocol = "-1"
  cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_eip" "demo" {
instance = "${aws_instance.zabbix-server.id}"
depends_on = ["aws_instance.zabbix-server"]
vpc = true
}
resource "aws_instance" "zabbix-server" {
ami = "${lookup(var.aws_opsman_ami,var.region)}"
instance_type = "m3.medium"
key_name = "${var.key_name}"
subnet_id = "${aws_subnet.public.id}"
vpc_security_group_ids = ["${aws_security_group.all_pass.id}"]
tags {
  Name = "zabbix-server"
}
}
resource "null_resource" "server-provisioning" {
triggers {
  instance = "${aws_instance.zabbix-server.id}"
}
connection {
  host = "${aws_eip.demo.public_ip}"
  user = "ec2-user"
  timeout = "5m"
  private_key = "${file("./hfu.pem")}"
}
provisioner "file" {
  # puppet.conf
  content = <<EOF
[main]
certname = ${var.puppetname}
server = ${var.puppetname}
strict_variables = true
masterport = 8140
[master]
node_terminus = exec
external_nodes = /etc/puppetlabs/enc.rb
autosign = true
vardir = /opt/puppetlabs/server/data/puppetserver
logdir = /var/log/puppetlabs/puppetserver
rundir = /var/run/puppetlabs/puppetserver
pidfile = /var/run/puppetlabs/puppetserver/puppetserver.pid
codedir = /etc/puppetlabs/code
[agent]
puppetmaster = ${var.puppetname}
environment = production
runinterval = 1h
EOF
  destination = "/tmp/puppetmaster"
}
provisioner "file" {
  # external node classifier
  content =<<EOF
#!/usr/bin/env ruby
require 'yaml'
node = ARGV[0]
# agent FQDN : ${app}.${env}.${Location || IDC}, e.g web01.prod.bjcnc
if node =~ /(^[a-zA-Z]+)(\d+)\.(\S+)\.(\S+)$/
  hostname = $1
  env = $3
  config = YAML.load_file('defaults.yaml')[env]
  print YAML.dump(config.fetch(hostname))
  exit 0
else
  config = YAML.load_file('defaults.yaml')
  print YAML.dump(config.fetch('base'))
  exit 0
end
EOF
  destination = "/tmp/enc"
}
provisioner "remote-exec" {
  inline = [
    # reserve EC2 for future usage.
    "sudo echo ${join(",", aws_instance.trial.*.private_ip)} >>/tmp/ec2_list" ,
    "sudo bash -c 'echo puppet \"${aws_instance.zabbix-server.private_ip} puppet.xxx.com\" >> /etc/hosts'" ,
    "sudo rpm -ivh ",
    "sudo rpm -Uvh ",
    "sudo sed -i 's/enabled=0/enabled=1/g' /etc/yum.repos.d/redhat-rhui.repo",
    "sudo yum -y install ruby mariadb mariadb-server vim-enhanced telnet zabbix-server-mysql zabbix-web-mysql puppetserver 1 >/dev/null ",
    "sudo mv /tmp/puppetmaster /etc/puppetlabs/puppet/puppet.conf",
    "sudo mv /tmp/enc /etc/puppetlabs/enc.rb",
    "sudo chmod a+x /etc/puppetlabs/enc.rb",
    # start puppetmaster
# "sudo systemctl start puppetserver",
  ]
}
}
resource "aws_instance" "trial" {
count = 1
ami = "${var.other_ami}"
instance_type = "t2.micro"
key_name = "${var.key_name}"
subnet_id = "${aws_subnet.private.id}"
vpc_security_group_ids = ["${aws_security_group.all_pass.id}"]
tags {
  # generate sequential tag , Name = "${format("web-%03d", count.index)}"
  Name = "${lookup(var.instance_tag, count.index)}"
}
provisioner "local-exec" {
  /*
  To reference attributes of your own resource, the syntax is self.ATTRIBUTE. For example ${self.private_ip_address} will interpolate that resource's private IP address. Note that this is only allowed/valid within provisioners.
  */
  command = "echo ${self.private_ip} > private_ips"
}
connection {
  host = "${self.private_ip}"
  bastion_host = "${aws_eip.demo.public_ip}"
  user = "ec2-user"
  timeout = "5m"
  bastion_port = "22"
  bastion_private_key = "${file("./hfu.pem")}"
}
provisioner "file" {
  # puppet.conf of agent
  content = <
[agent]
puppetmaster = ${var.puppetname}
environment = production
runinterval = 1h
EOF
  destination = "/tmp/init_env.sh"
}
provisioner "remote-exec" {
  inline = [
    "sudo bash -c 'echo puppet \"${aws_instance.zabbix-server.private_ip} puppet.xxx.com\" >> /etc/hosts

variable "access_key" {
default = "xxxx"
}
variable "secret_key" {
default = "xxxxxxx"
}
variable "key_name" {
default = "hfu"
}
variable "region" {
default = "cn-north-1"
}
variable "aws_opsman_ami" {
type = "map"
default = {
  cn-north-1 = "ami-52d1183f"
  us-east-1 = "ami-xx"
}
}
variable "other_ami" {
  default = "ami-52d1183f"
}
variable "aws_nat_ami" {
type = "map"
default = {
  cn-north-1 = "ami-1848da21"
  us-east-1 = "ami-xxx"
}
}
variable "puppetname" {
  default = "puppet.xxx.com"
}
variable "instance_tag" {
default = {
  "0" = "client"
}
}

#variables.tf

variable "access_key" {
  default = "xxxx"
}
variable "secret_key" {
  default = "xxxxxxx"
}
variable "key_name" {
  default = "hfu"
}
variable "region" {
  default = "cn-north-1"
}
variable "aws_opsman_ami" {
  type = "map"
  default = {
    cn-north-1 = "ami-52d1183f"
    us-east-1 = "ami-xx"
  }
}
variable "other_ami" {
    default = "ami-52d1183f"
}
variable "aws_nat_ami" {
  type = "map"
  default = {
    cn-north-1 = "ami-1848da21"
    us-east-1 = "ami-xxx"
  }
}
variable "puppetname" {
    default = "puppet.xxx.com"
}
variable "instance_tag" {
  default = {
    "0" = "client"
  }
}

至于层次结构跟cloudformation差不多,只不过它不是json文件,这个要注意。其他什么input/output/provider/provisioner也大同小异不多说了。