1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

「Knowledge」をTerraformを使用してECS(fagate)構成に変更してみた

Posted at

はじめに

自分の学習記録用にQiita:Team の オープンソースクローン 「Knowledge」を単一のEC2の中で
使用していたのですが、学習も兼ねてTerraformでECS環境へ移行してみました。

移行後の構成イメージ

AWS構成_knowledge.png

参考サイト

みんな大好きDevelopers.ioさんの以下のサイトを参考にしました。
こちらのサイトだと手動で作成していたのですが、
ちょうどTerraformの勉強をしていたので、Terraformを使用してみました。

Amazon ECS + RDS(PostgreSQL) で Qiita:Team の オープンソースクローン Knowledge(Docker版) を構築する

おおまかな手順の流れ

  1. Cloud9実行環境構築

  2. Terraformで環境作成

  3. ECRにイメージをアップロード

  4. タスク定義作成

  5. Terraformでサービス作成

  6. DBデータ移行


1.Cloud9実行環境構築

前提として別の記事でCloud9実行環境構築は作成しているので、
そちらの記事を参照ください。

(1) Homebrewインストール

homebrewについては以下を参照
homebrewとは何者か。仕組みについて調べてみた

$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"

(2) HomebrewにPATHを通す

1を実行すると、Terminalの最後に、PATHが通っていないと警告が表示されます。
そこで、以下コマンドを順に実行してPATHを通します。

$ test -d ~/.linuxbrew && PATH="$HOME/.linuxbrew/bin:$HOME/.linuxbrew/sbin:$PATH"
$ test -d /home/linuxbrew/.linuxbrew && PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH"
$ test -r ~/.bash_profile && echo "export PATH='$(brew --prefix)/bin:$(brew --prefix)/sbin'":'"$PATH"' >>~/.bash_profile
$ echo "export PATH='$(brew --prefix)/bin:$(brew --prefix)/sbin'":'"$PATH"' >>~/.profile

(3) 動作確認

新たにTerminalを開いて確認します。

$ brew
Example usage:
  brew search [TEXT|/REGEX/]
  brew info [FORMULA...]
  brew install FORMULA...
  brew update
  brew upgrade [FORMULA...]
  brew uninstall FORMULA...
  brew list [FORMULA...]

Troubleshooting:
  brew config
  brew doctor
  brew install --verbose --debug FORMULA

Contributing:
  brew create [URL [--no-fetch]]
  brew edit [FORMULA...]

Further help:
  brew commands
  brew help [COMMAND]
  man brew
  https://docs.brew.sh

簡単な手順でCloud9でもHomebrewを実行できるようになりました。

(4) tfenvをインストール

Terraformのバージョンを切り替えることができるtfenvをインストールします。
tfenvをインストールしていれば、新しいTerraformのバージョンがリリースされても、Cloud9上で旧バージョンのインストールを維持したまま、新バージョンを試すことができます。

$ brew install tfenv

(5) tfenvで利用できるTerraformのバージョンを確認

以下のコマンドで、tfenvを使ってインストールできるTerraformのバージョンを確認します。

$ tfenv list-remote

(6) tfenvでTerraformをインストール

最新のバージョンでインストールするには、以下のコマンドを実行します。

$ tfenv install latest

バージョンを指定する場合は、以下のコマンドに倣います。

$ tfenv install 0.11.13

(7) tfenvでTerraformのバージョンを選択

tfenvでバージョンを指定すると、terraformコマンドを実行した時に、指定したバージョンが使われるようになります。1つしかバージョンをインストールしていなくても、コマンドを実行する必要があります。

$ tfenv use latest

バージョンを指定する場合は、以下のコマンドに倣います。

$ tfenv use 0.11.13

(8) 動作確認

Terraformのバージョン確認コマンドを実行して、バージョンを表す文字列が返ることを確認します。

$ terraform --version
Terraform v0.12.0-beta2

これでCloud9でもTerraformが使えるようになりました。Cloud9をEC2モードで動かしている場合は、EC2にIAM Roleをアタッチすれば、TerraformでAWSのリソースを構築できるようになります。

2.Terraformで環境作成

(1) 今回作成する予定のディレクトリ構成

