
ブラウザだけで使えるClaude Code環境(EC2 + code-server + Bedrock)にCloudFrontを追加して、拡張機能もインストールできるようにしてみた
こんにちは、林です。
前回、EC2上のcode-serverにBedrock経由のClaude Codeを載せた環境を構築しました。
この構成には制約がありました。code-server自身が生成する自己署名証明書でHTTPSを動かしているため、ブラウザに警告が出るほか、拡張機能のインストールにも失敗します。
今回はEC2の前段にCloudFrontを置いて、この制約を解消してみました。
CloudFrontのデフォルトドメイン(xxxxxxxx.cloudfront.net)にはブラウザに信頼された証明書が最初から付いているため、証明書を自前で用意する必要がありません。
構成

前回との違いは、EC2の前にCloudFrontが入り、TLSの終端がCloudFront側に移る点です。
EC2上のcode-serverは暗号化なしのHTTPで動かし、インターネットからEC2への直接アクセスは遮断します。
VPC・IAMロールは前回と同じです。
この記事では変更点だけを記載しているため、事前準備(Bedrockのモデルアクセス有効化・IAMロール作成・VPC作成)は前回記事を参照してください。
EC2のセキュリティグループを変更する
前回はcode-serverのTCP 50443番を、自分のアクセス元IPからのみ許可していました。
今回はこのルールを削除し、代わりにTCP 8080番を、CloudFrontのマネージドプレフィックスリストからのみ許可します。
| タイプ | ポート範囲 | ソース |
|---|---|---|
| カスタムTCP | 8080 | com.amazonaws.global.cloudfront.origin-facing(プレフィックスリスト) |
ソースで実際に指定するIDは pl-xxxxxxxx の形式で、リージョンごとに異なります。セキュリティグループのインバウンドルール編集画面で、ソース欄に com.amazonaws.global.cloudfront.origin-facing と入力すると候補として表示されるので、選択すればそのリージョンのIDが自動で入力されます。
このIDはリージョンごとに異なるため、後述のCloudFormationテンプレートではMappingsでリージョン別の対応表を用意しています。
CloudFrontを前に置いても、EC2に直接アクセスできる状態のままでは意味がありません。
オリジンへの経路をCloudFrontからのみに絞ることで、暗号化なしのHTTPで待ち受けていてもインターネットからは到達できなくなります。
code-serverの設定を変更する
TLSをCloudFront側で終端するので、EC2上のcode-serverは暗号化なしのHTTPで動かします。
ユーザーデータで作成する config.yaml のうち、変わるのは次の2行だけです。
bind-addr: 0.0.0.0:8080
cert: false
前回は bind-addr: 0.0.0.0:50443 と cert: true でした。
Claude Codeのインストール部分(~/.claude/settings.json の作成など)は前回と全く同じです。
EIPとCloudFrontディストリビューションを追加する
CloudFrontのオリジンには、EC2のパブリックDNS名を指定します。
EC2を停止・起動するとこのDNS名は変わってしまうため、先にEIPを紐付けてDNS名を固定してから、ディストリビューションを作成します。
EIPはEC2コンソールの Elastic IP から割り当て、対象のEC2インスタンスに関連付けてください。
これでインスタンスを停止・起動しても、パブリックIPとパブリックDNS名が変わらなくなります。
ディストリビューションの主な設定です。
| 項目 | 設定値 |
|---|---|
| オリジンドメイン | EC2のパブリックDNS名 |
| オリジンプロトコルポリシー | HTTP only |
| HTTPポート | 8080 |
| ビューワープロトコルポリシー | Redirect HTTP to HTTPS |
| 許可するHTTPメソッド | GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE |
| キャッシュポリシー | CachingDisabled |
| オリジンリクエストポリシー | AllViewer |
CachingDisabled と AllViewer はどちらもCloudFrontの管理ポリシーです。
code-serverは操作のたびに応答が変わる動的なアプリケーションなので、キャッシュはせず、AllViewer でヘッダーやCookie、クエリ文字列をすべてオリジンに転送します。HTTPメソッドをGET/HEADだけに絞ると、ファイルの保存や拡張機能のインストールができなくなるので注意してください。
後述のCloudFormationテンプレートでは、これらのポリシーをIDで指定します。
CloudFrontはリージョンを持たないグローバルサービスなので、このIDはプレフィックスリストのIDと違ってリージョンやアカウントによらず固定です。
CloudFormationで自動構築する
ここまでの変更を反映したCloudFormationテンプレートです。
Ubuntu 24.04版 テンプレート全文
AWSTemplateFormatVersion: 2010-09-09
Description: code-server + Claude Code (Amazon Bedrock) behind CloudFront on Ubuntu 24.04
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Set basic information.
Parameters:
- SystemName
- Label:
default: Set your EC2 instance settings.
Parameters:
- InstanceType
- AMIID
Parameters:
SystemName:
Description: "Prefix of each resource name."
Type: String
Default: "code-server"
InstanceType:
Description: "EC2 instance type."
Type: String
Default: "t3.medium"
AMIID:
Description: "Ubuntu 24.04 AMI ID."
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/canonical/ubuntu/server/24.04/stable/current/amd64/hvm/ebs-gp3/ami-id
Mappings:
# CloudFront managed prefix list ID (per region)
# Reference: https://aws.amazon.com/jp/blogs/news/limit-access-to-your-origins-using-the-aws-managed-prefix-list-for-amazon-cloudfront/
AWSRegions2PrefixListID:
ap-northeast-1:
PrefixList: pl-58a04531
ap-northeast-2:
PrefixList: pl-22a6434b
ap-northeast-3:
PrefixList: pl-31a14458
ap-south-1:
PrefixList: pl-9aa247f3
ap-southeast-1:
PrefixList: pl-31a34658
ap-southeast-2:
PrefixList: pl-b8a742d1
ca-central-1:
PrefixList: pl-38a64351
eu-central-1:
PrefixList: pl-a3a144ca
eu-north-1:
PrefixList: pl-fab65393
eu-west-1:
PrefixList: pl-4fa04526
eu-west-2:
PrefixList: pl-93a247fa
eu-west-3:
PrefixList: pl-75b1541c
sa-east-1:
PrefixList: pl-5da64334
us-east-1:
PrefixList: pl-3b927c52
us-east-2:
PrefixList: pl-b6a144df
us-west-1:
PrefixList: pl-4ea04527
us-west-2:
PrefixList: pl-82a045eb
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub "${SystemName}-vpc"
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub "${SystemName}-igw"
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select [0, !GetAZs ""]
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
Tags:
- Key: Name
Value: !Sub "${SystemName}-public-subnet"
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${SystemName}-public-rtb"
PublicRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet
CodeServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub "${SystemName}-sg"
GroupDescription: "Security group for code-server (HTTP on 8080, from CloudFront only)"
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 8080
ToPort: 8080
SourcePrefixListId: !FindInMap [AWSRegions2PrefixListID, !Ref "AWS::Region", PrefixList]
Tags:
- Key: Name
Value: !Sub "${SystemName}-sg"
CodeServerRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub
- "${SystemName}-role-${Suffix}"
- Suffix: !Select [4, !Split ["-", !Select [2, !Split ["/", !Ref "AWS::StackId"]]]]
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- "ec2.amazonaws.com"
Action:
- "sts:AssumeRole"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
Policies:
- PolicyName: "BedrockInvokeAnthropicModels"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: "BedrockInvokeAnthropicModels"
Effect: "Allow"
Action:
- "bedrock:InvokeModel"
- "bedrock:InvokeModelWithResponseStream"
Resource:
- "arn:aws:bedrock:*::foundation-model/anthropic.*"
- !Sub "arn:aws:bedrock:*:${AWS::AccountId}:inference-profile/*.anthropic.*"
CodeServerInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- !Ref CodeServerRole
CodeServerEC2:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref AMIID
InstanceType: !Ref InstanceType
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
Encrypted: true
VolumeSize: 16
VolumeType: gp3
DeleteOnTermination: true
NetworkInterfaces:
- AssociatePublicIpAddress: true
DeviceIndex: "0"
SubnetId: !Ref PublicSubnet
GroupSet:
- !Ref CodeServerSecurityGroup
IamInstanceProfile: !Ref CodeServerInstanceProfile
Tags:
- Key: Name
Value: !Ref SystemName
UserData:
Fn::Base64: |
#!/bin/bash
set -eux
# Install code-server
apt update
apt install -y jq curl openssl
CODER_VERSION=$(curl -s https://api.github.com/repos/coder/code-server/releases/latest | jq -r .tag_name | sed 's/v//')
curl -fOL "https://github.com/coder/code-server/releases/download/v${CODER_VERSION}/code-server_${CODER_VERSION}_amd64.deb"
apt install -y ./code-server_${CODER_VERSION}_amd64.deb
rm -f code-server_${CODER_VERSION}_amd64.deb
mkdir -p /home/ubuntu/.config/code-server/
cat > /home/ubuntu/.config/code-server/config.yaml << EOF
bind-addr: 0.0.0.0:8080
auth: password
password: $(openssl rand -hex 16)
cert: false
EOF
chown -R ubuntu:ubuntu /home/ubuntu/.config
systemctl enable --now code-server@ubuntu
# Install Claude Code
sudo -u ubuntu bash -c 'curl -fsSL https://claude.ai/install.sh | bash'
mkdir -p /home/ubuntu/.claude
cat > /home/ubuntu/.claude/settings.json << 'EOF'
{
"env": {
"CLAUDE_CODE_USE_BEDROCK": "1",
"AWS_REGION": "ap-northeast-1",
"ANTHROPIC_MODEL": "jp.anthropic.claude-sonnet-4-6"
}
}
EOF
chown -R ubuntu:ubuntu /home/ubuntu/.claude
# Add PATH
sudo -u ubuntu bash -c 'grep -q ".local/bin" /home/ubuntu/.bashrc || echo "export PATH=\"$HOME/.local/bin:\$PATH\"" >> /home/ubuntu/.bashrc'
CodeServerEIP:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref CodeServerEC2
Tags:
- Key: Name
Value: !Ref SystemName
CodeServerDistribution:
Type: AWS::CloudFront::Distribution
DependsOn: CodeServerEIP
Properties:
DistributionConfig:
Enabled: true
Comment: !Ref SystemName
Origins:
- Id: "code-server"
DomainName: !GetAtt CodeServerEC2.PublicDnsName
CustomOriginConfig:
OriginProtocolPolicy: "http-only"
HTTPPort: 8080
DefaultCacheBehavior:
TargetOriginId: "code-server"
ViewerProtocolPolicy: "redirect-to-https"
AllowedMethods:
- "GET"
- "HEAD"
- "OPTIONS"
- "PUT"
- "POST"
- "PATCH"
- "DELETE"
# CachingDisabled
CachePolicyId: "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
# AllViewer
OriginRequestPolicyId: "216adef6-5c7f-47e4-b989-5492eafa07d3"
Outputs:
CloudFrontDomain:
Description: "code-server URL. Access it at https://<CloudFrontDomain>"
Value: !GetAtt CodeServerDistribution.DomainName
Amazon Linux 2023版 テンプレート全文
AWSTemplateFormatVersion: 2010-09-09
Description: code-server + Claude Code (Amazon Bedrock) behind CloudFront on Amazon Linux 2023
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Set basic information.
Parameters:
- SystemName
- Label:
default: Set your EC2 instance settings.
Parameters:
- InstanceType
- AMIID
Parameters:
SystemName:
Description: "Prefix of each resource name."
Type: String
Default: "code-server"
InstanceType:
Description: "EC2 instance type."
Type: String
Default: "t3.medium"
AMIID:
Description: "Amazon Linux 2023 AMI ID."
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64
Mappings:
# CloudFront managed prefix list ID (per region)
# Reference: https://aws.amazon.com/jp/blogs/news/limit-access-to-your-origins-using-the-aws-managed-prefix-list-for-amazon-cloudfront/
AWSRegions2PrefixListID:
ap-northeast-1:
PrefixList: pl-58a04531
ap-northeast-2:
PrefixList: pl-22a6434b
ap-northeast-3:
PrefixList: pl-31a14458
ap-south-1:
PrefixList: pl-9aa247f3
ap-southeast-1:
PrefixList: pl-31a34658
ap-southeast-2:
PrefixList: pl-b8a742d1
ca-central-1:
PrefixList: pl-38a64351
eu-central-1:
PrefixList: pl-a3a144ca
eu-north-1:
PrefixList: pl-fab65393
eu-west-1:
PrefixList: pl-4fa04526
eu-west-2:
PrefixList: pl-93a247fa
eu-west-3:
PrefixList: pl-75b1541c
sa-east-1:
PrefixList: pl-5da64334
us-east-1:
PrefixList: pl-3b927c52
us-east-2:
PrefixList: pl-b6a144df
us-west-1:
PrefixList: pl-4ea04527
us-west-2:
PrefixList: pl-82a045eb
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub "${SystemName}-vpc"
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub "${SystemName}-igw"
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select [0, !GetAZs ""]
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
Tags:
- Key: Name
Value: !Sub "${SystemName}-public-subnet"
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${SystemName}-public-rtb"
PublicRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet
CodeServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub "${SystemName}-sg"
GroupDescription: "Security group for code-server (HTTP on 8080, from CloudFront only)"
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 8080
ToPort: 8080
SourcePrefixListId: !FindInMap [AWSRegions2PrefixListID, !Ref "AWS::Region", PrefixList]
Tags:
- Key: Name
Value: !Sub "${SystemName}-sg"
CodeServerRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub
- "${SystemName}-role-${Suffix}"
- Suffix: !Select [4, !Split ["-", !Select [2, !Split ["/", !Ref "AWS::StackId"]]]]
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- "ec2.amazonaws.com"
Action:
- "sts:AssumeRole"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
Policies:
- PolicyName: "BedrockInvokeAnthropicModels"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: "BedrockInvokeAnthropicModels"
Effect: "Allow"
Action:
- "bedrock:InvokeModel"
- "bedrock:InvokeModelWithResponseStream"
Resource:
- "arn:aws:bedrock:*::foundation-model/anthropic.*"
- !Sub "arn:aws:bedrock:*:${AWS::AccountId}:inference-profile/*.anthropic.*"
CodeServerInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- !Ref CodeServerRole
CodeServerEC2:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref AMIID
InstanceType: !Ref InstanceType
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
Encrypted: true
VolumeSize: 16
VolumeType: gp3
DeleteOnTermination: true
NetworkInterfaces:
- AssociatePublicIpAddress: true
DeviceIndex: "0"
SubnetId: !Ref PublicSubnet
GroupSet:
- !Ref CodeServerSecurityGroup
IamInstanceProfile: !Ref CodeServerInstanceProfile
Tags:
- Key: Name
Value: !Ref SystemName
UserData:
Fn::Base64: |
#!/bin/bash
set -eux
# Install code-server
dnf install -y jq openssl
CODER_VERSION=$(curl -s https://api.github.com/repos/coder/code-server/releases/latest | jq -r .tag_name | sed 's/v//')
curl -fOL "https://github.com/coder/code-server/releases/download/v${CODER_VERSION}/code-server-${CODER_VERSION}-amd64.rpm"
dnf install -y ./code-server-${CODER_VERSION}-amd64.rpm
rm -f code-server-${CODER_VERSION}-amd64.rpm
mkdir -p /home/ec2-user/.config/code-server/
cat > /home/ec2-user/.config/code-server/config.yaml << EOF
bind-addr: 0.0.0.0:8080
auth: password
password: $(openssl rand -hex 16)
cert: false
EOF
chown -R ec2-user:ec2-user /home/ec2-user/.config
systemctl enable --now code-server@ec2-user
# Install Claude Code
sudo -u ec2-user bash -c 'curl -fsSL https://claude.ai/install.sh | bash'
mkdir -p /home/ec2-user/.claude
cat > /home/ec2-user/.claude/settings.json << 'EOF'
{
"env": {
"CLAUDE_CODE_USE_BEDROCK": "1",
"AWS_REGION": "ap-northeast-1",
"ANTHROPIC_MODEL": "jp.anthropic.claude-sonnet-4-6"
}
}
EOF
chown -R ec2-user:ec2-user /home/ec2-user/.claude
# Add PATH
sudo -u ec2-user bash -c 'grep -q ".local/bin" /home/ec2-user/.bashrc || echo "export PATH=\"$HOME/.local/bin:\$PATH\"" >> /home/ec2-user/.bashrc'
CodeServerEIP:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref CodeServerEC2
Tags:
- Key: Name
Value: !Ref SystemName
CodeServerDistribution:
Type: AWS::CloudFront::Distribution
DependsOn: CodeServerEIP
Properties:
DistributionConfig:
Enabled: true
Comment: !Ref SystemName
Origins:
- Id: "code-server"
DomainName: !GetAtt CodeServerEC2.PublicDnsName
CustomOriginConfig:
OriginProtocolPolicy: "http-only"
HTTPPort: 8080
DefaultCacheBehavior:
TargetOriginId: "code-server"
ViewerProtocolPolicy: "redirect-to-https"
AllowedMethods:
- "GET"
- "HEAD"
- "OPTIONS"
- "PUT"
- "POST"
- "PATCH"
- "DELETE"
# CachingDisabled
CachePolicyId: "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
# AllViewer
OriginRequestPolicyId: "216adef6-5c7f-47e4-b989-5492eafa07d3"
Outputs:
CloudFrontDomain:
Description: "code-server URL. Access it at https://<CloudFrontDomain>"
Value: !GetAtt CodeServerDistribution.DomainName
VPC・IAMロールの部分は前回と同一で、テンプレート上の差分は次の7箇所です。
AllowedIPパラメータを削除しました
EC2へのアクセス経路がCloudFrontに限定されるため、自分のIPを指定する必要が無くなったためです
- AllowedIP:
- Description: "Your access source IP in CIDR notation (e.g. 203.0.113.10/32)."
- Type: String
- CloudFrontのマネージドプレフィックスリストIDをリージョンごとに引くための
Mappingsを追加しました
+ Mappings:
+ AWSRegions2PrefixListID:
+ ap-northeast-1:
+ PrefixList: pl-58a04531
+ ap-northeast-2:
+ PrefixList: pl-22a6434b
+ # ...(以下17リージョン分。全文は後述のテンプレートを参照)
CodeServerSecurityGroupは、ポートと許可元を変更しています
SecurityGroupIngress:
- IpProtocol: tcp
- FromPort: 50443
- ToPort: 50443
- CidrIp: !Ref AllowedIP
+ FromPort: 8080
+ ToPort: 8080
+ SourcePrefixListId: !FindInMap [AWSRegions2PrefixListID, !Ref "AWS::Region", PrefixList]
CodeServerEC2のUserData内、config.yamlを生成する部分も変わります
cat > /home/ubuntu/.config/code-server/config.yaml << EOF
- bind-addr: 0.0.0.0:50443
+ bind-addr: 0.0.0.0:8080
auth: password
password: $(openssl rand -hex 16)
- cert: true
+ cert: false
EOF
CodeServerEIPとCodeServerDistributionは新規追加のリソースです
CodeServerEIP:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref CodeServerEC2
Tags:
- Key: Name
Value: !Ref SystemName
CodeServerDistribution:
Type: AWS::CloudFront::Distribution
DependsOn: CodeServerEIP
Properties:
DistributionConfig:
Enabled: true
Comment: !Ref SystemName
Origins:
- Id: "code-server"
DomainName: !GetAtt CodeServerEC2.PublicDnsName
CustomOriginConfig:
OriginProtocolPolicy: "http-only"
HTTPPort: 8080
DefaultCacheBehavior:
TargetOriginId: "code-server"
ViewerProtocolPolicy: "redirect-to-https"
AllowedMethods:
- "GET"
- "HEAD"
- "OPTIONS"
- "PUT"
- "POST"
- "PATCH"
- "DELETE"
# CachingDisabled
CachePolicyId: "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
# AllViewer
OriginRequestPolicyId: "216adef6-5c7f-47e4-b989-5492eafa07d3"
OutputsをEC2のパブリックIPからCloudFrontのドメインに変更しました。
- PublicIP:
- Description: "code-server public IP. Access it at https://<PublicIP>:50443"
- Value: !GetAtt CodeServerEC2.PublicIp
+ CloudFrontDomain:
+ Description: "code-server URL. Access it at https://<CloudFrontDomain>"
+ Value: !GetAtt CodeServerDistribution.DomainName
デプロイと動作確認
デプロイコマンドは次のとおりです。
AllowedIPが無くなった以外は、前回と同じ形です。
aws cloudformation create-stack --stack-name temp-code-server-cloudfront \
--template-body file://./code-server-cloudfront-ubuntu.yaml \
--capabilities CAPABILITY_NAMED_IAM
Amazon Linux 2023版は --template-body を code-server-cloudfront-al2023.yaml に変えてください。
使うモデルを変えたい場合は、テンプレートのユーザーデータ内、~/.claude/settings.json の ANTHROPIC_MODEL を書き換えてください。
デプロイが終わると、OutputsにCloudFrontのドメイン(xxxxxxxx.cloudfront.net)が出力されます。ディストリビューションの作成には数分かかるので、有効になるまで少し待ってから次に進んでください。
パスワードの確認方法はSession Manager経由で前回と同じです。
# Ubuntuの場合
sudo cat /home/ubuntu/.config/code-server/config.yaml | grep password:
# Amazon Linux 2023の場合
sudo cat /home/ec2-user/.config/code-server/config.yaml | grep password:
ブラウザでCloudFrontのドメインにアクセスします。前回と変わるのは次の2点です。
まず、証明書の警告が出ないことです。CloudFrontのデフォルトドメインを使うので、ブラウザに信頼された証明書でアクセスできます。

そして本題の、拡張機能をインストールできるかどうかです。日本語化のための「Japanese Language Pack for Visual Studio Code」と、「Claude Code for VS Code」の2つをインストールしてみました。


どちらも問題なくインストールできました。日本語パックは、インストール後に表示される再起動の案内に従うと反映されます。実際にメニューが日本語化されていることも確認できています。

あわせて、ターミナルやファイル保存がCloudFront経由でも問題なく動くかも確認します。code-serverはWebSocketで通信するため、ここが動かないとエディタとして使えません。

ターミナルの起動・コマンド実行ともに問題なく動作し、claude auth statusでBedrock経由のログイン状態も確認できました。
運用上の注意
CloudFrontとEIPが増えるぶん、前回の構成より料金がかかります。
EIPはインスタンスに紐付けていても課金対象なので、使い終わったらスタックごと削除してください。
CloudFrontのデフォルトドメインは推測されにくい文字列ですが、URLを知っていれば誰でもアクセスできてしまいます。認証はcode-serverのパスワードのみなので、長期運用する場合はCognito認証などをあわせて検討してください。
さいごに
CloudFrontを前段に置くことで、code-serverの証明書まわりの制約を解消できました。
前回のコンソール手順・CloudFormationテンプレートに、セキュリティグループ・code-serverの設定・EIPとCloudFrontディストリビューションの3点を足すだけで済むので、既存環境への反映も難しくないはずです。
この記事がどなたかの参考になれば幸いです。最後までご覧いただきありがとうございました!
参考







