初心者がローカルのdockerをAWSにアップして動かすまで（その２）

# １．目標
ローカルPC（Windows 11 Home）のDocker Desktopで、WordPressを動かしています。
これをGitHubに登録し、AWSのCodePipelineでデプロイして、ECS Fagateで実行します。
※1. コンテンツは外部公開せず、あくまでも個人的な実験のために作成する（基本的にドメインを買ったりDNS登録したりしない）
※2. DBはRDS、ファイルはS3に保存する

これは四苦八苦しながら、目標達成まで頑張る初心者の作業記録です。
なお、ChatGPTをフル活用して、作業をガイドしてもらいます。
さあどうなるか……？！

★前回までの記事は以下
https://qiita.com/twilightdragonfly/items/9d2895cf8ee590198bc3

# ２．コンテナをイメージとして保存
前回の記事でWordPressのセッティングを行いました。
これをカスタムイメージとして保存し、AWS ECRにアップしたいと思います。
まずは、ローカルPCで作業中のdockerの状態を確認します。
```PowerShell:PowerShell
PS C:\Users\testuser> docker ps
```
コンテナが起動していなかったので、以下コマンドで起動します。
注意事項として、このコマンドはdocker-compose.ymlのあるフォルダで実行します。
```PowerShell:PowerShell
PS C:\Users\testuser\test_wordpress> docker-compose start
```
再度、コマンドを打って、現在の状態を確認します。
```PowerShell:PowerShell
PS C:\Users\testuser\test_wordpress> docker ps
CONTAINER ID   IMAGE                  COMMAND                   CREATED      STATUS                    PORTS                  NAMES
c2f3b347148d   wordpress:6.6-php8.1   "docker-entrypoint.s…"   6 days ago   Up 4 seconds              0.0.0.0:8082->80/tcp   wordpress-wp
919d27004852   mysql:8.0              "docker-entrypoint.s…"   6 days ago   Up 5 seconds              3306/tcp, 33060/tcp    wordpress-db
```

それでは、wordpress-wpコンテナのイメージを保存したいと思います。
```PowerShell:PowerShell
PS C:\Users\testuser\test_wordpress> docker commit wordpress-wp my-custom-wordpress:latest
```
ちなみに、DBはRDSに移行するつもりなので、必要なのはwordpress-wpコンテナだけです。
イメージを保存できたか、以下コマンドで確認します。
```PowerShell:PowerShell
PS C:\Users\testuser\test_wordpress> docker images
REPOSITORY            TAG          IMAGE ID       CREATED          SIZE
my-custom-wordpress   latest       7e7c8e0091dc   16 seconds ago   987MB
```

次は、このイメージをAWS ECRにアップしたいと思います。


# ３．Terraformインストール
すっかり申し遅れておりましたが、Terraformも使ってやろうと欲張りなことを考えていました。
以下URLからTerraformをダウンロードしてきました。
https://developer.hashicorp.com/terraform/install

①C:\Program Files\terraformに解凍して設置
②環境変数を編集する。「Path」に「C:\Program Files\terraform」を追加
③Powershellまたはコマンドプロンプトで以下コマンドを実行し、インストールされたことを確認する
```PowerShell:PowerShell
PS C:\Users\testuser> terraform -version
Terraform v1.9.8
on windows_amd64
```

