はじめに
お疲れ様です。矢儀 @yuki_ink です。
AppStream 2.0、使ってますか??
先日、AppStream 2.0 での Amazon Linux 2 のサポート終了が発表されました。
Amazon AppStream 2.0 は、2026 年 4 月 15 日に Amazon Linux 2 のサポートを終了します。
AppStream 2.0は、2021年11月に初めてAmazon Linux 2のサポートを開始しました。それ以来、AppStream 2.0の機能は、2024年7月にリリースされたRed Hat Enterprise Linux (RHEL) 8 [1]と、2024年12月にリリースされたCIQのRocky Linux 8 [2]という2つの新しいLinuxディストリビューションのサポートを導入することで強化されてきました。
Always-OnフリートおよびOn-DemandフリートでAmazon Linux 2をご利用の既存ユーザーは、ワークロードをRHEL 8またはRocky Linux 8オペレーティングシステムに移行する計画を開始することをお勧めします。
(出典)Amazon Linux 2 EOL - AppStream Elastic Fleet Linux Support
RHEL 8 か Rocky Linux 8 に移行せよとのことですが、料金面では Rocky Linux 8 のほうが有利です。
そもそもRocky Linuxとは??
Rocky Linux は、Red Hat Enterprise Linux (RHEL) と互換性を保ちながら無償で利用できる Linux ディストリビューションです。
Red Hat 社が CentOS のサポート終了を突然発表したことを受け、CentOS の創設者である Gregory Kurtzer 氏が中心となって立ち上げたプロジェクトです。簡単に整理すると以下のような関係性になります。
- Red Hat Enterprise Linux (RHEL): 商用の有償ディストリビューション(安定性とサポートが充実)
- CentOS: RHEL の無償版として長年愛用されてきたが、2024 年 6 月 30 日にサポート終了
- Rocky Linux / AlmaLinux: CentOS の代替として登場した無償ディストリビューション
Rocky Linux と AlmaLinux はどちらも CentOS の代替として優秀ですが、Rocky Linux は CentOS の創設者が立ち上げたという安心感もあり、個人的には Rocky Linux を選ぶかなと思います。
やったこと
というわけで今回は、AppStream 2.0 で Rocky Linux 8 を使ってみたいと思います。
Firefoxを動かしてインターネットにアクセスすることをゴールにします。
イメージ構築の方法はこちらを参考にしました。
なお、今回は東京リージョンを利用します。
1. NW構築
CloudFormationで以下のリソースを作っていきます。
- VPC
- AppStream 2.0 用パブリックサブネット
AppStream 2.0 でブラウザを起動してインターネットにアクセスしたいので、今回はパブリックサブネットを利用します。
CloudFormationテンプレートを使って構築していきます。
AWSTemplateFormatVersion: '2010-09-09'
Description: VPC with public subnets in multiple AZs for AppStream 2.0
Parameters:
VpcCidr:
Type: String
Default: 10.1.0.0/16
PublicSubnetCidrA:
Type: String
Default: 10.1.1.0/24
PublicSubnetCidrC:
Type: String
Default: 10.1.2.0/24
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: AppStream-VPC
InternetGateway:
Type: AWS::EC2::InternetGateway
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetCidrA
AvailabilityZone: !Select [0, !GetAZs ap-northeast-1]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: AppStream-PublicSubnetA
PublicSubnetC:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetCidrC
AvailabilityZone: !Select [1, !GetAZs ap-northeast-1]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: AppStream-PublicSubnetC
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
PublicRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref PublicRouteTable
PublicSubnetCRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetC
RouteTableId: !Ref PublicRouteTable
Outputs:
VpcId:
Value: !Ref VPC
PublicSubnetAId:
Value: !Ref PublicSubnetA
PublicSubnetCId:
Value: !Ref PublicSubnetC
2. Image Builderの起動
AppStream 2.0 の画面から Images > Image builder に進み Launch Image builder ボタンをクリック。
遷移先の画面で、ベースとなるイメージを選択します。
今回は、記事執筆時点で最新の AppStream-RockyLinux8-05-30-2025 (Public) を元にイメージを作っていきます。