サンプルで作成したgithubをクローンして使ってみてください
https://github.com/sentail-yasu/knowledge-ecs-sample

開発環境でしか作らない想定だったので、以下の構成で作りました。
適宜変更してください

├── envs
│   ├── dev
│   │   ├── backend.tf
│   │   ├── main.tf
│   │   └── provider.tf
│   │   └── variables.t
├── acm.tf
├── ec2.tf
├── ecs.tf ←ここだけはこの章でで作らないように
├── lb.tf
├── network.tf
├── rds.tf
├── s3.tf
├── security_group.tf
└── variables.tf

(2) 定義作成

envs/dev/backend.tf

terraform {
  required_version = ">= 0.12"

  backend "s3" {
    bucket  = "tfstate-bucket" ←自分用のS3バケットを作成して変更
    region  = "ap-northeast-1"
    key     = "dev/terraform.tfstate" ←任意で変更
    encrypt = true
  }
}

envs/dev/main.tf

module "dev" {
  source             = "../../"

  vpc_cidr           = var.vpc_cidr
  subnet_cidr        = var.subnet_cidr
  name               = var.name
  rds_instance_class = var.rds_instance_class
  database_name      = var.database_name
  db_username        = var.db_username
  db_password        = var.db_password

  region             = var.region
  ami_id             = var.ami_id
  instance_count     = var.instance_count
  public_subnets     = var.public_subnets
  private_subnets    = var.private_subnets
  instance_type      = var.instance_type
  key_pair           = var.key_pair
  app_name           = var.app_name
  bastion_name       = var.bastion_name

}

envs/dev/provider.tf

provider "aws" {
  region  = "ap-northeast-1"
}

envs/dev/variables.tf

variable "vpc_cidr"{
  default = "10.1.0.0/16"
}

variable "subnet_cidr" {
  type = "map"

  default = {
    public-a  = "10.1.10.0/24"
    public-c  = "10.1.20.0/24"
    private-a = "10.1.100.0/24"
    private-c = "10.1.200.0/24"
  }
}

variable "name" {
  default = "knowledge"
}

variable "rds_instance_class" {
  default = "db.t2.small"
}
variable "database_name" {
  default = "knowledge"
}

variable "db_username" {
  default = "postgres"
}

variable "db_password" {}

variable "region" {
  default = "ap-northeast-1"
}

variable "ami_id" {
  default = "ami-0f310fced6141e627" ←AmazonLinux2 x86-64
}

variable "instance_count" {
  default = 2
}

variable "public_subnets" {
  default = {
    "0" = "subnet-xxxx" ←一回実行してサブネット作成後に手動で入れてください
    "1" = "subnet-xxxx" ←一回実行してサブネット作成後に手動で入れてください
  }
}
variable "private_subnets" {
  default = {
    "0" = "subnet-xxxx" ←一回実行してサブネット作成後に手動で入れてください
    "1" = "subnet-xxxx" ←一回実行してサブネット作成後に手動で入れてください
  }
}

variable "instance_type" {
  default = "t3.micro"
}

variable "key_pair" {
  default = "your key pair"
}

variable "app_name" {
  default = "web"
}

variable "bastion_name" {
  default = "bastion"
}

acm.tf

data aws_route53_zone route53-zone {
  name         = "your domain." ←自分で取得したドメインを入力
  private_zone = false
}

resource aws_acm_certificate cert {
  domain_name       = "www.your domain."
  validation_method = "DNS"
}

resource aws_route53_record cert_validation {
  zone_id = data.aws_route53_zone.route53-zone.zone_id
  name    = aws_acm_certificate.cert.domain_validation_options.0.resource_record_name
  type    = aws_acm_certificate.cert.domain_validation_options.0.resource_record_type
  records = [aws_acm_certificate.cert.domain_validation_options.0.resource_record_value]
  ttl     = 60
}

resource aws_acm_certificate_validation cert {
  certificate_arn = aws_acm_certificate.cert.arn
  validation_record_fqdns = [aws_route53_record.cert_validation.fqdn]
}

ec2.tf

