あめがえるのITブログ

頑張りすぎない。ほどほどに頑張るブログ。

AWS ALBでdualstackと書かれているものについて

Route53でALBと紐づくAliasレコードを作成しようとするとALB名の前にdualstackの記載があるので調べてみた。
※こんな感じ

ChatGPT様より

AWS Application Load Balancer (ALB) の Dualstack 機能は、IPv4IPv6 の両方のトラフィックをサポートするための機能です。この機能を有効にすると、ALBはIPv4IPv6アドレスの両方を使用してトラフィックを受信できるようになります。これにより、IPv6をサポートするクライアントからの接続が可能になり、より広範なユーザーへのアクセスが可能になります。

GUIを見ると無効になっているようだがRoute53では表示されるのはなぜ??


ChatGPT様より

AWS Route 53でAliasレコードを作成する際に、Dualstack エンドポイントが表示されるのは、AWSの標準動作の一部です。これは、Application Load Balancer (ALB) が Dualstack 機能をサポートしているため、Route 53では常に IPv4IPv6 の両方のトラフィックを処理できるエンドポイントとして dualstack の名前付きエンドポイントを提供します。

なぜDualstackエンドポイントが表示されるのか 互換性と将来の拡張性: たとえ現在 ALB で Dualstack が無効になっていても、Route 53 は将来的に IPv6 を使用する可能性を考慮して、Dualstack エンドポイントを提供します。 単純化された設定: ユーザーが後で ALB の Dualstack を有効にしたい場合、Alias レコードを変更する必要がなく、ALB での変更だけで済みます。 自動的な対応: Route 53 の Alias レコードが Dualstack エンドポイントを指している場合、ALB が Dualstack をサポートしているかどうかに関わらず、適切なトラフィックIPv4 または IPv6)を自動的に処理します。

( ̄д ̄)ふーん


感想

ChatGPT様ありがたや。

Linuxでrm -rf /を実行してみた

すべてを終わらせたくなったのでLinuxの禁断のコマンド(rm -rf /)を実行してみた。
※rm:ディレクトリ・ファイルを削除
※-r:再帰実行 ※ざっくり言うとサブディレクトリすべてに対して実行
※-f:強制
※/:ルートディレクトリ指定 ※Linuxディレクトリは/(ルート)から始まるのでトップを指定

※つまり、トップディレクトリから全ディレクトリに対して、強制的に削除を実行する。ということ。( ゚Д゚)ガクガク

やること

terraformでEC2を立てて、rm -rf /を実行する。

環境

ALB - EC2(Nginx)
※ALBいらないがいいサンプルがなかったのでこちらを使用

実践!

1.環境作成
1-1.tfファイルを作成

# vi main.tf
provider "aws" {
  region = "ap-northeast-1"
  profile = "testvault"
}

variable "env" {
  default = {
    env_name = "test"
    vpc_cidr = "10.0.0.0/16"
    sb_az1a = "ap-northeast-1a"
    sb_az1a_cidr = "10.0.1.0/24"
    sb_az1c = "ap-northeast-1c"
    sb_az1c_cidr = "10.0.2.0/24"
  }
}

### VPC
resource "aws_vpc" "vpc" {
    cidr_block = "${var.env.vpc_cidr}"
    tags = {
        Name = "${var.env.env_name}_vpc"
    }
}

### Subnet
resource "aws_subnet" "public_1a" {
  vpc_id = "${aws_vpc.vpc.id}"
  availability_zone = "${var.env.sb_az1a}"
  cidr_block        = "${var.env.sb_az1a_cidr}"
  tags = {
    Name = "${var.env.env_name}_public_1a"
  }
}

resource "aws_subnet" "public_1c" {
  vpc_id = "${aws_vpc.vpc.id}"
  availability_zone = "${var.env.sb_az1c}"
  cidr_block        = "${var.env.sb_az1c_cidr}"
  tags = {
    Name = "${var.env.env_name}_public_1c"
  }
}

### InternetGateway
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.vpc.id

  tags = {
    Name = "${var.env.env_name}_igw"
  }
}

### RouteTable
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }

  tags = {
    Name = "${var.env.env_name}_public_route_table"
  }
}

resource "aws_route_table_association" "public_1a" {
  subnet_id      = aws_subnet.public_1a.id
  route_table_id = aws_route_table.public.id
}

resource "aws_route_table_association" "public_1c" {
  subnet_id      = aws_subnet.public_1c.id
  route_table_id = aws_route_table.public.id
}

### SecurityGroup(ALB)
resource "aws_security_group" "example_alb_sg" {
  name        = "example_alb_sg"
  vpc_id      = aws_vpc.vpc.id
}