続いて、Configure Image Builder の画面で、以下の設定を入れていきます。
今回は以下の項目だけ設定しました(それ以外はデフォルトを維持)
| 項目 | 値 |
|---|---|
| Name | RockyLinux-Firefox |
| Display name - optional | RockyLinux-Firefox |
| Choose instance type | stream.standard.medium |
Firefox開発元の公式サイトによると 「64 ビット版 Firefox は、4GB 以上の RAM を搭載したマシンでのクラッシュが 39% 減っています」 とのことで、インスタンスタイプは4GBのメモリを積んでいる「stream.standard.medium」以上が推奨です。
続いて、Configure network の画面で、VPC・サブネットの設定を行います。
先ほど作ったVPCとサブネットを選択し、セキュリティグループはデフォルトのものを適用しています。
今回は Enable default internet access にもチェックを入れておきます。

最後の確認画面で問題なければ、Launch Image builder を押下します。

AppStream 2.0 を使い始めて間もないアカウントでは、ここで以下のエラーが発生することがあります。
AppStream 2.0 encountered an error because your service role 'arn:aws:iam::123456789012:role/service-role/AmazonAppStreamServiceAccess' is invalid
IAMロール AmazonAppStreamServiceAccess はAppStream 2.0 のサービス画面へのアクセスをトリガーとして自動生成されるものなので、
このエラーが発生した場合はしばらく待って、リトライしてみましょう。
3. Image Builder への接続
Image Builder画面の Action から Create Streaming URL をクリックし、ストリーミングURLを作成します。
今回はブラウザからストリーミングURLを開きます。

起動した画面でターミナルを開きます。
一応お守りとして sudo dnf remove firefox を叩きました(結果、何も入ってなかったけどw)

4. Rocky LinuxにFirefoxをインストールする
ターミナル上でFirefoxのインストーラをダウンロードします。
今回はFirefoxの日本語版を利用します。
ホームディレクトリ配下に Downloads というディレクトリがあったので、そこにインストーラをダウンロード。
$ cd ./Downloads/
$ pwd
/home/ImageBuilderAdmin/Downloads
$ curl -L -o firefox.tar.xz "https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=ja"
$ ls -l
-rw-rw-r--. 1 ImageBuilderAdmin ImageBuilderAdmin 75347636 Jul 12 07:29 firefox.tar.xz
外部環境でFirefoxのインストーラをダウンロードして、Image Builderに持ち込むことも可能です。
①公式ページからインストーラをダウンロード
②Image Builderにインストーラを持ち込み
画面上部の「フォルダ」っぽいボタンから TemporaryFiles に移動し、 Update file(s) からインストーラをアップロードします