resource "aws_instance" "bastion_ec2" {
  count                  = 1
  ami                    = var.ami_id
  instance_type          = var.instance_type
  key_name               = var.key_pair
  subnet_id              = lookup(var.public_subnets, count.index % 2)
  vpc_security_group_ids = ["${aws_security_group.bastion_security_group.id}"]

  tags = {
    Name = "${var.name}_${var.bastion_name}_${count.index + 1}"
  }
}

lb.tf

// albを作成。
resource "aws_alb" "alb" {
  name                       = "${var.name}-alb"
  security_groups            = ["${aws_security_group.alb.id}"]
  subnets = [
    "${aws_subnet.public-a.id}",
    "${aws_subnet.public-c.id}",
  ]
  internal                   = false
  enable_deletion_protection = false

  access_logs {
    bucket = "${var.name}-alb-logs-01"
  }
}

// albのターゲットグループ
resource "aws_alb_target_group" "alb" {
  name     = "${var.name}-tg"
  port     = 8080
  protocol = "HTTP"
  vpc_id   = aws_vpc.vpc.id
  target_type = "ip"

  health_check {
    interval            = 60
    path                = "/"
    // NOTE: defaultはtraffic-port
    //port                = 80
    protocol            = "HTTP"
    timeout             = 20
    unhealthy_threshold = 4
    matcher             = 302
  }
}

// 443ポートの設定。今回は事前にAWS Certificate Managerで作成済みの証明書を設定。
resource "aws_alb_listener" "alb_443" {
  load_balancer_arn = "${aws_alb.alb.arn}"
  port              = "443"
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-2015-05"
  certificate_arn   = "${aws_acm_certificate.cert.arn}"

  default_action {
    target_group_arn = "${aws_alb_target_group.alb.arn}"
    type             = "forward"
  }
}

resource "aws_alb_listener" "alb" {
  load_balancer_arn = "${aws_alb.alb.arn}"
  port              = "80"
  protocol          = "HTTP"

  default_action {
    target_group_arn = "${aws_alb_target_group.alb.arn}"
    type             = "forward"
  }
}

output "alb" {
  value = {
    dns_name         = "${aws_alb.alb.dns_name}"
    arn              = "${aws_alb.alb.arn}"
    target_group_arn = "${aws_alb_target_group.alb.arn}"
  }
}

network.tf

resource "aws_vpc" "vpc" {
  cidr_block           = var.vpc_cidr
  instance_tenancy     = "default"
  enable_dns_support   = true

  tags = {
    Name = "${var.name}-vpc"
  }
}

# EIP
resource "aws_eip" "nat" {
    vpc = true
}

# NatGateway
resource "aws_nat_gateway" "nat" {
  allocation_id = aws_eip.nat.id
  subnet_id = aws_subnet.public-a.id
}

# Subnet
resource "aws_subnet" "public-a" {
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = var.subnet_cidr["public-a"]
  map_public_ip_on_launch = true
  availability_zone = "ap-northeast-1a"

  tags = {
    Name = "public-subnet-1a"
  }
}

resource "aws_subnet" "public-c" {
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = var.subnet_cidr["public-c"]
  map_public_ip_on_launch = true
  availability_zone = "ap-northeast-1c"

  tags = {
    Name = "public-subnet-1c"
  }
}

resource "aws_subnet" "private-a" {
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = var.subnet_cidr["private-a"]
  availability_zone = "ap-northeast-1a"

  tags = {
    Name = "private-subunet-1a"
  }
}

resource "aws_subnet" "private-c" {
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = var.subnet_cidr["private-c"]
  availability_zone = "ap-northeast-1c"

  tags = {
    Name = "private-subunet-1c"
  }
}

# db_subnet_group
resource "aws_db_subnet_group" "db-subnet" {
    name = "db-subnet"
    description = "test db subnet"
    subnet_ids = ["${aws_subnet.private-a.id}", "${aws_subnet.private-c.id}"]
}

# Internet Gateway
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.vpc.id
  tags = {
    Name = "${var.name}-igw"
  }
}

# public Route Table
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.vpc.id
  tags = {
    Name = "${var.name}-rt"
  }
}

