1
1

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.

AWS × Nuxt.js × Go で初めて自作 Web アプリ作ってみた

Last updated at Posted at 2021-02-06

はじめに

業務では普段Javaの独自フレームワークやSVN、Db2といったレガシー&ニッチな技術スタックで開発をしているため、新しい技術を自分で追っかけていたりするのですが、今回初めて使ってみたい技術を詰め込んで Web アプリを作ってみました。

記事を書くことにも不慣れなため、お見苦しい部分が多々あるかと思いますが、間違い等あればコメントいただけると泣いて喜びます。

使用した技術

言語

  • バックエンド(Go, Gin-Gonic)
  • フロントエンド(Nuxt.js)

インフラ

  • AWS(VPC, Route53, ALB, ACM, EKS, S3, CloudFront, CloudWatch)
  • コンテナ(Docker, docker-compose)
  • データベース(MySQL)
  • Kubernetes
  • Terraform
  • CI/CD(GitHub Actions)

ソースコードはこちら
※詳細は README.md にも載せています

アーキテクチャ図

構成図

ポイント解説

Terraform

初めはネットの記事をコピペして見様見真似で動かしていましたが、やはりちゃんと理解していないと問題が発生したときにドン詰まる。。

まずは、プロバイダーを定義する main.tf ファイルを用意します。
この場合、terraform の 0.12.9 バージョンを使用することになります。
「=」を「>=」にするとそのバージョン以上という意味になる。
※Terraform 0.12から構文が変わっているとのことなので、調査する時もバージョンをチェックすることを忘れないで。

main.tf
terraform {
  required_version = "= 0.12.9"
}

awsのバージョンやリージョンはこちらのprovider.tfで定義しています。

provider.tf
provider "aws" {
  version = "3.0"
  region  = var.region
  profile = var.aws_profile
}
provider "local" {
  version = "2.0.0"
}
provider "tls" {
  version = "3.0.0"
}

次に変数を定義する variables.tf を用意します。
よく使う値は変数にいれてここで定義しました。
AWS のクレデンシャル情報は直接記述せずに、~/.aws/credentials に定義してそれを参照するようにしました。

variables.tf
variable "region" {
  default = "us-east-1"
}

variable "aws_profile" {
  type        = string
  description = "AWSのプロファイル名"
  default     = "terraform-eks"
}

variable "project" {
  default = "eks"
}

variable "environment" {
  default = "dev"
}

variable "vpc_cidr_block" {
  default = "10.0.0.0/16"
}

variable "num_subnets" {
  default = 3
}

variable "key_name" {
  type    = "string"
  default = "ambitious_key"
}

locals {
  base_tags = {
    Project     = var.project
    Terraform   = "true"
    Environment = var.environment
  }

  default_tags    = merge(local.base_tags, map("kubernetes.io/cluster/${local.cluster_name}", "shared"))
  base_name       = "${var.project}-${var.environment}"
  cluster_name    = "${local.base_name}-amb-cluster"
  cluster_version = "1.18"

  public_key_file  = "./${var.key_name}.id_rsa.pub"
  private_key_file = "./${var.key_name}.id_rsa"
}

各AWSのリソースごとにtfファイルを定義します。
eksの場合は、kubeconfigとconfigmapをアウトプットするためにlocalに格納します。

eks.tf
locals {
  kubeconfig = <<KUBECONFIG
apiVersion: v1
clusters:
- cluster:
    server: ${aws_eks_cluster.eks-cluster.endpoint}
    certificate-authority-data: ${aws_eks_cluster.eks-cluster.certificate_authority.0.data}
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: aws
  name: aws
current-context: aws
kind: Config
preferences: {}
users:
- name: aws
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      command: aws-iam-authenticator
      args:
        - "token"
        - "-i"
        - "${local.cluster_name}"
KUBECONFIG

  eks_configmap = <<CONFIGMAPAWSAUTH
apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: ${aws_iam_role.eks-node-role.arn}
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes
CONFIGMAPAWSAUTH
}

resource "aws_eks_cluster" "eks-cluster" {
  name     = local.cluster_name
  role_arn = aws_iam_role.eks-master-role.arn
  version  = local.cluster_version

  vpc_config {
    security_group_ids     = [aws_security_group.cluster-master.id]
    subnet_ids             = aws_subnet.subnet.*.id
    endpoint_public_access = true
  }

  depends_on = [
    aws_iam_role_policy_attachment.eks-cluster-policy,
    aws_iam_role_policy_attachment.eks-service-policy,
  ]
}

resource "aws_eks_node_group" "eks-cluster-node-group" {
  cluster_name    = aws_eks_cluster.eks-cluster.name
  node_group_name = "eks-cluster-node-group"
  node_role_arn   = aws_iam_role.eks-node-role.arn
  subnet_ids      = aws_subnet.subnet.*.id

  scaling_config {
    desired_size = 1
    max_size     = 1
    min_size     = 1
  }
}

リソースファイルを全て定義し終えたら、デプロイします。


terraform plan
terraform apply

apply に成功したら terraform output の結果をそれぞれファイルに保存します。

EKS ConfigMap → manifests/config_map.yml
kubectl config → .kube/config

export KUBECONFIG='.kube/config'
kubectl apply -f manifests/config_map.yml

ノードがReadyになって居ることを確認する。

kubectl get nodes

まとめ

現在の会社では、Azureを使用するプロジェクトが多いため、どのクラウドでも同じように使えるTerraformを採用しました。
実装している時はトライアンドエラーで進めていましたが、applyとdestroyには結構時間がかかるため、必要な部分だけ動作をテストするみたいなことが上手くできればよかったなぁと、振り返って思いました。もう少し勉強は必要ですが、実務でも今後導入していく予定です。

残りのGo,AWS,Nuxt.jsについては、後々別記事に書きます。

参考

実装時はこちらの記事を参考にさせていただきました。

Terraform

5分で分かるTerraform(Infrastructure as Code)

TerraformでEKS環境を構築する

Terraformを使ってEKSを作成してみた

tfenvでTerraformのバージョン管理をする

Managed Node Groupsを用いてTerraformでEKSクラスタをシュッと構築する

Terraformを0.11から0.12に移行するときの注意点とは

Terraform職人入門: 日々の運用で学んだ知見を淡々とまとめる

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?