resource "aws_security_group_rule" "ingress_alb_http" {
  type        = "ingress"
  from_port   = 80
  to_port     = 80
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.example_alb_sg.id
}

resource "aws_security_group_rule" "egress_alb_all" {
  type        = "egress"
  from_port   = 0
  to_port     = 0
  protocol    = "-1"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.example_alb_sg.id
}

### SecurityGroup(EC2)
resource "aws_security_group" "example_ec2_sg" {
  name        = "example_ec2_sg"
  vpc_id      = aws_vpc.vpc.id
}

resource "aws_security_group_rule" "ingress_ec2_http" {
  type        = "ingress"
  from_port   = 80
  to_port     = 80
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.example_ec2_sg.id
}

resource "aws_security_group_rule" "ingress_ec2_ssh" {
  type        = "ingress"
  from_port   = 22
  to_port     = 22
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.example_ec2_sg.id
}

resource "aws_security_group_rule" "egress_ec2_all" {
  type        = "egress"
  from_port   = 0
  to_port     = 0
  protocol    = "-1"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.example_ec2_sg.id
}

### IAM Role(EC2)
resource "aws_iam_role" "example-ec2-ssm-role" {
  name               = "example-ec2-ssm-role"
  assume_role_policy = data.aws_iam_policy_document.example-ec2-assume-role.json
}

data "aws_iam_policy_document" "example-ec2-assume-role" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

data "aws_iam_policy" "example-ec2-policy_ssm_managed_instance_core" {
  arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

resource "aws_iam_role_policy_attachment" "example-ec2-ssm_managed_instance_core" {
  role       = aws_iam_role.example-ec2-ssm-role.name
  policy_arn = data.aws_iam_policy.example-ec2-policy_ssm_managed_instance_core.arn
}

resource "aws_iam_instance_profile" "example-ec2-profile" {
  name = "example-ec2-profile"
  role = aws_iam_role.example-ec2-ssm-role.name
}

### EC2
resource "aws_instance" "example" {
  ami           = "ami-06180cd4edb6844d2"
  instance_type = "t2.micro"
  subnet_id = aws_subnet.public_1a.id
  security_groups = [aws_security_group.example_ec2_sg.id]
  associate_public_ip_address = true
  iam_instance_profile = aws_iam_instance_profile.example-ec2-profile.name

  user_data = <<-EOF
                #!/bin/bash
                sudo yum update -y
                sudo amazon-linux-extras install epel -y
                sudo yum install nginx -y
                sudo systemctl start nginx
                sudo systemctl enable nginx
              EOF
              
  tags = {
    Name = "example-instance"
  }
}

### ALB
resource "aws_alb" "example" {
  name               = "example-lb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.example_alb_sg.id]
  subnets = [aws_subnet.public_1a.id, aws_subnet.public_1c.id]
  enable_deletion_protection = false

  enable_http2 = true
  idle_timeout = 60
  ip_address_type = "ipv4"

  enable_cross_zone_load_balancing = true
}

resource "aws_alb_listener" "front_end" {
  load_balancer_arn = aws_alb.example.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.example.arn
  }
}

### TargetGroup
resource "aws_alb_target_group" "example" {
  name     = "example-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.vpc.id
}

resource "aws_alb_target_group_attachment" "example" {
  target_group_arn = aws_alb_target_group.example.arn
  target_id        = aws_instance.example.id
}

1-2.作成

# terraform plan
# terraform apply


2.rm -rf /を実行
2-1.EC2へログイン
[AWS] - [EC2] - 作成したインスタンスを選択

[接続]

[接続]

2-2.下記コマンドを実行

# sudo su -
# rm -rf /


※やっぱり実行できないように制限がかかっている
※--no-preserve-rootオプションを使えば実行できそう。。。

やってみた。

※cannot remove?消えてない?

※コマンドが実行できなくなっている。
※消えないものも多いが一部は消えている模様。

※なんか怖いのでもうやめる。。。


感想

明日仕事やだな。

AWSで特定のタグを持つリソースを検索してみた

タグからリソースを検索する必要があったので方法を調べてみた。

やること

WebConsoleとコマンドから特定のタグを持つリソースを検索する。
※今回はap-northeast-1でキーがServiceTagKey、値がServiceTagValueを持つリソースを検索する。

実践!

1.WebConsole(GUI)で検索
1-1.[AWS] - [Resource Groups & Tag Editor] - [タグエディタ]を押下

1-2.下記を選択
 ・リージョン:ap-northeast-1
 ・リソースタイプ:All supported resource types ※これで全リソースから検索可能
 ・タグ(キー):ServiceTagKey
 ・タグ(値):ServiceTagValue