# ４．ECRリポジトリ作成
TerraformでECRのリポジトリを作成します。
作業フォルダに、以下内容のmain.tfを保存しました。
```
provider "aws" {
  region = "ap-northeast-1" # 自分のリージョンを指定
}

# ECRリポジトリの作成
resource "aws_ecr_repository" "my_custom_wordpress" {
  name = "my-custom-wordpress"
  image_scanning_configuration {
    scan_on_push = true
  }
  tags = {
    Environment = "Practice"
  }
}

# ECRへのアクセス用IAMポリシー
resource "aws_iam_policy" "ecr_push_policy" {
  name        = "ECRPushPolicy"
  description = "Policy to allow pushing images to ECR"
  policy      = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect   = "Allow",
        Action   = [
          "ecr:GetAuthorizationToken",
          "ecr:BatchCheckLayerAvailability",
          "ecr:CompleteLayerUpload",
          "ecr:UploadLayerPart",
          "ecr:InitiateLayerUpload",
          "ecr:PutImage"
        ],
        Resource = "*"
      }
    ]
  })
}
```
次に以下コマンドを実行します。
```PowerShell:PowerShell
PS C:\Users\testuser> terraform init
```
すると「.terraform: The system cannot find the file specified.」エラー発生。
Windowsセキュリティによってブロックされたため、「ウイルスと脅威の防止」の履歴からterraform.exeを許可しました。
気を取り直して先に進みます。
```PowerShell:PowerShell
PS C:\Users\testuser> terraform plan
```
エラーが発生したのですが、要はAWSの権限足りないよというものだったので略させていただきます。
この後もたびたびAWSの権限が足りないと怒られました。最終的に追加したポリシーは以下になります。
```
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"ecr:CreateRepository",
				"ecr:DeleteRepository",
				"ecr:DescribeRepositories",
				"ecr:GetAuthorizationToken",
				"ecr:BatchCheckLayerAvailability",
				"ecr:BatchGetImage",
				"ecr:InitiateLayerUpload",
				"ecr:UploadLayerPart",
				"ecr:CompleteLayerUpload",
				"ecr:TagResource",
				"ecr:ListTagsForResource",
				"ecr:PutImage"
			],
			"Resource": "arn:aws:ecr:ap-northeast-1:xxxx:repository/*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"iam:CreatePolicy",
				"iam:AttachRolePolicy",
				"iam:GetPolicy",
				"iam:GetPolicyVersion",
				"iam:ListPolicyVersions",
				"iam:DeletePolicy",
				"iam:PassRole",
				"ecr:GetAuthorizationToken"
			],
			"Resource": "*"
		}
	]
}
```
iam:PassRoleアクションを許可するリソースをワイルドカード(*)で指定しているため、セキュリティがばがばです。
本番運用では怒られるため、作業の時だけ権限付与するようにします。
一案として、リソース変更権限を持つロールを用意して、本番作業時のみスイッチすることが考えられます。
なお、スイッチした瞬間にEventBridgeでCloudTrailのイベントを取得し、SNSで通知するようにすれば、企業が求めるセキュアな運用に沿うでしょう。

さて、以下コマンドでplanで確認したECRリポジトリを作成します。
※詰まったら「terraform plan」からやり直しになります。
```PowerShell:PowerShell
PS C:\Users\testuser> terraform apply
```
TerraformでAWSのリソースを作成することができました。

# ５．ECRにイメージをPUSH
Terraformで作成したECRリポジトリ名を利用し、AWS CLIを使ってログインします
```PowerShell:PowerShell
PS C:\Users\testuser> aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin AWSID.dkr.ecr.ap-northeast-1.amazonaws.com
```
※AWSIDは、自分のアカウントIDを入力します。
次に、Dockerイメージにタグを付与します。
```PowerShell:PowerShell
PS C:\Users\testuser> docker tag my-custom-wordpress:latest AWSID.dkr.ecr.ap-northeast-1.amazonaws.com/my-custom-wordpress:latest
```
いよいよ、イメージをECRにPUSHします！
```PowerShell:PowerShell
PS C:\Users\testuser> docker push AWSID.dkr.ecr.ap-northeast-1.amazonaws.com/my-custom-wordpress:latest
```
実行後「unexpected status from HEAD request to https://AWSID.dkr.ecr.ap-northeast-1.amazonaws.com/v2/my-custom-wordpress/manifests/latest: 403 Forbidden」なるエラーが。
どうやら、最後にアップしたイメージを取得するAWS権限が足りなかったようです。
（参考）https://qiita.com/1mono2/items/569ed58bd19db4b006f5
ここまでのエラー対応含め、調整したのが、前段で記載したポリシーになります。
これでECRにイメージをアップできました。

# ６．GitHubにファイルをアップ
docker-compose.ymlをGitHubにアップしたいと思います。
AWS CodeCommitがサービス終了していますので、GitHubまたはGitlabでコード管理する事になります。

ここまで作業して気付いたのですが、イメージをECRに置くのじゃなくて、GitHubに置いた方がまとめてファイル管理できますね。
しかし、GitHubのストレージ料金が発生しますし、今回の目標はCodePipelineでデプロイすることなので、ECRの方が連携しやすそうです。
ChatGPT先生を信じて、ECRで行きましょう。

Gitの基本コマンドはここでは触れません。
また、GitHubアカウント取得と初期設定も割愛させていただきます。
ファイルをアップするコマンドは、以下の通りです。
```
cd 作業ディレクトリ
git init
git add .
git commit -m "WordPress configuration"
git remote add origin https://github.com/ID/my-custom-wordpress.git
git push -u origin main
```
「error: src refspec main does not match any.」というエラーが発生しました。
現在のローカルリポジトリに main ブランチが存在しないために発生しているらしいです。
以下コマンドで、デフォルトのmasterブランチを、mainにリネームします。
```
git branch -M main
```

# ７．次のステップ
ChatGPT先生は以下のように教えてくれました。
１．ローカルでWordPressを起動し、プラグイン設定を完了。
２．設定済みの環境をDockerイメージとして保存。
３．RDS移行とともに、ECS（Fargate）にデプロイ。
４．デプロイ後にS3設定が有効な状態で運用開始。

今は上記の２が完了したところです。
またまた長くなりましたので、３以降は別ページに記載します。

　★続きのページを投稿したら、ここでご紹介します★