# public Route
resource "aws_route" "public_route" {
  gateway_id             = aws_internet_gateway.igw.id
  route_table_id         = aws_route_table.public.id
  destination_cidr_block = "0.0.0.0/0"
}

# パブリックルートテーブルとpublic-a関連付け
resource "aws_route_table_association" "public_a" {
    subnet_id      = aws_subnet.public-a.id
    route_table_id = aws_route_table.public.id
}

# パブリックルートテーブルとpublic-c関連付け
resource "aws_route_table_association" "public_c" {
    subnet_id      = aws_subnet.public-c.id
    route_table_id = aws_route_table.public.id
}

# private Route Table
resource "aws_route_table" "private" {
  vpc_id = aws_vpc.vpc.id
}

# private Route
resource "aws_route" "private_route" {
  nat_gateway_id             = aws_nat_gateway.nat.id
  route_table_id         = aws_route_table.private.id
  destination_cidr_block = "0.0.0.0/0"
}

# パブリックルートテーブルとprivate-a関連付け
resource "aws_route_table_association" "private-a" {
    subnet_id = aws_subnet.private-a.id
    route_table_id = aws_route_table.private.id
}

# パブリックルートテーブルとprivate-c関連付け
resource "aws_route_table_association" "private-c" {
    subnet_id = aws_subnet.private-c.id
    route_table_id = aws_route_table.private.id
}

output "vpc_id" {
  value = aws_vpc.vpc.id
}

output "subnet_public_a_id" {
  value = aws_subnet.public-a.id
}

output "subnet_public_c_id" {
  value = aws_subnet.public-c.id
}

output "subnet_private_a_id" {
  value = aws_subnet.private-a.id
}

output "subnet_private_c_id" {
  value = aws_subnet.private-c.id
}

rds.tf

resource "aws_db_parameter_group" "db-pg" {
    name = "knowledge"
    family = "postgres11.5"
    description = "knowledge"

    parameter {
        name = "log_min_duration_statement"
        value = "100"
    }
}

resource "aws_db_instance" "posgre" {
    identifier = "knowledge"
    allocated_storage = 10
    engine = "postgres"
    engine_version = "11.5"
    instance_class = var.rds_instance_class
    name = var.database_name
    username = var.db_username
    password = var.db_password
    db_subnet_group_name = "${aws_db_subnet_group.db-subnet.name}"
    vpc_security_group_ids = ["${aws_security_group.posgre_security_group.id}"]
    parameter_group_name = "${aws_db_parameter_group.db-pg.name}"
    multi_az = false
    backup_retention_period = "7"
    backup_window = "19:00-19:30"
    apply_immediately = "true"
    auto_minor_version_upgrade = false
}

output "rds_endpoint" {
    value = "${aws_db_instance.posgre.address}"
}

s3.tf