1-3.[リソースを検索]を押下し、検索したタグを持つリソースが出力されることを確認


2.コマンドライン(CLI)で検索
2-1.CloudShellから下記を実行

# aws resourcegroupstaggingapi get-resources --tag-filters Key=ServiceTagKey,Values=ServiceTagValue
{
    "ResourceTagMappingList": [
        {
            "ResourceARN": "arn:aws:ec2:ap-northeast-1:xxxxxxxxxxxx:network-interface/eni-09ec53ade2911c6fc",
            "Tags": [
                {
                    "Key": "ServiceTagKey",
                    "Value": "ServiceTagValue"
                },
                {
                    "Key": "aws:ecs:serviceName",
                    "Value": "test_my_service"
                },
                {
                    "Key": "aws:ecs:clusterName",
                    "Value": "test_my_cluster"
                }
            ]
        },
        {
            "ResourceARN": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task/test_my_cluster/1d0daa0b32ad43808274f757f71dcd74",
            "Tags": [
                {
                    "Key": "ServiceTagKey",
                    "Value": "ServiceTagValue"
                },
                {
                    "Key": "aws:ecs:serviceName",
                    "Value": "test_my_service"
                },
                {
                    "Key": "aws:ecs:clusterName",
                    "Value": "test_my_cluster"
                }
            ]
        },
        {
            "ResourceARN": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task/test_my_cluster/569e9353b0294059ae83375693009164",
            "Tags": [
                {
                    "Key": "ServiceTagKey",
                    "Value": "ServiceTagValue"
                },
                {
                    "Key": "aws:ecs:serviceName",
                    "Value": "test_my_service"
                },
                {
                    "Key": "aws:ecs:clusterName",
                    "Value": "test_my_cluster"
                }
            ]
        },
        {
            "ResourceARN": "arn:aws:ec2:ap-northeast-1:xxxxxxxxxxxx:network-interface/eni-0efb3571cc43e826c",
            "Tags": [
                {
                    "Key": "ServiceTagKey",
                    "Value": "ServiceTagValue"
                },
                {
                    "Key": "aws:ecs:serviceName",
                    "Value": "test_my_service"
                },
                {
                    "Key": "aws:ecs:clusterName",
                    "Value": "test_my_cluster"
                }
            ]
        },
        {
            "ResourceARN": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:service/test_my_cluster/test_my_service",
            "Tags": [
                {
                    "Key": "ServiceTagKey",
                    "Value": "ServiceTagValue"
                }
            ]
        }
    ]
}



感想

リソース名(Nameタグでなく)でも出力したいのだがないもんかな。。。( ̄д ̄)

AWS ECSの全サービスの詳細をCLI1行で取得してみた

ECSのサービスの詳細を取得する場合、Cluster名とService名を指定する必要があり、すべて取得するとなるとClusterでループしさらにServiceでもループさせて取得する必要がある。それぞれ実行してたら日が暮れるので1行でサクッと取れる方法を調べてみた。

ChatGPT様回答

※下記でよいとのこと。さすがChatGPT様。

# aws ecs list-clusters | jq -r '.clusterArns[]' | xargs -I {} sh -c "aws ecs list-services --cluster {} | jq -r '.serviceArns[]' | xargs -I {service} aws ecs describe-services --cluster {} --services {service}"


実践!

1.CloudShellで下記を実行

$ aws ecs list-clusters | jq -r '.clusterArns[]' | xargs -I {} sh -c "aws ecs list-services --cluster {} | jq -r '.serviceArns[]' | xargs -I {service} aws ecs describe-services --cluster {} --services {service}"

※取れた!下記は1つずつしかないが複数個あっても取れます。

