はじめに

Oracle Cloudを試している途中で、手元のWindowsではブラウザ認証できるものの、実際にOCI CLIを使いたいUbuntuサーバー側へ認証セッションを持っていく作業が少し面倒になった。

OCI CLIには、ブラウザのある端末で作成したセッションをexportし、別の端末でimportする仕組みが用意されている。手作業でも難しくはないが、セッションを作り直すたびに同じ操作を繰り返すことになる。

そこで、Windows側でのブラウザ認証からUbuntuへの転送、import、最後の認証確認までをPowerShellでまとめた。

先にスクリプト

Windows側のPowerShellから実行する。少なくとも $Region$ProfileName$UbuntuUser$UbuntuHost は自分の環境に合わせて変更する。

# ==============================
# 設定
# ==============================

$Region = "ap-osaka-1"
$ProfileName = "terraform-test"
$SessionMinutes = 60

$UbuntuUser = "ubuntu"
$UbuntuHost = "192.168.1.50"

$ExportBase = "$HOME\terraform-test"
$ExportZip = "$ExportBase.zip"

$RemoteZip = "/tmp/terraform-test.zip"
$RemoteOciConfig = "~/.oci/config"

$SshTarget = "${UbuntuUser}@${UbuntuHost}"

# 最後にEnter待ちするか
$PauseAtEnd = $true


# ==============================
# 外部コマンドの結果確認
# ==============================

function Test-CommandResult {
    param (
        [string]$Message
    )

    if ($LASTEXITCODE -ne 0) {
        throw "$Message (ExitCode: $LASTEXITCODE)"
    }
}


# ==============================
# メイン処理
# ==============================

try {

    Write-Host ""
    Write-Host "========================================"
    Write-Host " OCI Session Update"
    Write-Host "========================================"
    Write-Host ""

    # --------------------------
    # OCIセッション作成
    # --------------------------

    Write-Host "[1/5] OCIのブラウザ認証を開始します..."

    oci session authenticate `
        --region $Region `
        --profile-name $ProfileName `
        --session-expiration-in-minutes $SessionMinutes

    Test-CommandResult "OCI認証に失敗しました"

    Write-Host "[OK] OCI認証完了"
    Write-Host ""


    # --------------------------
    # セッションexport
    # --------------------------

    Write-Host "[2/5] セッションをexportします..."

    oci session export `
        --profile $ProfileName `
        --output-file $ExportBase `
        --force

    Test-CommandResult "セッションのexportに失敗しました"

    if (-not (Test-Path $ExportZip)) {
        throw "Exportファイルが見つかりません: $ExportZip"
    }

    Write-Host "[OK] Export完了: $ExportZip"
    Write-Host ""


    # --------------------------
    # Ubuntuへ転送
    # --------------------------

    Write-Host "[3/5] Ubuntuサーバーへ転送します..."

    scp $ExportZip "${SshTarget}:${RemoteZip}"

    Test-CommandResult "Ubuntuへの転送に失敗しました"

    Write-Host "[OK] 転送完了"
    Write-Host ""


    # --------------------------
    # Ubuntu側へimport
    # --------------------------

    Write-Host "[4/5] Ubuntu側へセッションをimportします..."

    ssh $SshTarget "mkdir -p ~/.oci && touch $RemoteOciConfig && chmod 700 ~/.oci && chmod 600 $RemoteOciConfig && oci session import --session-archive $RemoteZip --force && rm -f $RemoteZip"

    Test-CommandResult "Ubuntu側のセッションimportに失敗しました"

    Write-Host "[OK] Import完了"
    Write-Host ""


    # --------------------------
    # Ubuntu側で認証確認
    # --------------------------

    Write-Host "[5/5] Ubuntu側のOCI認証を確認します..."

    ssh $SshTarget "oci session validate --profile $ProfileName --auth security_token"

    Test-CommandResult "Ubuntu側のOCI認証確認に失敗しました"


    Write-Host ""
    Write-Host "========================================"
    Write-Host " SUCCESS"
    Write-Host " OCIセッションの更新が完了しました。"
    Write-Host "========================================"
    Write-Host ""
}
catch {

    Write-Host ""
    Write-Host "========================================"
    Write-Host " ERROR"
    Write-Host "========================================"
    Write-Host ""

    Write-Error $_.Exception.Message

    Write-Host ""
    Write-Host "処理は完了していません。"
    Write-Host ""
}
finally {

    if ($PauseAtEnd) {
        Read-Host "Enterキーを押すと終了します"
    }
}

何を自動化しているのか

スクリプトで行っているのは次の5つ。

Windows

oci session authenticate

oci session export

scpでUbuntuへ転送

Ubuntuでoci session import

oci session validate

最初の oci session authenticate ではブラウザが開くので、そこだけは自分でログインする。認証が終われば、その後はPowerShellからUbuntu側の確認まで進む。

Oracleのドキュメントにも、Webブラウザのあるコンピューターでセッションを作成・exportし、Webブラウザのない別のコンピューターへimportする手順が載っている。