# プライベートバケットの定義
resource "aws_s3_bucket" "alb-logs" {
  # バケット名は世界で1意にしなければならない
  bucket = "${var.name}-alb-logs-01"

  versioning {
    enabled = true
  }

  # 暗号化を有効
  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

# ブロックパブリックアクセス
resource "aws_s3_bucket_public_access_block" "alb-logs" {
  bucket                  = aws_s3_bucket.alb-logs.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

security_group.tf

# RDSに設定するセキュリティグループ
resource "aws_security_group" "posgre_security_group" {
  name   = "${var.name}-posgre-sg"
  vpc_id = aws_vpc.vpc.id

  ingress {
    from_port       = "5432"
    to_port         = "5432"
    protocol        = "tcp"
    cidr_blocks     = ["10.1.0.0/16"]
  }

  egress {
      from_port      = 0
      to_port        = 0
      protocol       = "-1"
      cidr_blocks    = ["0.0.0.0/0"]
  }
  tags = {
    Name = "${var.name}-posgre-sg"
  }
}

resource "aws_security_group" "alb" {
  name   = "${var.name}-alb-sg"
  vpc_id = aws_vpc.vpc.id

  ingress {
    from_port       = "443"
    to_port         = "443"
    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"]
  }
  tags = {
    Name = "${var.name}-alb-sg"
  }
}

output "db_sg_id" {
  value = aws_security_group.posgre_security_group.id
}

# bastionに設定するセキュリティグループ
resource "aws_security_group" "bastion_security_group" {
  name   = "${var.name}-${var.bastion_name}-sg"
  vpc_id = aws_vpc.vpc.id

  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"]
  }

  tags = {
    Name = "${var.name}-${var.bastion_name}-sg"
  }
}

output "bastion_sg_id" {
  value = aws_security_group.bastion_security_group.id
}

# ecsに設定するセキュリティグループ
resource "aws_security_group" "ecs" {
  name   = "${var.name}-ecs-sg"
  vpc_id = aws_vpc.vpc.id

  ingress {
    from_port       = "8080"
    to_port         = "8080"
    protocol        = "tcp"
    cidr_blocks     = ["10.1.0.0/16"]
  }

  egress {
      from_port      = 0
      to_port        = 0
      protocol       = "-1"
      cidr_blocks    = ["0.0.0.0/0"]
  }
  tags = {
    Name = "${var.name}-ecs-sg"
  }
}

variables.tf

variable "vpc_cidr"{}
variable "subnet_cidr" {}
variable "name" {}
variable "rds_instance_class" {}
variable "database_name" {}
variable "db_username" {}
variable "db_password" {}

variable "region" {}
variable "ami_id" {}
variable "instance_count" {}
variable "public_subnets" {}
variable "private_subnets" {}
variable "instance_type" {}
variable "key_pair" {}
variable "app_name" {}
variable "bastion_name" {}

(3) Terraform実行

実行するディレクトリに移動後、Terraformで環境構築
※なぜかACMのところで1回目は失敗してしまうのですが、
 2回目の実行で成功します。
 以下の記事の方も同じ事象みたいです
 https://qiita.com/pokotyan/items/6a00b5cdfe8811b4c832

$ cd terraform/envs/dev
$ terraform init
$ terraform plan
$ terraform apply

3.ECRにイメージをアップロード

(1) 公式DockerからDockerイメージをダウンロード

以下のリポジトリをクローンする
https://github.com/support-project/docker-knowledge

(2) データベース接続先の変更

volumes/knowledge/custom_connection.xmlでDB接続先設定をカスタマイズできるようですので、作成したPostgreSQLの情報を使ってこのファイルを編集します。

変更後のイメージ

<connectionConfig>
        <name>custom</name>
        <driverClass>org.postgresql.Driver</driverClass>
        <URL>jdbc:postgresql://RDSのエンドポイント:ポート番号/DB名</URL> ←ここを変更
        <user>postgres</user>
        <password>mysql123</password>
        <schema>public</schema>
        <maxConn>0</maxConn>
        <autocommit>false</autocommit>
</connectionConfig>

(3) Dockerfile の編集

さきほど編集した custom_connection.xml が コンテナ起動時に適用されるようにします。

VOLUME [ "/root/.knowledge" ]
COPY ./volumes/knowledge/custom_connection.xml /root/.knowledge/ ←ここを追加
EXPOSE 8080

(4) ECRのリポジトリ作成

前提としてAWSコンソールにログインしてECRリポジトリを作成しておく

(5) ECRへログイン

aws ecr get-login --no-include-email --region ap-northeast-1 > login.sh
bash login.sh

(6) Docker Image の作成

docker build -t knowledge .

(7) タグ付け

docker tag knowledge:latest ECRのリポジトリ名/knowledge:latest

(8) プッシュ

docker push ECRのリポジトリ名/knowledge:latest

4.タスク定義作成

(1) task_definition.jsonを作成

$ vi  task_definition.json

以下の内容を環境に置き換えて作成

{
    "family": "sample",
    "executionRoleArn": "arn:aws:iam::自分の環境に変更:role/ecsTaskExecutionRole",
    "networkMode": "awsvpc",
    "containerDefinitions": [
        {
            "name": "knowledge",
            "image": "自分のECRのリポジトリ/knowledge:latest",
            "ulimits": [
                {
                    "name": "nofile",
                    "softLimit": 65536,
                    "hardLimit": 65536
                }
            ],
            "portMappings": [
                {
                    "protocol": "tcp",
                    "containerPort": 8080
                }
            ],
            "memoryReservation": 256,
            "essential": true,
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/knowledge",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "knowledge"
                }
            }
        }
    ],
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "cpu": "512",
    "memory": "2048"
}

