Terraform v0.12.1
Swift製 WebFrameWork である Vapor をECS へのデプロイするところまでをTerraformの練習として書きました。
解説記事というよりは個人的な忘備録、メモになります。
Terraform が初めての場合は Terraform 公式のチュートリアルにまず取り掛かる事をお勧めします。
Terraform はバージョンによる差異も大きく、そしてどんどん良いものになっているため、これから始めるのであれば最新版を使うことをお勧めします。
アプリケーションの作成
まずECS上で動かすためのアプリケーションが必要です。
Vapor のテンプレートをアプリケーションとして使用します。
今回は以下のような Dockerfile を作成し、この Dockerfile により作られるイメージをECS で動かすことを目的とします。
Dockerfile
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y \
git \
vim \
wget \
curl
RUN /bin/bash -c "$(wget -qO- https://apt.vapor.sh)"
RUN apt-get install -y \
swift \
vapor
RUN vapor new Hello --template=web
WORKDIR /Hello
RUN vapor build
EXPOSE 80
CMD ["swift", "run", "Run", "--hostname", "0.0.0.0", "--port", "80"]
Terraform の設定
次に Terraform から AWS にアクセスできることを確認します。
########################
## Credential Infos
########################
variable "access_key" {
description = "AWS access key"
}
variable "secret_key" {
description = "AWS secret access key"
}
variable "region" {
description = "AWS region to host your network"
}
provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}
ECRの作成
CodeBuild で作成したイメージを格納する ECR を作成します。
########################
## ECR
########################
# ECS Repository
resource "aws_ecr_repository" "repository" {
name = "my-repository"
}
# Repositry Policy
# Permit pull image
resource "aws_ecr_repository_policy" "repository_policy" {
repository = "${aws_ecr_repository.repository.name}"
policy = <<EOF
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "new statement",
"Effect": "Allow",
"Principal": "*",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
]
}
]
}
EOF
}
CodeBuildProjectの作成
CodeBuildProject を作成します。
########################
## CodeBuild
########################
data "aws_iam_policy_document" "codebuild_assume_role_policy_document" {
statement {
sid = "CodebuildExecution"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["codebuild.amazonaws.com"]
}
}
}
resource "aws_iam_role" "codebuild_role" {
name = "my-codebuild"
assume_role_policy = "${data.aws_iam_policy_document.codebuild_assume_role_policy_document.json}"
}
data "aws_iam_policy_document" "codebuild_policy_document" {
statement {
sid = "Logging"
actions = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
]
resources = ["*"]
}
statement {
sid = "PushECR"
actions = [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage",
]
resources = ["*"]
}
}
resource "aws_iam_role_policy" "codebuild_role_policy" {
role = "${aws_iam_role.codebuild_role.name}"
policy = "${data.aws_iam_policy_document.codebuild_policy_document.json}"
}
# templete などを別ファイルに書き出すことをおすすめです。
data "template_file" "buildspec_template_file" {
template = <<EOF
version: 0.2
phases:
pre_build:
commands:
- echo pre_build
- echo Logging in to Amazon ECR...
- $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
build:
commands:
- echo build
- echo build docker image
- docker build -t vapor:latest .
post_build:
commands:
- echo post_build
- docker tag vapor:latest ${aws_ecr_repository.repository.repository_url}:latest
- docker push ${aws_ecr_repository.repository.repository_url}:latest
EOF
}
resource "aws_codebuild_project" "codebuild_project" {
name = "build-vapor-image"
description = "build vapor image"
build_timeout = "30"
service_role = "${aws_iam_role.codebuild_role.arn}"
artifacts {
type = "NO_ARTIFACTS"
}
cache {
type = "LOCAL"
modes = ["LOCAL_DOCKER_LAYER_CACHE", "LOCAL_SOURCE_CACHE"]
}
environment {
compute_type = "BUILD_GENERAL1_SMALL"
image = "aws/codebuild/docker:18.09.0"
type = "LINUX_CONTAINER"
privileged_mode = true
image_pull_credentials_type = "CODEBUILD"
}
source {
type = "GITHUB"
# プライベートリポジトリを使う場合はOAuthToken を設定する
# パラメーターストアに保存し、取ってくるのが簡単
# auth {
# type = "OAUTH"
# resource = "${aws_ssm_parameter.github_oauth_token.value}"
# }
location = "https://github.com/O-Junpei/vapor-docker-sample.git"
buildspec = "${data.template_file.buildspec_template_file.rendered}"
}
}
その2に続きます。