OCI CLIに用意されているexport/importを使い、毎回手で実行していた部分だけPowerShellにまとめた。

手作業でもできるが、何度もやると面倒だった

Windows側でセッションを作るところまでは簡単だった。

oci session authenticate `
    --region ap-osaka-1 `
    --profile-name terraform-test `
    --session-expiration-in-minutes 60

ブラウザで認証したあと、Ubuntuへ持っていくにはセッションをexportする。

oci session export `
    --profile terraform-test `
    --output-file "$HOME\terraform-test" `
    --force

生成されたZIPをUbuntuへコピーする。

scp "$HOME\terraform-test.zip" [email protected]:/tmp/terraform-test.zip

Ubuntu側へ入り、importする。

mkdir -p ~/.oci
touch ~/.oci/config
chmod 700 ~/.oci
chmod 600 ~/.oci/config

oci session import \
  --session-archive /tmp/terraform-test.zip \
  --force

最後にセッションが使えるか確認する。

oci session validate \
  --profile terraform-test \
  --auth security_token

一度だけならこれで困らない。ただ、短時間のセッションを使いながら試行錯誤していると、ブラウザ認証のたびにexport、SCP、SSH、import、validateと進めるのが煩わしくなった。

oci session authenticate--session-expiration-in-minutes は、2026年9月時点のOCI CLIドキュメントでは5〜60分を指定でき、未指定時は60分になっている。今回は最大の60分にしている。

PowerShell側では失敗した場所で止める

このスクリプトでは ociscpssh を続けて呼ぶ。どこかで失敗したらその時点で止まってほしいので、各コマンドの実行後に $LASTEXITCODE を確認し、0以外なら throw するようにした。

function Test-CommandResult {
    param (
        [string]$Message
    )

    if ($LASTEXITCODE -ne 0) {
        throw "$Message (ExitCode: $LASTEXITCODE)"
    }
}

throw すると catch に入るため、エラーになった段階を表示して処理を終える。

exportについては終了コードだけでなく、想定したZIPが実際に作られているかも確認した。

if (-not (Test-Path $ExportZip)) {
    throw "Exportファイルが見つかりません: $ExportZip"
}

Ubuntu側の準備もSSH越しに済ませる

Ubuntu側では ~/.oci/config が存在していない状態もあったので、import前にディレクトリとファイルを作るようにした。

mkdir -p ~/.oci
touch ~/.oci/config
chmod 700 ~/.oci
chmod 600 ~/.oci/config

そのあとに oci session import を実行し、成功した場合は転送したZIPを削除している。

oci session import --session-archive /tmp/terraform-test.zip --force && rm -f /tmp/terraform-test.zip

最後に oci session validate も通しているので、転送しただけで終わらず、Ubuntu側で実際に認証できるところまで確認できる。

実行前に必要なもの

今回のスクリプトは、次の状態を前提にしている。

環境必要なもの
WindowsPowerShell、OCI CLI、sshscp、Webブラウザ
UbuntuOCI CLI、SSHでログインできる状態

WindowsのOpenSSH Clientが使える環境なら、sshscp はそのままPowerShellから呼び出せる。

scpssh を何度か呼ぶので、SSH鍵でログインできる状態を想定している。パスワード認証でも実行できるが、その場合は途中で何度も入力が必要になる。

設定部分で主に変更するのは次の値になる。

変数内容
$RegionOCIのリージョン
$ProfileName作成・転送するOCI CLIプロファイル名
$SessionMinutesセッションの有効時間
$UbuntuUserUbuntuへSSH接続するユーザー
$UbuntuHostUbuntuサーバーのホスト名またはIPアドレス
$ExportBaseWindows側のexport先
$RemoteZipUbuntu側へ一時的に置くZIPのパス

セッションのZIPは認証情報として扱う

今のスクリプトでは、Ubuntu側のZIPはimportが成功したあとに削除しているが、Windows側へexportしたZIPは削除していない。また、Ubuntu側もimportより前に失敗すると、&& rm -f まで到達せず /tmp にZIPが残る。

今回は実際に使ったスクリプトをそのまま載せているが、今後も使うならここは直したい。Windows側も処理後に削除し、Ubuntu側も失敗時を含めて後始末する形にするつもりだ。一時ファイルの権限も明示した方がよさそうだ。

OCIにはほかの認証方法もある

今回はOracle Cloudを試し始めた段階で、自分のWindowsからUbuntuサーバーへ一時的なCLIセッションを渡したかった。Oracleが用意しているsessionのexport/importがそのまま使えた。

OCI Compute InstanceからOCIのサービスへアクセスする場合は、Instance Principalという認証方法も用意されている。ユーザーの認証情報をホストへ配布せずに済むため、環境によってはこちらの方が合う。

まだOracle Cloudに慣れていないので、今後使い方が変われば認証方法も変えるかもしれない。少なくとも試している最中は、ブラウザ認証以外を1回のPowerShell実行で済ませられるようになってかなり楽になった。