

# サービス検出を使用する新しい Amazon ECS サービスの作成
<a name="create-service-discovery"></a>

AWS CLI でサービス検出を使用する Fargate タスクを含むサービスを作成する方法について説明します。

サービス検出をサポートする AWS リージョン のリストについては、「[サービス検出を使用して Amazon ECS サービスを DNS 名で接続する](service-discovery.md)」を参照してください。

Fargate をサポートするリージョンの情報については、「[AWS Fargate で使用する Amazon ECS でサポートされているリージョン](AWS_Fargate-Regions.md)」 を参照してください。

**注記**  
デュアルスタックサービスエンドポイントを使用することで、IPv4 と IPv6 の両方を介して AWS CLI、SDK、および Amazon ECS API から Amazon ECS とやり取りできます。詳細については、「[Amazon ECS デュアルスタックエンドポイントの使用](dual-stack-endpoint.md)」を参照してください。

## 前提条件
<a name="create-service-discovery-prereqs"></a>

個のチュートリアルを開始する前に、次の前提条件を満たしていることを確認します。
+ AWS CLI の最新バージョンがインストールされ、設定されていること。詳細については、「[AWS CLIの最新バージョンのインストールまたは更新](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)」を参照してください。
+ 「[Amazon ECS を使用するようにセットアップする](get-set-up-for-amazon-ecs.md)」で説明されているステップが完了しました。
+ IAM ユーザーに [AmazonECS\_FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM ポリシー例で指定されている必要なアクセス権限があること。
+ 少なくとも 1 つの VPC と 1 つのセキュリティグループを作成している。詳細については、「[仮想プライベートクラウドを作成する](get-set-up-for-amazon-ecs.md#create-a-vpc)」を参照してください。

## ステップ 1: AWS Cloud Map でサービス検出リソースを作成する
<a name="create-service-discovery-namespace"></a>

サービス検出の名前空間およびサービス検出サービスを作成するには、次のステップに従います。

1. プライベート Cloud Map サービス検出の名前空間を作成します。この例では、`tutorial` と呼ばれる名前空間を作成します。{{vpc-abcd1234}} を、既存のいずれかの VPC の ID に置き換えます。

   ```
   aws servicediscovery create-private-dns-namespace \
         --name {{tutorial}} \
         --vpc {{vpc-abcd1234}}
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "OperationId": "{{h2qe3s6dxftvvt7riu6lfy2f6c3jlhf4-je6chs2e}}"
   }
   ```

1. 前のステップの出力の `OperationId` を使用して、プライベート名前空間が正常に作成されたことを確認します。名前空間 ID は後続のコマンドで使用するため、書き留めておきます。

   ```
   aws servicediscovery get-operation \
         --operation-id {{h2qe3s6dxftvvt7riu6lfy2f6c3jlhf4-je6chs2e}}
   ```

   出力は次のとおりです。

   ```
   {
       "Operation": {
           "Id": "{{h2qe3s6dxftvvt7riu6lfy2f6c3jlhf4-je6chs2e}}",
           "Type": "CREATE_NAMESPACE",
           "Status": "SUCCESS",
           "CreateDate": 1519777852.502,
           "UpdateDate": 1519777856.086,
           "Targets": {
              "NAMESPACE": "{{ns-uejictsjen2i4eeg}}"
           }
       }
   }
   ```

1. 前のステップの出力からの `NAMESPACE` ID を使用して、サービス検出サービスを作成します。この例では、`myapplication` という名前のサービスが作成されます。サービス ID と ARN は後続のコマンドで使用するため、書き留めておきます。

   ```
   aws servicediscovery create-service \
         --name {{myapplication}} \
         --dns-config "NamespaceId="{{ns-uejictsjen2i4eeg}}",DnsRecords=[{Type="{{A}}",TTL="{{300}}"}]" \
         --health-check-custom-config FailureThreshold={{1}}
   ```

   出力は次のとおりです。

   ```
   {
       "Service": {
          "Id": "{{srv-utcrh6wavdkggqtk}}",
           "Arn": "arn:aws:servicediscovery:{{region}}:{{aws_account_id}}:service/{{srv-utcrh6wavdkggqtk}}",
           "Name": "myapplication",
           "DnsConfig": {
               "NamespaceId": "{{ns-uejictsjen2i4eeg}}",
               "DnsRecords": [
                   {
                       "Type": "{{A}}",
                       "TTL": {{300}}
                   }
               ]
           },
           "HealthCheckCustomConfig": {
               "FailureThreshold": {{1}}
           },
           "CreatorRequestId": "e49a8797-b735-481b-a657-b74d1d6734eb"
       }
   }
   ```

## ステップ 2: Amazon ECS リソースを作成する
<a name="create-service-discovery-cluster"></a>

Amazon ECS クラスター、タスク定義、サービスを作成するには、次のステップに従います。

1. Amazon ECS クラスターを作成します。この例では、`tutorial` という名前のクラスターを作成します。

   ```
   aws ecs create-cluster \
         --cluster-name {{tutorial}}
   ```

1. Fargate と互換性があり、`awsvpc` ネットワークモードを使用するタスク定義を登録します。以下の手順に従ってください。

   1. 次のタスク定義の内容で、`fargate-task.json` というファイルを作成します。

      ```
      {
          "family": "tutorial-task-def",
              "networkMode": "awsvpc",
              "containerDefinitions": [
                  {
                      "name": "sample-app",
                      "image": "public.ecr.aws/docker/library/httpd:2.4",
                      "portMappings": [
                          {
                              "containerPort": 80,
                              "hostPort": 80,
                              "protocol": "tcp"
                          }
                      ],
                      "essential": true,
                      "entryPoint": [
                          "sh",
                          "-c"
                      ],
                      "command": [
                          "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
                      ]
                  }
              ],
              "requiresCompatibilities": [
                  "FARGATE"
              ],
              "cpu": "256",
              "memory": "512"
      }
      ```

   1. `fargate-task.json` を使用してタスク定義を登録します。

      ```
      aws ecs register-task-definition \
            --cli-input-json file://fargate-task.json
      ```

1. 次のステップに従って、ECS サービスを作成します。

   1. 作成する ECS サービスの内容で、`ecs-service-discovery.json` という名前のファイルを作成します。この例では、前のステップで作成したタスク定義を使用します。このタスク定義の例では `awsvpc` ネットワークモードを使用しているため、`awsvpcConfiguration` が必要となります。

      ECS サービスを作成する際に、Fargate と、サービス検出をサポートする `LATEST` プラットフォームバージョンを指定します。AWS Cloud Map でサービス検出サービスが作成される場合、`registryArn` は返される ARN です。`securityGroups` および `subnets` は、Cloud Map 名前空間の作成に使用される VPC に属している必要があります。Amazon VPC コンソールからセキュリティグループとサブネット ID を取得できます。

      ```
      {
          "cluster": "tutorial",
          "serviceName": "ecs-service-discovery",
          "taskDefinition": "tutorial-task-def",
          "serviceRegistries": [
             {
                "registryArn": "arn:aws:servicediscovery:{{region}}:{{aws_account_id}}:service/{{srv-utcrh6wavdkggqtk}}"
             }
          ],
          "launchType": "FARGATE",
          "platformVersion": "LATEST",
          "networkConfiguration": {
             "awsvpcConfiguration": {
                "assignPublicIp": "ENABLED",
                "securityGroups": [ "{{sg-abcd1234}}" ],
                "subnets": [ "{{subnet-abcd1234}}" ]
             }
          },
          "desiredCount": {{1}}
      }
      ```

   1. `ecs-service-discovery.json` を使用して ECS サービスを作成します。

      ```
      aws ecs create-service \
            --cli-input-json file://ecs-service-discovery.json
      ```

## ステップ 3: AWS Cloud Map でサービス検出を検証する
<a name="create-service-discovery-verify"></a>

サービス検出情報をクエリして、すべてが正常に作成されたことを確認します。サービス検出を設定した後、AWS Cloud Map API オペレーションを使用するか、VPC 内のインスタンスから `dig` を呼び出すことができます。以下の手順に従ってください。

1. サービス検出サービス ID を使用して、サービス検出インスタンスを一覧表示します。リソースクリーンアップのインスタンス ID (太字でマーク) を書き留めます。

   ```
    aws servicediscovery list-instances \
          --service-id {{srv-utcrh6wavdkggqtk}}
   ```

   出力は次のとおりです。

   ```
   {
       "Instances": [
           {
               "Id": "16becc26-8558-4af1-9fbd-f81be062a266",
               "Attributes": {
                   "AWS_INSTANCE_IPV4": "172.31.87.2"
                   "AWS_INSTANCE_PORT": "80", 
                   "AVAILABILITY_ZONE": "us-east-1a", 
                   "REGION": "us-east-1", 
                   "ECS_SERVICE_NAME": "ecs-service-discovery", 
                   "ECS_CLUSTER_NAME": "tutorial", 
                   "ECS_TASK_DEFINITION_FAMILY": "tutorial-task-def"
               }
           }
       ]
   }
   ```

1. サービス検出の名前空間、サービス、および ECS クラスター名などの追加パラメータを使用して、サービス検出インスタンスに関する詳細をクエリします。

   ```
   aws servicediscovery discover-instances \
         --namespace-name tutorial \
         --service-name myapplication \
         --query-parameters ECS_CLUSTER_NAME=tutorial
   ```

1. サービス検出サービス用に Route 53 ホストゾーンに作成された DNS レコードは、次の AWS CLI コマンドでクエリを実行できます。

   1. 名前空間 ID を使用して、名前空間に関する情報を取得しますが、これには Route 53 ホストゾーン ID が含まれます。

      ```
      aws servicediscovery \
            get-namespace --id {{ns-uejictsjen2i4eeg}}
      ```

      出力は次のとおりです。

      ```
      {
          "Namespace": {
              "Id": "{{ns-uejictsjen2i4eeg}}",
              "Arn": "arn:aws:servicediscovery:{{region}}:{{aws_account_id}}:namespace/{{ns-uejictsjen2i4eeg}}",
              "Name": "tutorial",
              "Type": "DNS_PRIVATE",
              "Properties": {
                   "DnsProperties": {
                      "HostedZoneId": "{{Z35JQ4ZFDRYPLV}}"
                  }
              },
              "CreateDate": 1519777852.502,
              "CreatorRequestId": "9049a1d5-25e4-4115-8625-96dbda9a6093"
          }
      }
      ```

   1. 前のステップの Route 53 ホストゾーン ID (太字のテキストを参照) を使用して、ホストゾーンのリソースレコードセットを取得します。

      ```
      aws route53 list-resource-record-sets \
            --hosted-zone-id {{Z35JQ4ZFDRYPLV}}
      ```

1. `dig` を使用して、VPC 内のインスタンスから DNS をクエリすることもできます。

   ```
   dig +short myapplication.tutorial
   ```

## ステップ 4: クリーンアップする
<a name="create-service-discovery-cleanup"></a>

このチュートリアルが終了したら、未使用のリソースに対する料金が発生しないように、それに関連付けられたリソースをクリーンアップします。以下の手順に従ってください。

1. 前に書き留めたサービス ID とインスタンス ID を使用して、サービス検出サービスインスタンスの登録を解除します。

   ```
   aws servicediscovery deregister-instance \
         --service-id {{srv-utcrh6wavdkggqtk}} \
         --instance-id {{16becc26-8558-4af1-9fbd-f81be062a266}}
   ```

   出力は次のとおりです。

   ```
   {
       "OperationId": "{{xhu73bsertlyffhm3faqi7kumsmx274n-jh0zimzv}}"
   }
   ```

1. 前のステップの出力の `OperationId` を使用して、サービス検出インスタンスが正常に登録解除されたことを確認します。

   ```
   aws servicediscovery get-operation \ 
         --operation-id {{xhu73bsertlyffhm3faqi7kumsmx274n-jh0zimzv}}
   ```

   ```
   {
     "Operation": {
           "Id": "xhu73bsertlyffhm3faqi7kumsmx274n-jh0zimzv",
           "Type": "DEREGISTER_INSTANCE",
           "Status": "SUCCESS",
           "CreateDate": 1525984073.707,
           "UpdateDate": 1525984076.426,
           "Targets": {
               "INSTANCE": "16becc26-8558-4af1-9fbd-f81be062a266",
               "ROUTE_53_CHANGE_ID": "C5NSRG1J4I1FH",
               "SERVICE": "srv-utcrh6wavdkggqtk"
           }
       }
   }
   ```

1. サービス ID を使用してサービス検出のサービスを削除します。

   ```
   aws servicediscovery delete-service \ 
         --id {{srv-utcrh6wavdkggqtk}}
   ```

1. 名前空間 ID を使用してサービス検出の名前空間を削除します。

   ```
   aws servicediscovery delete-namespace \ 
         --id {{ns-uejictsjen2i4eeg}}
   ```

   出力は次のとおりです。

   ```
   {
       "OperationId": "{{c3ncqglftesw4ibgj5baz6ktaoh6cg4t-jh0ztysj}}"
   }
   ```

1. 前のステップの出力の `OperationId` を使用して、サービス検出名前空間が正常に削除されたことを確認します。

   ```
   aws servicediscovery get-operation \ 
         --operation-id {{c3ncqglftesw4ibgj5baz6ktaoh6cg4t-jh0ztysj}}
   ```

   出力は次のとおりです。

   ```
   {
       "Operation": {
           "Id": "{{c3ncqglftesw4ibgj5baz6ktaoh6cg4t-jh0ztysj}}",
           "Type": "DELETE_NAMESPACE",
           "Status": "SUCCESS",
           "CreateDate": 1525984602.211,
           "UpdateDate": 1525984602.558,
           "Targets": {
               "NAMESPACE": "ns-rymlehshst7hhukh",
               "ROUTE_53_CHANGE_ID": "CJP2A2M86XW3O"
           }
       }
   }
   ```

1. Amazon ECS サービスに必要な数を更新して `0` にします。次のステップでサービスを削除するには、これを実行する必要があります。

   ```
   aws ecs update-service \
         --cluster tutorial \
         --service ecs-service-discovery \
         --desired-count 0
   ```

1. Amazon ECS サービスを削除します。

   ```
   aws ecs delete-service \
         --cluster tutorial \
         --service ecs-service-discovery
   ```

1. Amazon ECS クラスターを削除します。

   ```
   aws ecs delete-cluster \
         --cluster tutorial
   ```