AWS Elemental MediaConnectのSRT caller modeをプライベートサブネットで使ってみた

AWS Elemental MediaConnectのSRT CallerなSourceをNAT Gateway経由でインターネット接続可能なプライベートサブネットで使用してみました。インターネット経由でListenerに接続が可能です。
2022.09.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

清水です。AWS Elemental MediaConnectではこれまでのSRT listener modeに加えて、SRT caller modeを先日のアップデートでサポートしました。

SRT Callerを使用した際の特徴の1つは、Caller側がいわゆるプライベートサブネット配下にある状態でもNAT Gatewayを介してインターネット接続できる環境下であればListener側との映像伝送が可能であることです。

ところで、MediaConnectではVPCを介した入出力をサポートしています。

本エントリでは、MediaConnectのVPC Source(入力)でSRT caller modeを試してみます。具体的にはSRT CalleなMediaConnect Sourceをプライベートサブネットに配置します。インターネットへはNAT Gatewayを介して接続できる状況として、SRT Listenerと接続して映像伝送が可能かを確認してみました。

MediaConnectのSRT caller modeをプライベートサブネットで使ってみた

まずは今回検証する環境についてです。先日のエントリの環境をベースに、SRT caller modeをsourceに持つMediaConnect Flowについて、Source TypeをVPC Sourceとします。

Source部分については指定したVPCのプライベートIPを持つぐあいですね。このVPC Sourceについては、VPC内のリソースとのプライベートIP通信を行うことが多いかと思いますが、VPC内に設置したNAT Gatewayを使ってVPC Sourceをインターネットに接続可能とします。 つまり、このVPC Sourceとしては、プライベートIPを持ちつつ、NATのグローバルIPでインターネット経由の通信が可能になっている状態、となります。

SRT caller modeの特徴を考えれば、この状態でも対となるSRT Listenerとの映像伝送が可能となるはずです。これを実際に確認してみます。

1. VPCならびにMediaConnect SRT listener flowの準備

VPCについては上記構成のものを作成済みとし、作成手順は省略します。

またMediaConnect listener flowについては、以下エントリの「srt-listener-flow」をそのまま利用しました。こちらも作成手順などは省略します。

1点、SRT listener output (srt-listener-output)のCIDR allow listのみ更新をしておきます。対になるSRT Caller(XXX)とはVPCのNAT Gateway経由で通信する想定となります。srt-listener-outputに接続を許可するIPアドレスとしては、このNAT Gatewayのものを指定すれば良いことなりますね。

今回使用したNAT GatewayのIPアドレス(Elastic IP address)は52.XXX.XXX.75でした。

このIPアドレス52.XXX.XXX.75を、srt-listener-outputのCIDR allow listに指定しておきます。

2. VPC MediaConnect用のIAM準備

続いてSRT caller modeでVPC SourceなMediaConnect Flowの作成、と行きたいのですが、この前にMediaConnectのVPC対応用のIAMについて準備しておきます。

MediaConnectではSource、Outputの双方でVPCに対応したタイプ(VPC Source、VPC Output)を選択することができます。まとめてVPC MediaConnectと称することとしましょう。このVPC MediaConnect使用の際、MediaConnectが必要に応じて指定したVPCに属するENI (Elastic Network Interface)を作成します。このときに、MediaConnectに作成に使用するIAM権限を付与しておく必要があります。ここでは、、

(すでにVPC MediaConnect用のIAMが準備されていれば、このステップは省略することができます。今回私はVPC MediaConnectの使用が初めてだったため、このステップでIAMを準備しています。)

以下ドキュメントを参考に進めます。

IAMポリシーの作成

まずは許可するアクションを定義したIAMポリシーを作成します。

IAMのマネジメントコンソール、Policiesの画面から[Create policy]ボタンで進みます。タブを「JSON」側にして以下内容を記載します。このポリシー内容はUser Guideの「Allow AWS Elemental MediaConnect to create and manage network interfaces in your VPC」 AWS Elemental MediaConnect resource-based policy examples - AWS Elemental MediaConnectを参考にしています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ec2:describeNetworkInterfaces",
                "ec2:describeSecurityGroups",
                "ec2:describeSubnets",
                "ec2:createNetworkInterface",
                "ec2:createNetworkInterfacePermission",
                "ec2:deleteNetworkInterface",
                "ec2:deleteNetworkInterfacePermission"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

Policy NameとDescriptionを記載して[Create policy]でポリシーを作成します。NameはMediaConnectVPCPolicyとしました。

IAMロールの作成

