使用OSS版的Drone 0.4和Terraform来进行基础设施持续集成(CI)
总结
使用drone0.4的terraform插件来进行基础设施CI。
-
- レポジトリは Github のプライベートレポジトリを作成
- デプロイ先は AWS
有关于0.4版本的无人机环境配置,请参考之前的文章。
有关Terraform插件的详细信息,请点击此处。
先决条件 jué
-
- drone の OAuth applications 登録済み
- terraform の tfstate は S3 で管理する
准备


由于部署密钥会自动注册,因此GitHub和Drone的配置已完成。
创建S3存储桶
创建一个用于管理tfstate的S3存储桶。
$ aws s3 mb s3://quickguard-terraform-config
创建秘密变量
通过 Drone 画面中的 SECRETS 输入环境变量创建秘密变量。

环境变量的内容
-
- AWS_ACCESS_KEY_ID
-
- AWS_SECRET_ACCESS_KEY
-
- AWS_DEFAULT_REGION
-
- SSH_KEY_NAME : EC2インスタンスに設定する SSH Key Name
-
- TFSTATE_BUCKET : tfstate 管理用の S3 Bucket Name
- TFSTATE_KEY : tfstate Name
将创建的 secret 变量保存为 .drone.sec 文件,并提交。
$ git add .drone.sec
$ git commit -m "[CI SKIP]added .drone.sec file"
创建.drone.yml文件
build:
image: docker-registry:5000/terraform
environment:
- AWS_ACCESS_KEY_ID=$$AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY=$$AWS_SECRET_ACCESS_KEY
- AWS_DEFAULT_REGION=$$AWS_DEFAULT_REGION
- SSH_KEY_NAME=$$SSH_KEY_NAME
- TFSTATE_BUCKET=$$TFSTATE_BUCKET
- TFSTATE_KEY=$$TFSTATE_KEY
commands:
- cd $DRONE_DIR
- rm -rf .terraform
- terraform remote config -backend=s3 -backend-config=region=${AWS_DEFAULT_REGION} -backend-config=bucket=${TFSTATE_BUCKET} -backend-config=key=${TFSTATE_KEY}
- terraform remote pull
- terraform plan -var access_key=${AWS_ACCESS_KEY_ID} -var secret_key=${AWS_SECRET_ACCESS_KEY} -var region=${AWS_DEFAULT_REGION} -var key_name=${SSH_KEY_NAME}
when:
branch: "!master"
deploy:
terraform:
plan: false
sensitive: true
remote:
backend: S3
config:
access_key: $$AWS_ACCESS_KEY_ID
secret_key: $$AWS_SECRET_ACCESS_KEY
region: $$AWS_DEFAULT_REGION
bucket: $$TFSTATE_BUCKET
key: $$TFSTATE_KEY
vars:
access_key: $$AWS_ACCESS_KEY_ID
secret_key: $$AWS_SECRET_ACCESS_KEY
region: $$AWS_DEFAULT_REGION
key_name: $$SSH_KEY_NAME
when:
branch: master
只有当提交到主分支时,才会执行terraform apply操作。这个镜像使用了基于alpine的容器,安装了terraterm 0.6.11。而当提交到非主分支时,会执行terraform plan操作。
测试时的terraform容器的Dockerfile如下
FROM alpine:3.2
ENV TERRAFORM_VERSION 0.6.11
RUN apk add --update wget bash git perl libxml2-utils openssh ca-certificates unzip && \
wget -q "https://circle-artifacts.com/gh/andyshinn/alpine-pkg-glibc/6/artifacts/0/home/ubuntu/alpine-pkg-glibc/packages/x86_64/glibc-2.21-r2.apk" && \
apk add --allow-untrusted glibc-2.21-r2.apk && \
wget -q -O /terraform.zip "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip" && \
unzip /terraform.zip -d /bin && \
apk del --purge wget ca-certificates unzip && \
rm -rf /var/cache/apk/* glibc-2.21-r2.apk /terraform.zip
VOLUME ["/data"]
WORKDIR /data
ENTRYPOINT ["/bin/terraform"]
CMD ["--help"]
将 .drone.sec 文件和 .drone.yml 文件提交到代码库中
(由于还没有 Terraform 代码,请在提交消息中输入 [CI SKIP] 来跳过)
让我们尝试进行基础设施CI
先暫時修改並創建例子以生成terraform代碼。
provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}
resource "aws_eip" "default" {
instance = "${aws_instance.web.id}"
vpc = true
}
resource "aws_security_group" "default" {
name = "eip_example"
description = "Used in the terraform"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "web" {
instance_type = "t2.micro"
ami = "${lookup(var.aws_amis, var.region)}"
key_name = "${var.key_name}"
security_groups = ["${aws_security_group.default.name}"]
user_data = "${file("userdata.sh")}"
tags {
Name = "eip-example"
}
}
output "address" {
value = "${aws_instance.web.private_ip}"
}
output "elastic ip" {
value = "${aws_eip.default.public_ip}"
}
variable "access_key" {
description = "AWS access key"
}
variable "secret_key" {
description = "AWS secret key"
}
variable "region" {
description = "The AWS region to create things in."
}
# ubuntu-trusty-14.04 (x64)
variable "aws_amis" {
default = {
"ap-northeast-1" = "ami-a21529cc"
}
}
variable "key_name" {
description = "Name of the SSH keypair to use in AWS."
}
#!/bin/bash -v
apt-get update -y
apt-get install -y nginx > /tmp/nginx.log
创建一个合适的分支并推送terraform代码,然后创建一个Pull Request。


如果没有问题,就合并。

可以确认 Terraform 的输出