{
    "services": [
        {
            "serviceArn": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:service/test_my_cluster/test_my_service",
            "serviceName": "test_my_service",
            "clusterArn": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:cluster/test_my_cluster",
            "loadBalancers": [],
            "serviceRegistries": [],
            "status": "ACTIVE",
            "desiredCount": 2,
            "runningCount": 2,
            "pendingCount": 0,
            "launchType": "FARGATE",
            "platformVersion": "LATEST",
            "platformFamily": "Linux",
            "taskDefinition": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/test_my_task:3",
            "deploymentConfiguration": {
                "deploymentCircuitBreaker": {
                    "enable": false,
                    "rollback": false
                },
                "maximumPercent": 200,
                "minimumHealthyPercent": 100
            },
            "deployments": [
                {
                    "id": "ecs-svc/2828737226229126325",
                    "status": "PRIMARY",
                    "taskDefinition": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/test_my_task:3",
                    "desiredCount": 2,
                    "pendingCount": 0,
                    "runningCount": 2,
                    "failedTasks": 0,
                    "createdAt": "2023-11-10T07:14:37.901000+00:00",
                    "updatedAt": "2023-11-10T07:15:14.781000+00:00",
                    "launchType": "FARGATE",
                    "platformVersion": "1.4.0",
                    "platformFamily": "Linux",
                    "networkConfiguration": {
                        "awsvpcConfiguration": {
                            "subnets": [
                                "subnet-0e71a0ea85a43e175",
                                "subnet-01d7fc3fec309c469"
                            ],
                            "securityGroups": [
                                "sg-0dd54db1f11572af9"
                            ],
                            "assignPublicIp": "ENABLED"
                        }
                    },
                    "rolloutState": "COMPLETED",
                    "rolloutStateReason": "ECS deployment ecs-svc/2828737226229126325 completed."
                }
            ],
            "roleArn": "arn:aws:iam::xxxxxxxxxxxx:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",
            "events": [
                {
                    "id": "b16689fb-9656-4144-9e75-a3ff30d8a139",
                    "createdAt": "2023-11-10T07:15:14.789000+00:00",
                    "message": "(service test_my_service) has reached a steady state."
                },
                {
                    "id": "d2bd8853-661e-4eb8-9ff7-9d3b46a38691",
                    "createdAt": "2023-11-10T07:15:14.788000+00:00",
                    "message": "(service test_my_service) (deployment ecs-svc/2828737226229126325) deployment completed."
                },
                {
                    "id": "0d319851-b6a1-4021-9aa9-f5f3b5d78ae2",
                    "createdAt": "2023-11-10T07:14:44.698000+00:00",
                    "message": "(service test_my_service) has started 2 tasks: (task 166f6247d2bd4d6797b7d024ee6babbe) (task 5af0639671cd40fcb5c334fd9208eba0)."
                }
            ],
            "createdAt": "2023-11-10T07:14:37.901000+00:00",
            "placementConstraints": [],
            "placementStrategy": [],
            "networkConfiguration": {
                "awsvpcConfiguration": {
                    "subnets": [
                        "subnet-0e71a0ea85a43e175",
                        "subnet-01d7fc3fec309c469"
                    ],
                    "securityGroups": [
                        "sg-0dd54db1f11572af9"
                    ],
                    "assignPublicIp": "ENABLED"
                }
            },
            "schedulingStrategy": "REPLICA",
            "deploymentController": {
                "type": "ECS"
            },
            "createdBy": "arn:aws:iam::xxxxxxxxxxxx:user/vaultuser",
            "enableECSManagedTags": true,
            "propagateTags": "SERVICE",
            "enableExecuteCommand": false
        }
    ],
    "failures": []
}



感想

Bashを覚えると他を忘れるという、、、もっと頭よくなりたい。。。

AWS ECSのタスクにタグを伝搬してみた



タスクのコスト管理などにタグをつけたい場合があるが、デフォルトではタグが付かないので設定を入れる必要がある。
※こんな感じ

やること

TerraformでECS(Fargate)環境を作成し、サービスとタスク定義にタグをつけ、それぞれ伝搬させてタスクにタグが伝搬されるか確認する。

実践!

1.下記を参考にECS環境を作成する。
amegaeru.hatenablog.jp
2.タグ伝搬設定
2-1.terraformに下記を追加

### TaskDefinitionに下記を追加
  tags = {
    "Name"        = "example-task"
    "Environment" = "Production"
  }

### Serviceに下記を追加
  tags = {
    ServiceTagKey = "ServiceTagValue"
  }

  enable_ecs_managed_tags = true
  propagate_tags = "TASK_DEFINITION"

2-2.適用

# terraform apply


3.タスク更新
3-1.[ECS] - [Cluster] - [test_my_cluster] を押下

3-2.[test_my_service]を押下

3-3.[サービスを更新]を押下

3-4.[新しいデプロイを強制]にチェック

3-5.[更新]を押下


4.タグ確認
4-1.[タスク]タブを選択し、新たに作成されたタスクを選択

4-2.タスク定義のタグが伝搬されていることを確認


5.サービスからの伝搬に変更しタグ確認
5-1.Terraformコードを下記に変更

変更前)propagate_tags = "TASK_DEFINITION"
変更後)propagate_tags = "SERVICE"

5-2.適用

# terraform

5-3.項番3を実施
5-4.項番4を実施し、サービスのタグが伝搬されていることを確認

6.設定確認
GUIでは確認できないので、CLIで確認する