続いてIAMロールを作成します。IAMのマネジメントコンソール、Rolesの画面から[Create role]ボタンで進みます。Trusted entity typeは「AWS service」を選択、Use caseで「EC2」を選択します。(ただしのちほど、このUse caseで選ぶ信頼対象は変更します。)

Add permissionsでは、先ほど作成したIAMポリシー「MediaConnectVPCPolicy」を選択します。

Role nameとDescriptionを入力して、[Create role]でロールを作成します。NameはMediaConnectVPCRoleとしました。

IAMロールの信頼関係の編集

ロールの作成後、MediaConnectVPCRole詳細画面の「Trust relationships」タブで、信頼関係を編集します。対象となるService Principalを"ec2.amazonaws.com"から"mediaconnect.amazonaws.com"とします。またサービス間の混乱した代理人の防止(Cross-service confused deputy prevention - AWS Elemental MediaConnect)のため、AWSアカウントをaws:SourceAccountで指定しています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "mediaconnect.amazonaws.com"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "123456789012"
                }
            }
        }
    ]
}

以上でIAMロールの作成は完了です。

3. VPC SourceなMediaConnect SRT caller flowの作成

IAMの準備ができたら、いざ!SRT caller modeでVPC SourceなMediaConnect Flowの作成を行います。しかしマネジメントコンソールから作成を試みたのですが、SourceListenerAddressの指定がうまく行かずエラーとなってしまいました。

AWS CLIでFlowを作成します。

% aws --version
aws-cli/2.7.34 Python/3.9.11 Darwin/21.6.0 exe/x86_64 prompt/off

以下のJSONファイルを準備しました。"SourceListenerAddress""SourceListenerPort"で、先日のエントリで作成したsrt-listener-outputの情報を指定します。また"VpcInterfaces"でVPC(サブネット)、Security Groupを指定します。

vpc-srt-caller-flow.json

{
    "AvailabilityZone": "ap-northeast-1a",
    "Name": "vpc-srt-caller-flow",
    "Source": {
        "Description": "VPC SRT caller Source",
        "MaxBitrate": 10000000,
        "MinLatency": 2000,
        "Name": "vpc-srt-caller-source",
        "Protocol": "srt-caller",
        "SourceListenerAddress": "35.XXX.XXX.56",
        "SourceListenerPort": 5079,
        "VpcInterfaceName": "vpc-srt-caller-vpc-interface"
    },
    "VpcInterfaces": [
        {
            "Name": "vpc-srt-caller-vpc-interface",
            "NetworkInterfaceType": "ena",
            "RoleArn": "arn:aws:iam::123456789012:role/MediaConnectVPCRole",
            "SecurityGroupIds": [
                "sg-08edxxxxxxxxxxxxx"
            ],
            "SubnetId": "subnet-0589xxxxxxxxxxxxx"
        }
    ]
}

なお、Security Groupは以下のようなInbound rulesは無指定、Outbound rulesはデフォルトの全許可のものを使用しました。

aws mediaconnect create-flowコマンドを先ほどのJSONファイルを入力として実行します。

% aws mediaconnect create-flow --cli-input-json file://vpc-srt-caller-flow.json
{
    "Flow": {
        "AvailabilityZone": "ap-northeast-1a",
        "Description": "VPC SRT caller Source",
        "EgressIp": "18.XXX.XXX.232",
        "Entitlements": [],
        "FlowArn": "arn:aws:mediaconnect:ap-northeast-1:123456789012:flow:1-WlADxxxxxxxxxxxxxxxxxxxxxxxxx:vpc-srt-caller-flow",
        "MediaStreams": [],
        "Name": "vpc-srt-caller-flow",
        "Outputs": [],
        "Source": {
            "Description": "VPC SRT caller Source",
            "IngestIp": "10.100.201.136",
            "Name": "vpc-srt-caller-source",
            "SourceArn": "arn:aws:mediaconnect:ap-northeast-1:123456789012:source:1-WlADxxxxxxxxxxxxxxxxxxxxxxxxx:vpc-srt-caller-source",
            "Transport": {
                "MaxBitrate": 10000000,
                "MinLatency": 2000,
                "Protocol": "srt-caller",
                "SourceListenerAddress": "35.XXX.XXX.56",
                "SourceListenerPort": 5079
            },
            "VpcInterfaceName": "vpc-srt-caller-vpc-interface"
        },
        "Sources": [
            {
                "Description": "VPC SRT caller Source",
                "IngestIp": "10.100.201.136",
                "Name": "vpc-srt-caller-source",
                "SourceArn": "arn:aws:mediaconnect:ap-northeast-1:123456789012:source:1-WlADxxxxxxxxxxxxxxxxxxxxxxxxx:vpc-srt-caller-source",
                "Transport": {
                    "MaxBitrate": 10000000,
                    "MinLatency": 2000,
                    "Protocol": "srt-caller",
                    "SourceListenerAddress": "35.XXX.XXX.56",
                    "SourceListenerPort": 5079
                },
                "VpcInterfaceName": "vpc-srt-caller-vpc-interface"
            }
        ],
        "Status": "STANDBY",
        "VpcInterfaces": [
            {
                "Name": "vpc-srt-caller-vpc-interface",
                "NetworkInterfaceIds": [
                    "eni-0bddxxxxxxxxxxxxx"
                ],
                "NetworkInterfaceType": "ena",
                "RoleArn": "arn:aws:iam::123456789012:role/MediaConnectVPCRole",
                "SecurityGroupIds": [
                    "sg-08edxxxxxxxxxxxxx"
                ],
                "SubnetId": "subnet-0589xxxxxxxxxxxxx"
            }
        ]
    }
}

