12
11

More than 5 years have passed since last update.

Terraform + CircleCI 2.0 + Ansible で作る CD (Continuous Delivery) 環境

Posted at

初めに

これは 第2のドワンゴ Advent Calendar 2017 24日目の記事です。

この記事では、Terraform + CircleCI 2.0 + Ansible を使ったCD(Continuous Delivery) 環境構築方法について解説します。

CD(Continuous Delivery) とは

CDと略されますが、Continuous Delivery と Continuous Deployment と2つの意味で使われることが多いです。

両者の違いについては、上記のURLで解説されているため、説明は割愛しますが、以下継続的デリバリーの略語としてCDを使用します。

CD を行うために必要なモノ

  • インフラストラクチャー
  • CI/CDツール
  • デプロイツール

以上のものが必要です。

今回の事例では、インフラストラクチャーは AWS上にTerraformで構築しました。

AWSの場合、他にもCloudFormationなどが選択肢としてありますが、
- HCLが CloudFormationのJson/Yamlに比べて読みやすい
- インフラの状態管理がしやすい
- 後々クラウドプロバイダーを変更した時にツールを変えてなくて良い

ということから今回は Terraform を採用しています。

CircleCI 2.0 では Workflow機能が使え、testの実行、ビルド、デプロイなどをワークフローとして定義できるため、今回はCircleCI 2.0 を使用しています。

デプロイについては、Ansibleを使用しました。

また対象となるアプリケーションは今回のサンプルでは Play 2.6(Scala)を使用しています。

ワークフロー

  • テストの実行
  • アプリケーションのビルド
  • S3へのビルド成果物アップロード
  • ansibleスクリプトの実行
    • ビルド成果物の配置
    • アプリケーションサーバーの再起動

Terraform でのプロビジョニング

provider "aws" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region     = "${var.region}"
}

resource "aws_vpc" "backbeard_vpc" {
  cidr_block = "10.0.0.0/16"
  tags { Name = "backbeard" }
}
resource "aws_key_pair" "backbeard" {
  key_name   = "${var.key_name}"
  public_key = "${var.ssh_public_key}"
}

resource "aws_subnet" "backbeard_subnet" {
  vpc_id = "${aws_vpc.backbeard_vpc.id}"
  cidr_block = "10.0.0.0/24"
  availability_zone = "${var.region}a"
  tags {
    Name = "backbeard"
  }
}

resource "aws_network_interface" "backbeard" {
  subnet_id = "${aws_subnet.backbeard_subnet.id}"
  private_ips = ["10.0.0.100"]
  tags {
    Name = "backbeard"
  }
}

resource "aws_internet_gateway" "backbeard" {
  vpc_id = "${aws_vpc.backbeard_vpc.id}"
}

resource "aws_instance" "backbeard" {
  ami           = "ami-0a00ce72"
  instance_type = "t2.micro"
  key_name = "${var.key_name}"

  network_interface {
    network_interface_id = "${aws_network_interface.backbeard.id}"
    device_index = 0
  }
  tags {
    Name = "backbeard"
  }
}

resource "aws_eip" "lb" {
  instance = "${aws_instance.backbeard.id}"
  vpc      = true
}

resource "aws_security_group" "backbeard" {
  name        = "backbeard"
  description = "backbeard security group"
  vpc_id      = "${aws_vpc.backbeard_vpc.id}"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    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_route_table" "backbeard" {
  vpc_id = "${aws_vpc.backbeard_vpc.id}"

  route {
    cidr_block = "10.0.0.0/0"
    gateway_id = "${aws_internet_gateway.backbeard.id}"
  }

  tags {
    Name = "backbeard"
  }
}

以上のテンプレートでインフラを作成しました。

backbeardという名前は、現在個人で作っているサービスのコードネームなので適当に無視してください。

Ansibleでのデプロイ

今回Ansibleを以下の用途で使っています。
- Terraformで作成したEC2インスタンスについて必要なアプリケーションのインストール・設定ファイルの配置
- アプリケーションのデプロイ・再起動

Ansibleの設定ファイルは以下のとおりです。

CircleCI での ビルド成果物のアップロード、deployの実行

.circleci/config.yml に定義しています。

リポジトリ

https://github.com/ymizushi/cd-sample
今回作成した環境について、以上のリポジトリで公開しています。

最後に

今回は Terraform + CircleCI + ANsibleでの CD環境構築について説明させていただきました。

個人の開発においてCD環境構築は後回しになりがちな部分であると思いますが、このあたりを先に構築しておくと、リリースと確認に煩雑な手間をかけなくて良くなるため、アプリケーションの開発に集中しやすくなると感じました。

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11