(2) タスク定義作成

$ aws ecs register-task-definition --cli-input-json file://$PWD/task-definitions.json

5.Terraformでサービス作成

(1) 定義作成

ecs.tf

## cluster設定
resource "aws_ecs_cluster" "ecs_cluster" {
  name = "${var.name}-cluster"
}

resource "aws_ecs_service" "ecs" {
  name                               = "${var.name}-01"
  cluster                            = "${aws_ecs_cluster.ecs_cluster.id}"
  task_definition                    = "knowledge-fagate:1"
  desired_count                      = 2
  launch_type                        = "FARGATE"
  deployment_minimum_healthy_percent = 100
  deployment_maximum_percent         = 200

  network_configuration {
    subnets = [
        "${aws_subnet.private-a.id}",
        "${aws_subnet.private-c.id}"
    ]

    security_groups = [
      "${aws_security_group.ecs.id}"
    ]

    assign_public_ip = "false"
  }

  health_check_grace_period_seconds = 0

  load_balancer {
    target_group_arn = "${aws_alb_target_group.alb.arn}"
    container_name   = "knowledge"
    container_port   = 8080
  }

  scheduling_strategy = "REPLICA"

  deployment_controller {
    type = "CODE_DEPLOY"
  }
  // deployやautoscaleで動的に変化する値を差分だしたくないので無視する
  lifecycle {
    ignore_changes = [
      "desired_count",
      "task_definition",
      "load_balancer",
    ]
  }
  propagate_tags = "TASK_DEFINITION"
}

(2) オプトイン設定を定義

どうやらタスク定義はARNがオプトインの設定を変更しない場合、ARNが長すぎてエラーになってしまうため、以下の公式ドキュメントに従い、自分が使用しているIAMだけオプトイン設定を変更する。
https://aws.amazon.com/jp/blogs/compute/migrating-your-amazon-ecs-deployment-to-the-new-arn-and-resource-id-format-2/

(3) Terraform実行

$ cd terraform/envs/dev
$ terraform init
$ terraform plan
$ terraform apply

(4) 実行後確認

ECSのサービスが無事出来ていれば完璧

**

6.DBデータ移行

(1) 移行前のRDSにログインできるEC2にログイン

※割愛してますが、組み込みのKnowledgeのposgreにログインできなかったため、
 わざわざRDSを建て、GUIからDBの移行しました...

(2) postgresql11のインストール

こちらのpostgres環境はバージョン11であったため、
以下のコマンドでインストール実施

$ sudo rpm -ivh --nodeps https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
$ sed -i "s/\$releasever/7/g" "/etc/yum.repos.d/pgdg-redhat-all.repo"
$ sudo yum install -y postgresql11

(3) 以下のコマンドでdump取得

pg_dump -U ユーザ名 -h ホスト名 -p 5432 DB名 -f ファイル名.dump

(4) 移行後のRDSにログインできるEC2にログイン

(5) postgresql11のインストール

こちらのpostgres環境はバージョン11であったため、
以下のコマンドでインストール実施

$ sudo rpm -ivh --nodeps https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
$ sed -i "s/\$releasever/7/g" "/etc/yum.repos.d/pgdg-redhat-all.repo"
$ sudo yum install -y postgresql11

(6) 以下のコマンドでdumpから復元

なんか色々エラーが起きてたけど、無視しました...
そのせいなのかユーザが復元されませんでした

psql -U ユーザ名 -h ホスト名 -d データベース名 -p 5432 -f ファイル名.dump

(7) 画像を読み込めるように再度修正

なぜか画像が読み込めなくてなっていたので、
DBに直接ログインして以下のSQL文を発行する。
※正直ここは環境特有かも

UPDATE knowledges
SET content = REPLACE(content, '/knowledge/open.file/download?', '/open.file/download?');

以上で、移行完了です。

今後の課題

Terraformの実行もECRにイメージをアップするところも
手動でやってしまったので、CI/CDツールをもっと活かして自動化していきたいと思います。

1
3
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
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?