VPC SourceなMediaConnect SRT caller flowが作成できました。VPC Sourceであるsrt-vpc-caller-sourceにはIPアドレス10.100.201.136が割り当てられています。(なおsrt-vpc-caller-flowとしては、18.XXX.XXX.232なパブリックIPアドレスが割り当てられています。)

EC2のマネジメントコンソールから、Network interfacesについても確認してみましょう。

Public IPを持たずPrivate IPのみが割り当てられたENIが確認できました。Description欄には「Created by AWS MediaConnect」と記載されていますね。

4. MediaLive Workflowの作成

VPCなMediaConnectの準備ができました。続いてMediaLive Workflowを作成していきます。Workflowの名前とVideo sourceとなるMediaConnect Flow以外は以前のエントリと同一とします。以下では変更ポイントのみまとめていきます。

Workflowの名前は前は「vpc-srt-medialive-workflow」としました。Step 2 Choose a video sourceでInput typeとして「MediaConnect」を選択、「Create a new input」としてMediaConnect flowsで先ほど作成した「`vpc-srt-caller-flow」を選択します。

以降は以前のエントリと同様です。作成したMediaLive Workflowは下記となります。

MediaLive Workflowを作成したタイミングで、MediaConnect Flow「vpc-srt-caller-flow」についてaws mediaconnect describe-flowコマンドで情報を取得してみましょう。Outputsの項目が追加されていることがわかりますね。

describe-flow

 % aws mediaconnect describe-flow --flow-arn arn:aws:mediaconnect:ap-northeast-1:123456789012:flow:1-WlADxxxxxxxxxxxxxxxxxxxxxxxxx:vpc-srt-caller-flow --profile shimizu.toshiya
{
    "Flow": {
        "AvailabilityZone": "ap-northeast-1a",
        "Description": "VPC SRT caller Source",
        "EgressIp": "18.XXX.XXX.232",
        "Entitlements": [],
        "FlowArn": "arn:aws:mediaconnect:ap-northeast-1:123456789012:flow:1-WlADxxxxxxxxxxxxxxxxxxxxxxxxx:vpc-srt-caller-flow",
        "MediaStreams": [],
        "Name": "vpc-srt-caller-flow",
        "Outputs": [
            {
                "Description": "Output created automatically by MediaLive for account 123456789012 to input ARN arn:aws:medialive:ap-northeast-1:123456789012:input:50xxxxx",
                "MediaLiveInputArn": "arn:aws:medialive:ap-northeast-1:123456789012:input:50xxxxx",
                "Name": "MediaLive-f057xxxxxxxx",
                "OutputArn": "arn:aws:mediaconnect:ap-northeast-1:123456789012:output:1-WlADxxxxxxxxxxxxxxxxxxxxxxxxx:MediaLive-f057xxxxxxxx"
            }
        ],
        "Source": {
            "Description": "VPC SRT caller Source",
            "IngestIp": "10.100.201.136",
            "Name": "vpc-srt-caller-source",
            "SourceArn": "arn:aws:mediaconnect:ap-northeast-1:123456789012:source:1-WlADxxxxxxxxxxxxxxxxxxxxxxxxx:vpc-srt-caller-source",
            "Transport": {
                "MaxBitrate": 10000000,
                "MinLatency": 2000,
                "Protocol": "srt-caller",
                "SourceListenerAddress": "35.XXX.XXX.56",
                "SourceListenerPort": 5079
            },
            "VpcInterfaceName": "vpc-srt-caller-vpc-interface"
        },
        "Sources": [
            {
                "Description": "VPC SRT caller Source",
                "IngestIp": "10.100.201.136",
                "Name": "vpc-srt-caller-source",
                "SourceArn": "arn:aws:mediaconnect:ap-northeast-1:123456789012:source:1-WlADxxxxxxxxxxxxxxxxxxxxxxxxx:vpc-srt-caller-source",
                "Transport": {
                    "MaxBitrate": 10000000,
                    "MinLatency": 2000,
                    "Protocol": "srt-caller",
                    "SourceListenerAddress": "35.XXX.XXX.56",
                    "SourceListenerPort": 5079
                },
                "VpcInterfaceName": "vpc-srt-caller-vpc-interface"
            }
        ],
        "Status": "STANDBY",
        "VpcInterfaces": [
            {
                "Name": "vpc-srt-caller-vpc-interface",
                "NetworkInterfaceIds": [
                    "eni-0bddxxxxxxxxxxxxx"
                ],
                "NetworkInterfaceType": "ena",
                "RoleArn": "arn:aws:iam::123456789012:role/MediaConnectVPCRole",
                "SecurityGroupIds": [
                    "sg-08edxxxxxxxxxxxxx"
                ],
                "SubnetId": "subnet-0589xxxxxxxxxxxxx"
            }
        ]
    }
}

5. 映像を打ち上げて動作確認

各リソースが作成できたので、実際に映像を打ち上げて動作確認をしてみます。MediaConnectのsrt-listener-flow、MediaLiveのvpc-srt-medialive-wokflowの順にStartさせます。(MediaConnectのvpc-srt-caller-flowはMediaLiveのvpc-srt-medialive-workflowのStartと連動してStartします。)

OBS Studioからsrt-listener-flowsrt-listener-sourceにSRTで映像を打ち上げます。

視聴はMediaPackageのHLS endpointをCloudFront経由で確認します。

再生PlayerにはmacOS上のSafariブラウザを使用しました。再生できていますね!

vpc-srt-caller-flowvpc-srt-caller-sourceに対する、CloudWatchメトリックも確認しておきましょう。きちんとsrt-listner-outputに接続し、映像が伝送できていることがわかります。

6. NAT Gatewayへの経路を断った場合の確認

プライベートサブネットに配置した、SRT callerなMediaConnectのVPC SourceがNAT Gatewayを経由してインターネット上のSRT ListenerなMediaConnect Outputと接続できていることが確認できました。ここで、vpc-srt-caller-sourceの属しているプライベートサブネットのルートテーブルからNAT Gatewayへの経路を削除してみましょう。プライベートサブネットはインターネットへの経路を持たない状態になるので、そこに配置されているvpc-srt-caller-sourceは対となるインターネット上のsrt-listner-outputへ通信ができなくなるはずです。

ルートテーブルを変更してみます。変更前の状態は以下のように0.0.0.0/0に対するNAT Gatewayへの経路がある状態でした。

NAT Gatewayへの経路を削除します。

ルートテーブル変更後、しばらくすると映像の伝送が停止されたようで、Playerで再生している映像は真っ暗になりました。

MediaConnectのマネジメントコンソールを確認してみましょう。vpc-srt-caller-sourceDisconnectedとなり、メトリックから映像伝送ができていないことがわかります。

後続のMediaLiveでも映像入力がなくなり、視聴している映像が真っ暗になっていたわけですね。

プライベートサブネットのNAT Gatewayへの経路を削除し、vpc-srt-caller-sourceがインターネットへ通信できないよう設定すると映像伝送もできなくなることが確認できました。

まとめ

AWS Elemental MediaConnectで先日サポートされたSRT caller modeについて、プライベートサブネットなVPC Sourceに設定しNAT Gateway経由でSRT Listenerと接続、映像伝送できることを確認し、SRT Callerの特徴を噛み締めてみました。

VPC MediaConnectについては、VPC内やVPC Peering先、Direct Connect接続先など閉じた通信で使うことが前提で、おそらくNAT Gatewayを使ったインターネット経由の通信はあまり想定していないケースかなと個人的には思っています。(インターネット接続するなら、シンプルに非VPC MediaConnectを使うほうが良いのではないかという考えです。)そのため今回の構成は推奨されるものではなく、あくまで検証用途となりますが、柔軟な構成が実現できることでこのような検証ができることは喜ばしいなぁと思いました。