# aws ecs describe-services --cluster test_my_cluster --service test_my_service
{
    "services": [
        {
            "serviceArn": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:service/test_my_cluster/test_my_service",
            "serviceName": "test_my_service",
            "clusterArn": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:cluster/test_my_cluster",
            "loadBalancers": [],
            "serviceRegistries": [],
            "status": "ACTIVE",
            "desiredCount": 2,
            "runningCount": 2,
            "pendingCount": 0,
            "launchType": "FARGATE",
            "platformVersion": "LATEST",
            "platformFamily": "Linux",
            "taskDefinition": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/test_my_task:2",
            "deploymentConfiguration": {
                "deploymentCircuitBreaker": {
                    "enable": false,
                    "rollback": false
                },
                "maximumPercent": 200,
                "minimumHealthyPercent": 100
            },
            "deployments": [
                {
                    "id": "ecs-svc/4585009772463196880",
                    "status": "PRIMARY",
                    "taskDefinition": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/test_my_task:2",
                    "desiredCount": 2,
                    "pendingCount": 0,
                    "runningCount": 2,
                    "failedTasks": 0,
                    "createdAt": "2023-11-09T12:00:02.488000+00:00",
                    "updatedAt": "2023-11-09T12:03:12.223000+00:00",
                    "launchType": "FARGATE",
                    "platformVersion": "1.4.0",
                    "platformFamily": "Linux",
                    "networkConfiguration": {
                        "awsvpcConfiguration": {
                            "subnets": [
                                "subnet-07e57870668086b8d",
                                "subnet-07de7490b4eb4ac28"
                            ],
                            "securityGroups": [
                                "sg-08189946c15738aae"
                            ],
                            "assignPublicIp": "ENABLED"
                        }
                    },
                    "rolloutState": "COMPLETED",
                    "rolloutStateReason": "ECS deployment ecs-svc/4585009772463196880 completed."
                }
            ],
            "roleArn": "arn:aws:iam::xxxxxxxxxxxx:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",
            "events": [
                {
                    "id": "e474c982-7ec5-4adf-a819-41d19b261351",
                    "createdAt": "2023-11-09T12:03:12.231000+00:00",
                    "message": "(service test_my_service) has reached a steady state."
                },
                {
                    "id": "bdac6b90-0aee-4003-bf33-6526eb1e184a",
                    "createdAt": "2023-11-09T12:03:12.230000+00:00",
                    "message": "(service test_my_service) (deployment ecs-svc/4585009772463196880) deployment completed."
                },
                {
                    "id": "8a515cca-a02d-4414-8c98-713d12b684d0",
                    "createdAt": "2023-11-09T12:01:40.629000+00:00",
                    "message": "(service test_my_service) has stopped 2 running tasks: (task a1c1c765c65943fbb1f3e327cdb44c0e) (task 015212dd06bc4e369ef96837d2782b6a)."
                },
                {
                    "id": "b43b8358-4aaf-4f17-ab84-4b738a022cbf",
                    "createdAt": "2023-11-09T12:00:19.061000+00:00",
                    "message": "(service test_my_service) has started 2 tasks: (task 3ecf5e6e342544fcbeb983a00b2e6721) (task c2ecbb3d9dd94634a4a5ca62157ec298)."
                },
                {
                    "id": "f25855cb-445c-44ba-b770-873641ec1c4c",
                    "createdAt": "2023-11-09T11:27:52.929000+00:00",
                    "message": "(service test_my_service) has reached a steady state."
                },
                {
                    "id": "45228bd3-af38-48a3-9577-d20cc0d26926",
                    "createdAt": "2023-11-09T11:27:52.928000+00:00",
                    "message": "(service test_my_service) (deployment ecs-svc/1804178643143848991) deployment completed."
                },
                {
                    "id": "620b5c3e-94b4-403a-a6a3-520c1c2ccb80",
                    "createdAt": "2023-11-09T11:26:53.884000+00:00",
                    "message": "(service test_my_service) has stopped 2 running tasks: (task d73aa4a66d41462c9bda352c9d888512) (task bd727d24d56a4585b3123d19e31be1a4)."
                },
                {
                    "id": "67782c26-c27f-45d0-8a68-5d23e0227dcb",
                    "createdAt": "2023-11-09T11:25:40.600000+00:00",
                    "message": "(service test_my_service) has started 2 tasks: (task 015212dd06bc4e369ef96837d2782b6a) (task a1c1c765c65943fbb1f3e327cdb44c0e)."
                },
                {
                    "id": "99488bda-57ca-4088-ae2a-707db4a481ac",
                    "createdAt": "2023-11-09T11:23:36.513000+00:00",
                    "message": "(service test_my_service) has reached a steady state."
                },
                {
                    "id": "8407cdd3-1adc-4712-91c1-ad9a58aec04c",
                    "createdAt": "2023-11-09T11:23:36.512000+00:00",
                    "message": "(service test_my_service) (deployment ecs-svc/2246503820580644060) deployment completed."
                },
                {
                    "id": "6b9a85ab-5c09-4167-9783-e6cd1093dbc9",
                    "createdAt": "2023-11-09T11:22:13.933000+00:00",
                    "message": "(service test_my_service) has stopped 2 running tasks: (task ef71f61e777945179bde60c810cb356c) (task 9234724d9df34a878960a9edad786b18)."
                },
                {
                    "id": "fade1152-e3de-41a6-a3ac-dfb8452cf32a",
                    "createdAt": "2023-11-09T11:21:03.337000+00:00",
                    "message": "(service test_my_service) has started 2 tasks: (task bd727d24d56a4585b3123d19e31be1a4) (task d73aa4a66d41462c9bda352c9d888512)."
                },
                {
                    "id": "36fa0e83-48f1-42e4-850e-8aa3c59ddf53",
                    "createdAt": "2023-11-09T11:20:41.411000+00:00",
                    "message": "(service test_my_service) has started 2 tasks: (task 9234724d9df34a878960a9edad786b18) (task ef71f61e777945179bde60c810cb356c)."
                },
                {
                    "id": "4bd549c4-bdea-4ea2-bf11-c87f769b1f7a",
                    "createdAt": "2023-11-09T11:12:56.255000+00:00",
                    "message": "(service test_my_service) has reached a steady state."
                },
                {
                    "id": "4f0d0ba5-6b17-4759-9c1a-c7cdfcf98c87",
                    "createdAt": "2023-11-09T11:12:56.254000+00:00",
                    "message": "(service test_my_service) (deployment ecs-svc/2241376552719585905) deployment completed."
                },
                {
                    "id": "e15f792d-3f1c-4249-a2ca-464d54021366",
                    "createdAt": "2023-11-09T11:12:28.285000+00:00",
                    "message": "(service test_my_service) has started 2 tasks: (task 6734ffc09f0f47b883e04df2a511f189) (task c59eae0b798b4c2d8e61b47cd928b9f9)."
                }
            ],
            "createdAt": "2023-11-09T11:12:22.106000+00:00",
            "placementConstraints": [],
            "placementStrategy": [],
            "networkConfiguration": {
                "awsvpcConfiguration": {
                    "subnets": [
                        "subnet-07e57870668086b8d",
                        "subnet-07de7490b4eb4ac28"
                    ],
                    "securityGroups": [
                        "sg-08189946c15738aae"
                    ],
                    "assignPublicIp": "ENABLED"
                }
            },
            "schedulingStrategy": "REPLICA",
            "deploymentController": {
                "type": "ECS"
            },
            "createdBy": "arn:aws:iam::xxxxxxxxxxxx:user/vaultuser",
            "enableECSManagedTags": true, ## ここから確認
            "propagateTags": "SERVICE",  ## ここから確認
            "enableExecuteCommand": false
        }
    ],
    "failures": []
}