アップロードしたファイルは ./MyFiles/TemporaryFiles/ ディレクトリに格納されています。
$ pwd
/home/ImageBuilderAdmin
$ ls -ltr ./MyFiles/TemporaryFiles/
-rw-rw-r--. 1 ImageBuilderAdmin ImageBuilderAdmin 75347636 Jul 12 07:23 firefox-140.0.4.tar.xz
以下のコマンドを実行して、Rocky LinuxにFirefoxをインストールし、起動します。
$ sudo tar xvJf firefox.tar.xz -C /usr/local
$ sudo ln -s /usr/local/firefox/firefox /usr/bin/firefox
$ /usr/bin/firefox &
5. アプリケーション最適化マニフェストファイルを生成する
マニフェストファイルとは、ソフトウェアやシステムの動作に必要な設定やリソース情報を記述したファイルのことです。このファイルには、プログラムが参照するコンポーネントやライブラリ、実行時に必要な外部ファイル、各種設定値などが記載されます。最適化マニフェストは、アプリケーションごとに 1 つある行区切りのテキストファイルです。
作成すると、新しいフリートインスタンスでの初回起動時におけるアプリケーションの起動がより迅速になります。
ということで作っていきましょう!
上記出典の記事を参考に作業を進めます。
まずはルート親 PID を見つけます。
今回は 7577 でした。
$ ps -ef | grep -i /usr/bin/firefox | grep -v grep
ImageBu+ 7577 3271 2 19:46 pts/0 00:00:04 /usr/bin/firefox
vi ~/getfilestool.sh と叩いて、カレントディレクトリ(どこでもいい)に getfilestool.sh スクリプトを作成。
#!/bin/bash
## usage getfilestool.sh $pid
lsof -p $(pstree -p $1 | grep -o '([0-9]\+)' | grep -o '[0-9]\+' | tr '\012' ,)|grep REG | sed -n '1!p' | awk '{print $9}'|awk 'NF'
実行権限を付与して、実行します。
$ chmod u+x ~/getfilestool.sh
$ sudo ~/getfilestool.sh 7577 > /tmp/firefox-manifest.txt
6. AppStream 2.0 アプリケーションカタログを作成する
AppStream 2.0 経由でFirefoxを利用できるように、Firefoxをアプリケーションカタログに登録します。
ターミナル上で以下のコマンドを実行します。
## アプリケーションの追加
$ sudo AppStreamImageAssistant add-application \
--name "Firefox" \
--absolute-app-path "/usr/bin/firefox" \
--display-name "Firefox" \
--absolute-icon-path "/usr/share/icons/HighContrast/256x256/apps/firefox.png" \
--absolute-manifest-path "/tmp/firefox-manifest.txt"
## アプリケーションが追加されたことを確認
$ AppStreamImageAssistant list-applications
#### このように表示されたら問題なし ####
{
"status": 0,
"message": "Success",
"applications": [
{
"Name": "Firefox",
"AbsoluteAppPath": "/usr/bin/firefox",
"DisplayName": "Firefox",
"AbsoluteIconPath": "/usr/share/icons/HighContrast/256x256/apps/firefox.png",
"AbsoluteManifestPath": "/opt/appstream/AppCatalogHelper/AppManifests/<ランダム文字列>.txt"
}
]
}
7. イメージの作成
$ sudo AppStreamImageAssistant create-image \
--name "Firefox" \
--display-name "Firefox" \
--description "Firefox on RockyLinux8" \
--use-latest-agent-version
## 数秒後、リモートセッションが切断される
リモートセッションが切断されたのち、Image Builderを確認すると、ステータスが Snapshotting となっています。

しばらく待つと、Image registryに作成したイメージが表示されるようになります。

8. フリートとスタックの作成
こちらの記事を参考に作業を進めます。
「フリートの作成」、「スタックの作成」の章を参照させていただきました。
- フリート名は
firefoxにしました。 - イメージとして、先ほど作成したイメージ
Firefoxを指定しています。 - インスタンスタイプはImage Builder同様「stream.standard.medium」にしました。
- VPCとサブネットは最初に作成したものを指定します。
- スタック名は
firefoxにしました。 -
Home foldersは、今回は無効にしました。
※Home foldersを有効にすると、S3バケットが自動で作成され、ユーザーが自身のホームフォルダに保存したデータは、S3バケットへ自動的にバックアップされるようになります。この機能を利用することで、ユーザーは後続のセッションでもデータにアクセスできます。
9. 動作確認
スタック画面の Action から Create Streaming URL をクリックし、ストリーミングURLを作成します。
User ID はなんでもいいです。

ブラウザからストリーミングURLにアクセスすると、アプリケーションカタログ画面に遷移します。

Firefox のアイコンをクリックすると、Firefoxが起動します。

終わりに
以上、Rocky Linuxベースのイメージを使って、AppStream 2.0でFirefoxを動かすことができました。
感覚的には、Amazon Linux 2と同様の操作感で設定ができたかなと思います。
残念なのは、 せっかく日本語版のFirefoxを入れたのに、AppStream 2.0経由で日本語入力ができない ということです。
Firefoxの日本語化対応が今後の課題となります。。
※この課題については、Amazon Linux 2をはじめ他のLinux系OSでも同じことが言えます。
Rocky Linuxにしたから日本語対応できていないということではありません。
以下の記事を参考に、日本語化対応ができそうなので、またの機会に試してみようと思います。
参考資料
上記で記述した記事に加え、以下の記事も参考にさせていただきました!
ありがとうございました!







