はじめに
まず、大前提として、ここから先は現在キャッチアップしているTerraformを使いながら、さまざまなコードを自分用に書いていきます。
※補足事項
そのため、内容は完全に自分向けとなっています。
また、このブログ投稿サイトのプラットフォームについても、自分自身の備忘録としてメモを残す場として活用していきたいと考えています。このプラットフォーム上に記録を積み重ねていく予定です。
あらかじめ、その点をご理解いただければ幸いです。
コード説明
本記事では、Terraform を使用して AWS 上にインフラを構築する手順を解説します。
具体的には、VPC、サブネット、インターネットゲートウェイ、NAT ゲートウェイ、ALB(Application Load Balancer)、ECS(Elastic Container Service)、RDS(Relational Database Service)を設定し、Fargate を利用したアプリケーションのデプロイを行います。
AWS プロバイダーの設定
まず、Terraform に AWS のプロバイダーを設定します。今回は東京リージョン(ap-northeast-1
)を使用します。
provider "aws" {
region = "ap-northeast-1"
}
VPC の作成
VPC(Virtual Private Cloud)は、AWS 内でリソースを管理するためのネットワーク環境です。
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = { Name = "Terraform-vpc" }
}
サブネットの作成
サブネットを作成し、適切に分割します。
resource "aws_subnet" "public1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.0.0/20"
availability_zone = "ap-northeast-1a"
tags = { Name = "Terraform-subnet-public1-ap-northeast-1a" }
}
このように、パブリックサブネットとプライベートサブネットを複数設定します。
インターネットゲートウェイの作成
インターネットと接続するために IGW(Internet Gateway)を設定します。
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = { Name = "Terraform-igw" }
}
ルートテーブルと NAT ゲートウェイ
パブリックサブネットには IGW を経由するルート、プライベートサブネットには NAT ゲートウェイを経由するルートを設定します。
resource "aws_route" "public_internet_access" {
route_table_id = aws_route_table.public.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
NAT ゲートウェイの設定:
resource "aws_nat_gateway" "public1" {
subnet_id = aws_subnet.public1.id
allocation_id = aws_eip.nat.id
tags = { Name = "Terraform-nat-public1-ap-northeast-1a" }
}
ECS クラスターの構築
Fargate で動作する ECS クラスターを構築します。
resource "aws_ecs_cluster" "main" {
name = "my-ecs-cluster"
}
タスク実行ロールを作成し、ECS タスクが AWS のサービスを利用できるようにします。
resource "aws_iam_role" "ecs_task_execution_role" {
name = "ecs-task-execution-role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Effect = "Allow",
Principal = { Service = "ecs-tasks.amazonaws.com" },
Action = "sts:AssumeRole"
}]
})
}
ECS サービスの定義
ECS のタスク定義を作成し、Fargate で動作するアプリケーションをデプロイします。
resource "aws_ecs_task_definition" "main" {
family = "Datadog"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = "256"
memory = "512"
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
task_role_arn = aws_iam_role.ecs_task_execution_role.arn
}
ALB(Application Load Balancer)の設定
ALB を作成し、ECS のアプリケーションを外部公開します。
resource "aws_lb" "main_alb" {
name = "terraform-main-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.public_sg.id]
subnets = [aws_subnet.public1.id, aws_subnet.public2.id]
}
ターゲットグループとリスナーの設定:
resource "aws_lb_target_group" "main_target_group" {
name = "terraform-main-target-group"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
target_type = "ip"
}
resource "aws_lb_listener" "http_listener" {
load_balancer_arn = aws_lb.main_alb.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08"
certificate_arn = var.acm_certificate_arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.main_target_group.arn
}
}
RDS(MySQL)の設定
データベース用の RDS を作成します。
resource "aws_db_instance" "rds_instance" {
allocated_storage = 20
engine = "mysql"
engine_version = "8.0.39"
instance_class = "db.t4g.micro"
username = "myuser"
password = jsondecode(data.aws_secretsmanager_secret_version.rds_password_v5.secret_string)["password"]
db_name = "mydatabase"
publicly_accessible = false
}
実際に完成したコード
# AWSプロバイダーの設定(東京リージョン)
provider "aws" {
region = "ap-northeast-1"
}
# ACM 証明書の ARN(外部入力用)
variable "acm_certificate_arn" {
default = "arn:aws:acm:ap-northeast-1:xxx"
description = "ARN of the ACM Certificate"
}
# VPC の定義
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "Terraform-vpc"
}
}
# パブリックサブネット(AZ: ap-northeast-1a)
resource "aws_subnet" "public1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.0.0/20"
availability_zone = "ap-northeast-1a"
tags = {
Name = "Terraform-subnet-public1-ap-northeast-1a"
}
}
# パブリックサブネット(AZ: ap-northeast-1c)
resource "aws_subnet" "public2" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.16.0/20"
availability_zone = "ap-northeast-1c"
tags = {
Name = "Terraform-subnet-public2-ap-northeast-1c"
}
}
# プライベートサブネット(AZ: ap-northeast-1a)
resource "aws_subnet" "private1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.128.0/20"
availability_zone = "ap-northeast-1a"
tags = {
Name = "Terraform-subnet-private1-ap-northeast-1a"
}
}
# プライベートサブネット(AZ: ap-northeast-1c)
resource "aws_subnet" "private2" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.144.0/20"
availability_zone = "ap-northeast-1c"
tags = {
Name = "Terraform-subnet-private2-ap-northeast-1c"
}
}
# プライベートサブネット(AZ: ap-northeast-1a, 別のCIDRブロック)
resource "aws_subnet" "private3" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.160.0/20"
availability_zone = "ap-northeast-1a"
tags = {
Name = "Terraform-subnet-private3-ap-northeast-1a"
}
}
# プライベートサブネット(AZ: ap-northeast-1c, 別のCIDRブロック)
resource "aws_subnet" "private4" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.176.0/20"
availability_zone = "ap-northeast-1c"
tags = {
Name = "Terraform-subnet-private4-ap-northeast-1c"
}
}
# インターネットゲートウェイ(IGW)の定義(VPC のインターネット接続用)
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "Terraform-igw"
}
}
# パブリックルートテーブルの定義(パブリックサブネット用のルートテーブル)
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
tags = {
Name = "Terraform-rtb-public"
}
}
# インターネットアクセス用のデフォルトルート(0.0.0.0/0 → IGW)
resource "aws_route" "public_internet_access" {
route_table_id = aws_route_table.public.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
# パブリックサブネットをルートテーブルに関連付け
resource "aws_route_table_association" "public1" {
subnet_id = aws_subnet.public1.id
route_table_id = aws_route_table.public.id
}
resource "aws_route_table_association" "public2" {
subnet_id = aws_subnet.public2.id
route_table_id = aws_route_table.public.id
}
# NAT ゲートウェイ用の Elastic IP(プライベートサブネットのインターネットアクセス用)
resource "aws_eip" "nat" {
tags = {
Name = "Terraform-eip-ap-northeast-1a"
}
}
# NAT ゲートウェイの定義(プライベートサブネットがインターネットにアクセスできるようにする)
resource "aws_nat_gateway" "public1" {
subnet_id = aws_subnet.public1.id
allocation_id = aws_eip.nat.id
tags = {
Name = "Terraform-nat-public1-ap-northeast-1a"
}
}
# プライベートルートテーブル(AZ: ap-northeast-1a)
resource "aws_route_table" "private1" {
vpc_id = aws_vpc.main.id
tags = {
Name = "Terraform-rtb-private1-ap-northeast-1a"
}
}
# プライベートルートの定義(NAT ゲートウェイ経由でインターネットアクセス)
resource "aws_route" "private1_nat_access" {
route_table_id = aws_route_table.private1.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.public1.id
}
# プライベートサブネットをルートテーブルに関連付け
resource "aws_route_table_association" "private1" {
subnet_id = aws_subnet.private1.id
route_table_id = aws_route_table.private1.id
}
# プライベートルートテーブル(AZ: ap-northeast-1c)
resource "aws_route_table" "private2" {
vpc_id = aws_vpc.main.id
tags = {
Name = "Terraform-rtb-private2-ap-northeast-1c"
}
}
# プライベートルートの定義(NAT ゲートウェイ経由でインターネットアクセス)
resource "aws_route" "private2_nat_access" {
route_table_id = aws_route_table.private2.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.public1.id
}
# プライベートサブネットをルートテーブルに関連付け
resource "aws_route_table_association" "private2" {
subnet_id = aws_subnet.private2.id
route_table_id = aws_route_table.private2.id
}
# プライベートルートテーブル(AZ: ap-northeast-1a, 別のサブネット用)
resource "aws_route_table" "private3" {
vpc_id = aws_vpc.main.id
tags = {
Name = "Terraform-rtb-private3-ap-northeast-1a"
}
}
# プライベートルート(AZ: ap-northeast-1a, NAT ゲートウェイ経由でインターネットアクセス)
resource "aws_route" "private3_nat_access" {
route_table_id = aws_route_table.private3.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.public1.id
}
# プライベートサブネットをルートテーブルに関連付け(AZ: ap-northeast-1a)
resource "aws_route_table_association" "private3" {
subnet_id = aws_subnet.private3.id
route_table_id = aws_route_table.private3.id
}
# プライベートルートテーブル(AZ: ap-northeast-1c, 別のサブネット用)
resource "aws_route_table" "private4" {
vpc_id = aws_vpc.main.id
tags = {
Name = "Terraform-rtb-private4-ap-northeast-1c"
}
}
# プライベートルート(AZ: ap-northeast-1c, NAT ゲートウェイ経由でインターネットアクセス)
resource "aws_route" "private4_nat_access" {
route_table_id = aws_route_table.private4.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.public1.id
}
# プライベートサブネットをルートテーブルに関連付け(AZ: ap-northeast-1c)
resource "aws_route_table_association" "private4" {
subnet_id = aws_subnet.private4.id
route_table_id = aws_route_table.private4.id
}
# ECS 用のセキュリティグループ(アプリケーションの通信を制御)
resource "aws_security_group" "ecs_sg" {
vpc_id = aws_vpc.main.id
# ALB からのリクエストを許可(ポート 1323)
ingress {
from_port = 1323
to_port = 1323
protocol = "tcp"
security_groups = [aws_security_group.public_sg.id]
}
# すべてのアウトバウンドトラフィックを許可
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "Terraform-private-instance-sg"
}
}
# CloudWatch Logs グループの作成
resource "aws_cloudwatch_log_group" "ecs_logs" {
name = "/ecs/datadog"
retention_in_days = 7 # ログの保持期間(必要に応じて変更)
}
# ECS クラスターの定義(Fargate でアプリを実行)
resource "aws_ecs_cluster" "main" {
name = "my-ecs-cluster"
}
# ECS タスク実行ロールの定義(ECS タスクが必要な AWS サービスにアクセスするための IAM ロール)
resource "aws_iam_role" "ecs_task_execution_role" {
name = "ecs-task-execution-role"
# ECS タスクがこのロールを引き受けるためのポリシー
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "ecs-tasks.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
# タスク実行に必要な AWS サービスへのアクセス許可
inline_policy {
name = "ecs-task-execution-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ecr:GetAuthorizationToken",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents",
"s3:GetObject"
]
Resource = "*"
}
]
})
}
}
# ECS タスク定義(Fargate で動作するコンテナの定義)
resource "aws_ecs_task_definition" "main" {
family = "Datadog"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = "256"
memory = "512"
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
task_role_arn = aws_iam_role.ecs_task_execution_role.arn # <-- 追加
volume {
name = "cws-instrumentation-volume"
}
container_definitions = jsonencode([
{
name = "cws-instrumentation-init"
image = "datadog/cws-instrumentation:latest"
essential = false
user = "0"
command = [
"/cws-instrumentation",
"setup",
"--cws-volume-mount",
"/cws-instrumentation-volume"
]
mountPoints = [
{
sourceVolume = "cws-instrumentation-volume"
containerPath = "/cws-instrumentation-volume"
readOnly = false
}
]
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = "/ecs/datadog"
awslogs-region = "ap-northeast-1"
awslogs-stream-prefix = "cws-instrumentation-init"
}
}
},
{
name = "datadog-agent"
image = "datadog/agent:latest"
essential = true
environment = [
{
name = "DD_API_KEY"
value = "xxx"
},
{
name = "DD_SITE"
value = "ap1.datadoghq.com"
},
{
name = "ECS_FARGATE"
value = "true"
},
# メトリクス収集(CPU・メモリ)を有効化
{
name = "DD_CONTAINER_METRICS_ENABLED"
value = "true"
},
# Process Monitoring を完全に無効化
{
name = "DD_PROCESS_AGENT_ENABLED"
value = "false"
},
{
name = "DD_PROCESS_CONFIG_ENABLED"
value = "false"
},
{
name = "DD_ORCHESTRATOR_EXPLORER_ENABLED"
value = "false"
},
{
name = "DD_SYSTEM_PROBE_ENABLED"
value = "false"
},
# APM, ログ, セキュリティ機能も無効化
{
name = "DD_LOGS_ENABLED"
value = "false"
},
{
name = "DD_APM_ENABLED"
value = "false"
},
{
name = "DD_TRACE_ENABLED"
value = "false"
},
{
name = "DD_SECURITY_AGENT_ENABLED"
value = "false"
},
{
name = "DD_RUNTIME_SECURITY_CONFIG_ENABLED"
value = "false"
},
{
name = "DD_RUNTIME_SECURITY_CONFIG_EBPFLESS_ENABLED"
value = "false"
}
]
healthCheck = {
command = ["CMD-SHELL", "/probe.sh"]
interval = 30
timeout = 5
retries = 2
startPeriod = 60
}
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = "/ecs/datadog"
awslogs-region = "ap-northeast-1"
awslogs-stream-prefix = "datadog-agent"
}
}
},
{
name = "my-app-repo"
image = "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-repo"
entryPoint = ["/server"] # `server` に変更
environment = [
# MySQL 環境変数
{
"name": "GO_ENV",
"value": "prod"
},
{
"name": "MYSQL_ROOT_PASSWORD",
"value": "xxx"
},
{
"name": "MYSQL_USER",
"value": "myuser"
},
{
"name": "MYSQL_PW",
"value": "${jsondecode(data.aws_secretsmanager_secret_version.rds_password_v5.secret_string)["password"]}"
},
{
"name": "MYSQL_HOST",
"value": "${aws_db_instance.rds_instance.address}"
},
{
"name": "MYSQL_PORT",
"value": "3306"
},
{
"name": "MYSQL_DB",
"value": "mydatabase"
},
# phpMyAdmin 環境変数
{
"name": "PMA_ARBITRARY",
"value": "1"
},
{
"name": "PMA_USER",
"value": "myuser"
},
{
"name": "PMA_PASSWORD",
"value": "root"
},
{
"name": "PMA_HOST",
"value": "dev-mysql"
},
{
"name": "PMA_PORT",
"value": "3306"
},
# Cognito 環境変数
{
"name": "COGNITO_USER_POOL_ID",
"value": "xxx"
},
{
"name": "COGNITO_CLIENT_ID",
"value": "XXX"
},
{
"name": "AWS_REGION",
"value": "ap-northeast-1"
},
# OpenAI APIキー
{
"name": "OPENAI_API_KEY",
"value": "XXX"
}
]
mountPoints = [
{
sourceVolume = "cws-instrumentation-volume"
containerPath = "/cws-instrumentation-volume"
readOnly = true
}
]
linuxParameters = {
capabilities = {
add = ["SYS_PTRACE"]
}
}
dependsOn = [
{
containerName = "datadog-agent"
condition = "HEALTHY"
},
{
containerName = "cws-instrumentation-init"
condition = "SUCCESS"
}
]
portMappings = [
{
containerPort = 1323
hostPort = 1323
protocol = "tcp"
}
]
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = "/ecs/datadog"
awslogs-region = "ap-northeast-1"
awslogs-stream-prefix = "my-app-repo"
}
}
}
])
}
# ECS サービスの定義(Fargate で実行し、プライベートサブネットに配置)
resource "aws_ecs_service" "main" {
name = "my-ecs-service"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.main.arn
desired_count = 1
launch_type = "FARGATE"
enable_execute_command = true # <-- 追加
# ネットワーク設定(プライベートサブネットで実行し、パブリック IP を付与しない)
network_configuration {
subnets = [aws_subnet.private1.id, aws_subnet.private2.id]
security_groups = [aws_security_group.ecs_sg.id]
assign_public_ip = false # パブリック IP を付与せず、NAT 経由で通信
}
# ALB との接続設定(ECS タスクを ALB に登録)
load_balancer {
target_group_arn = aws_lb_target_group.main_target_group.arn
container_name = "my-app-repo"
container_port = 1323
}
}
# パブリック(ALB)用セキュリティグループの定義(HTTPS トラフィックを許可)
resource "aws_security_group" "public_sg" {
vpc_id = aws_vpc.main.id
# インバウンドルール: HTTPS (443) の受信を全インターネットから許可
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 = "Terraform-public-sg"
}
}
# アプリケーションロードバランサー(ALB)の定義(パブリックアクセス可能な ALB)
resource "aws_lb" "main_alb" {
name = "terraform-main-alb"
internal = false # パブリック ALB
load_balancer_type = "application"
security_groups = [aws_security_group.public_sg.id] # ALB に適用するセキュリティグループ
subnets = [aws_subnet.public1.id, aws_subnet.public2.id] # ALB の配置サブネット
enable_deletion_protection = false # 削除保護を無効化
tags = {
Name = "terraform-main-alb"
}
}
# ターゲットグループの定義(ALB がリクエストを転送する先)
resource "aws_lb_target_group" "main_target_group" {
name = "terraform-main-target-group"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
target_type = "ip" # Fargate の場合は 'ip' に設定
# ヘルスチェックの設定(ALB が正常なターゲットを判断する)
health_check {
interval = 30
path = "/"
protocol = "HTTP"
timeout = 5
healthy_threshold = 3
unhealthy_threshold = 3
}
# セッション維持設定(ALB の負荷分散時にセッションを保持)
stickiness {
type = "lb_cookie"
enabled = true
cookie_duration = 86400
}
tags = {
Name = "terraform-main-target-group"
}
}
# ALB のリスナー設定(HTTPS リクエストをターゲットグループに転送)
resource "aws_lb_listener" "http_listener" {
load_balancer_arn = aws_lb.main_alb.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08"
certificate_arn = var.acm_certificate_arn # SSL 証明書の ARN を指定
# ターゲットグループへのリクエスト転送設定
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.main_target_group.arn
}
}
# RDS 用セキュリティグループ(データベースへのアクセスを制御)
resource "aws_security_group" "rds_sg" {
vpc_id = aws_vpc.main.id
# インバウンドルール: MySQL (3306) の接続を VPC 内のリソースから許可
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"]
}
# アウトバウンドルール: すべての通信を許可
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "Terraform-rds-sg"
}
}
# RDS 用サブネットグループの定義(RDS を配置するサブネットを指定)
resource "aws_db_subnet_group" "rds_subnet_group" {
name = "terraform-rds-subnet-group"
subnet_ids = [aws_subnet.private3.id, aws_subnet.private4.id]
tags = {
Name = "Terraform-rds-subnet-group"
}
}
# Secrets Manager を使用して RDS のパスワードを管理
resource "aws_secretsmanager_secret" "rds_password_v5" {
name = "rds_password_v5"
}
# Secrets Manager に保存する RDS のパスワード(初期設定)
resource "aws_secretsmanager_secret_version" "rds_password_version_v5" {
secret_id = aws_secretsmanager_secret.rds_password_v5.id
secret_string = jsonencode({ password = "mypassword123" })
}
# Secrets Manager から RDS のパスワードを取得
data "aws_secretsmanager_secret_version" "rds_password_v5" {
secret_id = aws_secretsmanager_secret.rds_password_v5.arn
depends_on = [aws_secretsmanager_secret_version.rds_password_version_v5]
}
# RDS インスタンスの定義(MySQL 8.0 を使用)
resource "aws_db_instance" "rds_instance" {
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "8.0.39"
instance_class = "db.t4g.micro"
username = "myuser" # 変更
password = jsondecode(data.aws_secretsmanager_secret_version.rds_password_v5.secret_string)["password"]
db_name = "mydatabase" # ← ここを追加
db_subnet_group_name = aws_db_subnet_group.rds_subnet_group.name
vpc_security_group_ids = [aws_security_group.rds_sg.id]
publicly_accessible = false
multi_az = false
tags = {
Name = "Terraform-rds-instance"
}
# 削除時の最終スナップショット作成をスキップ
skip_final_snapshot = true
}
まとめ
この記事は、自分用の備忘録としてまとめたものです。その点をご理解いただけると幸いです。
もし、この記事の内容が少しでも参考になれば嬉しく思います。
今後も同様の内容を継続して投稿していきますので、温かく見守っていただけるとありがたいです。
おまけ
独自ドメインでアクセスすると、ブラウザで以下のように表示されることを確認できます。