感想

ECS奥が深いねぇ(´Д`)

TerraformでAPI GatewayとLambdaの構成を作成してみた

やること

terraformでAPI Gateway+Lambdaの構成を作成する。

構成

ブラウザ ⇒ APIGateway ⇒ Lambda(Python)

実践

1.Pythonコード作成

# vi lambda_function.py
import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
# zip lambda_function.py


2.環境構築
2-1.terraformコード作成

# vi main.tf
provider "aws" {
  region = "ap-northeast-1"
}

## Lambda関数
resource "aws_lambda_function" "example" {
  function_name = "example_lambda_function"
  runtime       = "python3.8"
  handler       = "lambda_function.lambda_handler"

  filename = "lambda_function.zip"

  role = aws_iam_role.lambda_exec.arn
}

## Lambdaロール
resource "aws_iam_role" "lambda_exec" {
  name = "lambda_exec_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = "sts:AssumeRole",
        Effect = "Allow",
        Principal = {
          Service = "lambda.amazonaws.com"
        },
      },
    ],
  })
}

## APIGateway
resource "aws_api_gateway_rest_api" "example" {
  name        = "ExampleAPI"
  description = "Example API"
}

resource "aws_api_gateway_resource" "example" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  parent_id   = aws_api_gateway_rest_api.example.root_resource_id
  path_part   = "examplepath"
}

resource "aws_api_gateway_method" "example" {
  rest_api_id   = aws_api_gateway_rest_api.example.id
  resource_id   = aws_api_gateway_resource.example.id
  http_method   = "GET"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "example" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  resource_id = aws_api_gateway_resource.example.id
  http_method = aws_api_gateway_method.example.http_method

  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.example.invoke_arn
}

resource "aws_api_gateway_deployment" "example" {
  depends_on = [aws_api_gateway_integration.example]

  rest_api_id = aws_api_gateway_rest_api.example.id
  stage_name  = "test"
}

resource "aws_lambda_permission" "api_gateway" {
  statement_id  = "AllowAPIGatewayInvoke"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.example.function_name
  principal     = "apigateway.amazonaws.com"

  source_arn = "${aws_api_gateway_rest_api.example.execution_arn}/*/*/*"
}

2-2.terraform実行

# terraform plan
# terraform apply


3.動作確認
3-1.接続URL確認
[API Gateway] - 作成されたAPIを押下

[ステージ]を押下

[test]横の+を展開

[GET]を押下し、[URLを呼び出す]のURLを確認


3-2.接続確認
ブラウザでアクセスし、[Hello from Lambda!]が表示されることを確認

ついでにCurlコマンドでも確認

# curl https://bw9jnqmaxa.execute-api.ap-northeast-1.amazonaws.com/test/examplepath
StatusCode        : 200
StatusDescription : OK
Content           : "Hello from Lambda!"
RawContent        : HTTP/1.1 200 OK
                    Connection: keep-alive
                    x-amzn-RequestId: 2553b9b7-6d98-4e54-a1db-fddd38eaf553
                    x-amz-apigw-id: NgMdaE4ktjMEIyw=
                    X-Amzn-Trace-Id: Root=1-653cc122-611f384b1e9780c6624df265;Sample 
                    d=0;l...
Forms             : {}
Headers           : {[Connection, keep-alive], [x-amzn-RequestId, 2553b9b7-6d98-4e54 
                    -a1db-fddd38eaf553], [x-amz-apigw-id, NgMdaE4ktjMEIyw=], [X-Amzn 
                    -Trace-Id, Root=1-653cc122-611f384b1e9780c6624df265;Sampled=0;li 
                    neage=f3c5689d:0]...}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 20



感想

terraformは扱いやすくてよいねー(´Д`)

