はじめに
Railsのアプリケーションを複数管理しているので今後の手間も考え、
何かテンプレ的なものが出来たらいいなと思って作成してみました。
今後の運用において改善点もまだまだあると思ってますのでご意見ご要望はどしどし頂けたらと思います。
今回のゴール
Terraformで構築したEC2インスタンスにAnsibleを使ってRailsアプリケーションをデプロイするまでをゴールとします。
事前準備
Docker, Terraform, aws-cli, Ansibleのインストールをお願いします。
brew install docker
brew install terraform
brew install awscli
brew install ansible
ちなみに私の環境は下記のようになっています。
macOS Mojave 10.14.6
Docker 18.09.2
Compose 1.23.2
Terraform 0.12.3
aws-cli 1.15.50
Ansible 2.6.0
テンプレートリポジトリ
DockerでRails環境構築
以前に記事書いたのでこちらを参考に構築してください。
RubyをインストールせずにDockerでRails環境を構築する
ここまで完了した方は先ほどのテンプレートリポジトリから
terraform
とansible
フォルダをコピーし、個人のリポジトリを作成してpushしておいてください。
TerraformでAWSにインフラ準備
EC2, RDS, LBの構成で進めます。
terraform.tfstate格納用のS3バケットとAWSクレデンシャルは各自で用意してください。
S3バケット名:tf-bucket
AWSクレデンシャルprofile名:tf-profile
[tf-profile]
aws_access_key_id = XXXXXXXXXXXXXXXXX
aws_secret_access_key = YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
provider "aws" {
region = "ap-northeast-1"
version = "2.12.0"
profile = "tf-profile"
}
terraform {
required_version = ">= 0.12"
backend "s3" {
bucket = "tf-bucket"
region = "ap-northeast-1"
key = "sample/sg/terraform.tfstate"
encrypt = true
profile = "tf-profile"
}
}
# EC2に設定するセキュリティグループ
resource "aws_security_group" "ec2_security_group" {
name = "${var.app_name}-sg"
vpc_id = var.vpc_id
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"
security_groups = [aws_security_group.lb_security_group.id]
}
egress {
from_port = "0"
to_port = "0"
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.app_name}-sg"
}
}
output "ec2_sg_id" {
value = aws_security_group.ec2_security_group.id
}
//...これより後ろの設定はそのまま残しておいてください。
variable "vpc_id" {
default = "your-vpc-id"
}
variable "app_name" {
default = "sample-app"
}
ファイルの修正が完了したら下記コマンドを順番に実行してみてください。
terraform init
terraform plan
terraform apply
最後まで実行出来たらセキュリティグループが作成されているはずです。
output
メソッドで最終的に作成されたセキュリティグループIDを出力していることを覚えて追いてください。これを後ほどEC2作成時に利用します。
次にEC2の作成です。
Keypairは事前に作成し、サブネットも各自のサブネットIDを指定してください。
サブネット:subnet-000111222、subnet-333444555
Keypair:tf-keypair
provider "aws" {
region = "ap-northeast-1"
version = "2.12.0"
profile = "tf-profile"
}
terraform {
required_version = ">= 0.12"
backend "s3" {
bucket = "tf-bucket"
region = "ap-northeast-1"
key = "sample/ec2/terraform.tfstate"
encrypt = true
profile = "tf-profile"
}
}
data "terraform_remote_state" "security_group" {
backend = "s3"
config = {
bucket = "tf-bucket"
region = "ap-northeast-1"
key = "sample/sg/terraform.tfstate"
profile = "tf-profile"
}
}
resource "aws_instance" "ec2" {
count = var.instance_count
ami = var.ami_id
instance_type = var.instance_type
key_name = var.key_pair
subnet_id = lookup(var.subnets, count.index % 2)
associate_public_ip_address = "true"
vpc_security_group_ids = [data.terraform_remote_state.security_group.outputs.ec2_sg_id]
tags = {
Name = "${var.app_name}_${count.index + 1}"
}
}
output "instance_ids" {
value = {
for instance in aws_instance.ec2 :
instance.id => instance.private_ip
}
}
output "instance_count" {
value = var.instance_count
}
variable "ami_id" {
default = "ami-0b898040803850657"
}
variable "instance_count" {
default = 1
}
variable "subnets" {
default = {
"0" = "subnet-000111222"
"1" = "subnet-333444555"
}
}
variable "instance_type" {
default = "t3.micro"
}
variable "key_pair" {
default = "tf-keypair"
}
variable "app_name" {
default = "sample-app"
}
ファイルの修正が完了したら下記コマンドを順番に実行してみてください。
terraform init
terraform plan
terraform apply
最後まで実行出来たらEC2が作成されているはずです。
作成したKeypairにてssh接続出来るか各自確認をお願いします。
RDSとLBの手順は割愛しますが、似たような感じでテンプレとして用意していますのでご活用頂けたらと思います。
AnsibleでRuby環境構築
以前に記事を書いています。→ AnsibleでRuby環境構築
今回はこれに+αとして実際にGitサーバからソースをCloneし、CapistranoでRailsアプリをデプロイするテンプレまで作成しました。
まずはansibleユーザーがssh接続するための設定をします。
---
[server]
先ほどTerraformで作成したEC2のIP
[server:vars]
ansible_user=ec2-user
ansible_ssh_private_key_file=~/.ssh/tf-keypair.pem
[server_secret:children]
server
[development:children]
server
次にアプリ名やデプロイ先のフォルダなどを指定をします。
ここで先ほどcommitした個人のリポジトリを指定してください。
あと、sshでClone出来るように各自で公開鍵と秘密鍵を作成してGitサーバ側に公開鍵を設定してください。
GitHubでssh接続する手順~公開鍵・秘密鍵の生成から
---
ruby_version: 2.6.3
bundler_version: 2.0.2
git_url: git@github.com:hoge.git
app_user: sample-app
project_name: sample
deploy_directory: /opt/{{ project_name }}
先ほど作成した秘密鍵やその他暗号化が必要な情報はansible-vault
で暗号化してください。
vault_pass_sampleをvault_passへリネームして下記コマンドを実行してください。
ansible-vault edit group_vars/server_secret.yml
ここにrailsのmaster_keyや先ほど作成した秘密鍵や公開鍵などを設定してください。
rails_master_key: xxx
ssh_authorized_keys: 'ssh-rsa XXX'
ssh_private_key: |
-----BEGIN RSA PRIVATE KEY-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
...
-----END RSA PRIVATE KEY-----
最後にgitブランチやcapistrano実行時のenvをgroup_vars/{env}.yml
に設定して、
下記コマンドを実行するとEC2インスタンス環境にRuby環境の構築からGitリポジトリのCloneまで一通り行ってくれます。
# 初回のみ実行
ansible-playbook init.yml -i development
# 2回目以降デプロイ用
ansible-playbook deploy.yml -i development
※nginx.confやlogrotate.confなどもテンプレとして配置してますので各プロジェクトの設定に応じてご利用ください。
Capistrano
参考までにCapistrano設定ファイル群をcapistrano
フォルダに置いてますので興味のある方は覗いてみてください。