AWS WAF+ALB+EC2の環境を作成し、WAFでIPブロックを設定してみた


WAFを使った環境構築案件が増えそうなのでお勉強してみた。

やること

terraformでWAF+ALB+EC2の環境を作成し、その後接続元のIPを制限する設定を入れ挙動を確認する。

環境

接続元 ⇒ AWS WAF ⇒ ALB ⇒ EC2(Nginx)

実践!

1.環境作成

# vi main.tf
provider "aws" {
  region = "ap-northeast-1"
  profile = "testvault"
}

variable "env" {
  default = {
    env_name = "test"
    vpc_cidr = "10.0.0.0/16"
    sb_az1a = "ap-northeast-1a"
    sb_az1a_cidr = "10.0.1.0/24"
    sb_az1c = "ap-northeast-1c"
    sb_az1c_cidr = "10.0.2.0/24"
  }
}

### VPC
resource "aws_vpc" "vpc" {
    cidr_block = "${var.env.vpc_cidr}"
    tags = {
        Name = "${var.env.env_name}_vpc"
    }
}

### Subnet
resource "aws_subnet" "public_1a" {
  vpc_id = "${aws_vpc.vpc.id}"
  availability_zone = "${var.env.sb_az1a}"
  cidr_block        = "${var.env.sb_az1a_cidr}"
  tags = {
    Name = "${var.env.env_name}_public_1a"
  }
}

resource "aws_subnet" "public_1c" {
  vpc_id = "${aws_vpc.vpc.id}"
  availability_zone = "${var.env.sb_az1c}"
  cidr_block        = "${var.env.sb_az1c_cidr}"
  tags = {
    Name = "${var.env.env_name}_public_1c"
  }
}

### InternetGateway
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.vpc.id

  tags = {
    Name = "${var.env.env_name}_igw"
  }
}

### RouteTable
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }

  tags = {
    Name = "${var.env.env_name}_public_route_table"
  }
}

resource "aws_route_table_association" "public_1a" {
  subnet_id      = aws_subnet.public_1a.id
  route_table_id = aws_route_table.public.id
}

resource "aws_route_table_association" "public_1c" {
  subnet_id      = aws_subnet.public_1c.id
  route_table_id = aws_route_table.public.id
}

### SecurityGroup(ALB)
resource "aws_security_group" "example_alb_sg" {
  name        = "example_alb_sg"
  vpc_id      = aws_vpc.vpc.id
}

resource "aws_security_group_rule" "ingress_alb_http" {
  type        = "ingress"
  from_port   = 80
  to_port     = 80
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.example_alb_sg.id
}

resource "aws_security_group_rule" "egress_alb_all" {
  type        = "egress"
  from_port   = 0
  to_port     = 0
  protocol    = "-1"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.example_alb_sg.id
}

### SecurityGroup(EC2)
resource "aws_security_group" "example_ec2_sg" {
  name        = "example_ec2_sg"
  vpc_id      = aws_vpc.vpc.id
}

resource "aws_security_group_rule" "ingress_ec2_http" {
  type        = "ingress"
  from_port   = 80
  to_port     = 80
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.example_ec2_sg.id
}

resource "aws_security_group_rule" "ingress_ec2_ssh" {
  type        = "ingress"
  from_port   = 22
  to_port     = 22
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.example_ec2_sg.id
}

resource "aws_security_group_rule" "egress_ec2_all" {
  type        = "egress"
  from_port   = 0
  to_port     = 0
  protocol    = "-1"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.example_ec2_sg.id
}

### IAM Role(EC2)
resource "aws_iam_role" "example-ec2-ssm-role" {
  name               = "example-ec2-ssm-role"
  assume_role_policy = data.aws_iam_policy_document.example-ec2-assume-role.json
}

data "aws_iam_policy_document" "example-ec2-assume-role" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

data "aws_iam_policy" "example-ec2-policy_ssm_managed_instance_core" {
  arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

resource "aws_iam_role_policy_attachment" "example-ec2-ssm_managed_instance_core" {
  role       = aws_iam_role.example-ec2-ssm-role.name
  policy_arn = data.aws_iam_policy.example-ec2-policy_ssm_managed_instance_core.arn
}

resource "aws_iam_instance_profile" "example-ec2-profile" {
  name = "example-ec2-profile"
  role = aws_iam_role.example-ec2-ssm-role.name
}

### EC2
resource "aws_instance" "example" {
  ami           = "ami-06180cd4edb6844d2"
  instance_type = "t2.micro"
  subnet_id = aws_subnet.public_1a.id
  security_groups = [aws_security_group.example_ec2_sg.id]
  associate_public_ip_address = true
  iam_instance_profile = aws_iam_instance_profile.example-ec2-profile.name

  user_data = <<-EOF
                #!/bin/bash
                sudo yum update -y
                sudo amazon-linux-extras install epel -y
                sudo yum install nginx -y
                sudo systemctl start nginx
                sudo systemctl enable nginx
              EOF
              
  tags = {
    Name = "example-instance"
  }
}

### ALB
resource "aws_alb" "example" {
  name               = "example-lb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.example_alb_sg.id]
  subnets = [aws_subnet.public_1a.id, aws_subnet.public_1c.id]
  enable_deletion_protection = false

  enable_http2 = true
  idle_timeout = 60
  ip_address_type = "ipv4"

  enable_cross_zone_load_balancing = true
}

resource "aws_alb_listener" "front_end" {
  load_balancer_arn = aws_alb.example.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.example.arn
  }
}

### TargetGroup
resource "aws_alb_target_group" "example" {
  name     = "example-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.vpc.id
}

resource "aws_alb_target_group_attachment" "example" {
  target_group_arn = aws_alb_target_group.example.arn
  target_id        = aws_instance.example.id
}

### WAF
resource "aws_wafv2_web_acl" "example" {
  name        = "example-waf"
  description = "Example WAF for ALB"
  scope       = "REGIONAL"

  default_action {
    allow {}
  }

  rule {
    name     = "sample-rule"
    priority = 1

    action {
      block {}
    }

    statement {
      ip_set_reference_statement {
        arn = aws_wafv2_ip_set.example.arn
      }
    }
    
    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "sampleRule"
      sampled_requests_enabled   = false
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "exampleAcl"
    sampled_requests_enabled   = false
  }
}

resource "aws_wafv2_ip_set" "example" {
  name               = "example-ip-set"
  description        = "Example IP set for WAF"
  scope              = "REGIONAL"
  ip_address_version = "IPV4"

  addresses = ["1.2.3.4/32"]
}

### WAFとALBの関連付け
resource "aws_wafv2_web_acl_association" "example" {
  web_acl_arn = aws_wafv2_web_acl.example.arn
  resource_arn = aws_alb.example.arn
}


2.コード実行

# terraform plan
# terraform apply


3.接続
※接続できることを確認


4.接続元のグローバルIP確認
※cmanで確認
https://www.cman.jp/network/support/go_access.cgi


5.IP制限
5-1.[WAF]-[IPSets]

5-2.リジョンが[Asia Pacific (Tokyo)]となっていることを確認し、[example-ip-set]を押下

5-3.[Add IP address]を押下

5-4.4で確認した接続元のグローバルIPを設定

5-5.[Add]


6.接続
※「403 Forbidden」が返ることを確認



感想

1回やればイメージがつくから実践は大事だねぇ(´Д`)