| name | sakura-cloud-iaas |
| description | Sakura Cloud IaaS API (iaas-api-go) ライブラリの使用ガイド。
さくらインターネットのクラウドサービスで、サーバー、ディスク、スイッチ、ロードバランサーなどのIaaSリソースをGoで操作する際に使用。
リソースの作成・取得・更新・削除、電源操作、検索・フィルタリング、エラーハンドリング、フェイクモードでのテストについてガイドする。
ユーザーが「さくらクラウド」「Sakura Cloud」「IaaS」「サーバー作成」「スイッチ作成」「ディスク作成」「リソース管理」「電源操作」「リソース検索」「APIクライアント」「Goでさくら」などの言葉を使ったら、このスキルを参照すること。
|
Sakura Cloud IaaS API (iaas-api-go) Skill
Overview
このスキルは、さくらクラウドのIaaSサービスをGoから操作するための iaas-api-go ライブラリの使い方を提供します。
このライブラリを使用する際は:
- クライアント初期化 - APIトークンを使用してクライアントを作成
- リソースオペレーション - オペレーションを作成して操作対象を選択
- CRUD操作 - 作成・取得・更新・削除を実行
- 検索 - フィルタリングとソートでリソースを検索
- エラーハンドリング - APIエラーを適切に処理
インストール
go get
go get github.com/sacloud/iaas-api-go
推奨される依存パッケージ(helper/api などを使用する場合):
go get github.com/sacloud/api-client-go
go get github.com/sacloud/packages-go
go.mod の例:
module your-project
go 1.22
require (
github.com/sacloud/iaas-api-go v1.14.0
github.com/sacloud/api-client-go v0.3.5
github.com/sacloud/packages-go v0.1.0
)
依存関係の自動解決
iaas-api-go をインポートすれば、Go Modules が自動的に必要な依存関係を解決してインストールします。
基本的なインポート例:
import (
"github.com/sacloud/iaas-api-go"
"github.com/sacloud/iaas-api-go/helper/api"
"github.com/sacloud/iaas-api-go/helper/power"
"github.com/sacloud/iaas-api-go/helper/wait"
"github.com/sacloud/iaas-api-go/helper/query"
"github.com/sacloud/iaas-api-go/helper/cleanup"
"github.com/sacloud/iaas-api-go/helper/plans"
"github.com/sacloud/iaas-api-go/search"
"github.com/sacloud/iaas-api-go/types"
"github.com/sacloud/iaas-api-go/ostype"
)
ドキュメント・リファレンス
関連プロジェクト
クライアント初期化
基本的な方法
APIトークンを直接使用する場合:
package main
import (
"context"
"github.com/sacloud/iaas-api-go"
)
func main() {
ctx := context.Background()
client := iaas.NewClientFromEnv()
client := iaas.NewClient(token, secret)
}
環境変数:
SAKURACLOUD_ACCESS_TOKEN - APIアクセストークン
SAKURACLOUD_ACCESS_TOKEN_SECRET - シークレット
helper/apiパッケージを使用(推奨)
より高度な設定が必要な場合:
import (
"github.com/sacloud/api-client-go"
"github.com/sacloud/iaas-api-go/helper/api"
)
opts, err := api.DefaultOption()
if err != nil {
log.Fatal(err)
}
caller := api.NewCallerWithOptions(opts)
opts := &api.CallerOptions{
Options: &client.Options{
AccessToken: token,
AccessTokenSecret: secret,
},
DefaultZone: "is1a",
TraceAPI: true,
}
caller := api.NewCallerWithOptions(opts)
リソース操作パターン
多くのリソースで共通のCRUDパターンが使用されます:
resourceOp := iaas.NewXxxOp(client)
result, err := resourceOp.Create(ctx, zone, request)
result, err := resourceOp.Read(ctx, zone, id)
result, err := resourceOp.Update(ctx, zone, id, request)
err := resourceOp.Delete(ctx, zone, id)
result, err := resourceOp.Find(ctx, zone, condition)
操作パターンの種類
1. フルCRUD(作成・取得・更新・削除)
Server, Disk, Switch, Internet, LoadBalancer, VPCRouter, Database, Archive, SSHKey など
2. 読み取り専用(検索・取得のみ)
Zone, Region, ServerPlan, DiskPlan, LicenseInfo, PrivateHostPlan など
3. 設定のみ更新(UpdateSettings)
AutoBackup, DNS, GSLB, SimpleMonitor などは設定のみを更新
4. アプライアンス特有(電源操作付き)
Database, LoadBalancer, VPCRouter, NFS などは Boot/Shutdown/Reset を持つ
5. 特殊操作
Bill(請求), AuthStatus(認証), Coupon(クーポン)などは専用メソッド
利用可能なオペレーション:
コンピューティング:
NewServerOp() - サーバー
NewServerPlanOp() - サーバープラン
NewPrivateHostOp() - 専有ホスト
NewPrivateHostPlanOp() - 専有ホストプラン
ストレージ:
NewDiskOp() - ディスク
NewDiskPlanOp() - ディスクプラン
NewArchiveOp() - アーカイブ/ISOイメージ
NewCDROMOp() - CD-ROM
ネットワーク:
NewSwitchOp() - スイッチ
NewInternetOp() - ルーター
NewInternetPlanOp() - インターネットプラン
NewInterfaceOp() - ネットワークインターフェース
NewSubnetOp() - サブネット
NewBridgeOp() - ブリッジ
NewIPAddressOp() - IPアドレス
NewIPv6NetOp() - IPv6ネット
NewIPv6AddrOp() - IPv6アドレス
NewPacketFilterOp() - パケットフィルタ
アプライアンス:
NewLoadBalancerOp() - ロードバランサー
NewVPCRouterOp() - VPCルーター
NewDatabaseOp() - データベース
NewNFSOp() - NFS
NewNASOp() - NAS
NewMobileGatewayOp() - モバイルゲートウェイ
DNS/アクセス制御:
NewDNSOp() - DNS
NewGSLBOp() - GSLB
NewSimpleMonitorOp() - シンプル監視
認証/セキュリティ:
NewSSHKeyOp() - SSH鍵
NewCertificateAuthorityOp() - 証明書認証局
NewLicenseOp() - ライセンス
NewLicenseInfoOp() - ライセンス情報
コンテナ/レジストリ:
NewContainerRegistryOp() - コンテナレジストリ
自動化:
NewAutoScaleOp() - オートスケール
NewAutoBackupOp() - 自動バックアップ
NewESMEOp() - ESME(SMS送信)
通知:
NewSimpleNotificationDestinationOp() - シンプル通知宛先
NewSimpleNotificationGroupOp() - シンプル通知グループ
その他:
NewIconOp() - アイコン
NewNoteOp() - スタートアップスクリプト
NewProxyLBOp() - エンハンスドロードバランサー
NewLocalRouterOp() - ローカルルーター
NewEnhancedDBOp() - エンハンスドデータベース
NewSIMOp() - SIM
NewBillOp() - 請求
NewCouponOp() - クーポン
NewServiceClassOp() - サービスクラス
NewZoneOp() - ゾーン
NewRegionOp() - リージョン
NewAuthStatusOp() - 認証ステータス
リソースの作成
各リソースには専用のCreateRequest構造体があります:
sw, err := iaas.NewSwitchOp(client).Create(ctx, "is1a", &iaas.SwitchCreateRequest{
Name: "my-switch",
Description: "説明",
Tags: types.Tags{"env:prod", "app:web"},
})
server, err := iaas.NewServerOp(client).Create(ctx, "is1a", &iaas.ServerCreateRequest{
CPU: 1,
MemoryMB: 1024,
Commitment: types.Commitments.Standard,
Generation: types.PlanGenerations.Default,
ConnectedSwitches: []*iaas.ConnectedSwitch{{Scope: types.Scopes.Shared}},
InterfaceDriver: types.InterfaceDrivers.VirtIO,
Name: "my-server",
Description: "説明",
})
disk, err := iaas.NewDiskOp(client).Create(ctx, "is1a", &iaas.DiskCreateRequest{
Name: "my-disk",
SizeMB: 20 * 1024,
DiskPlanID: types.DiskPlans.SSD,
Connection: types.DiskConnections.VirtIO,
}, nil, 0)
OSイメージからディスク作成
import (
"github.com/sacloud/iaas-api-go/helper/query"
"github.com/sacloud/iaas-api-go/ostype"
)
archive, err := query.FindArchiveByOSType(ctx, iaas.NewArchiveOp(client), "is1a", ostype.Ubuntu)
if err != nil {
log.Fatal(err)
}
disk, err := iaas.NewDiskOp(client).Create(ctx, "is1a", &iaas.DiskCreateRequest{
Name: "ubuntu-disk",
SizeMB: 40 * 1024,
DiskPlanID: types.DiskPlans.SSD,
Connection: types.DiskConnections.VirtIO,
SourceArchiveID: archive.ID,
}, nil, 0)
サーバー+ディスク一括作成
server, err := iaas.NewServerOp(client).Create(ctx, "is1a", &iaas.ServerCreateRequest{
CPU: 2,
MemoryMB: 4 * 1024,
Name: "web-server",
Commitment: types.Commitments.Standard,
Generation: types.PlanGenerations.Default,
ConnectedSwitches: []*iaas.ConnectedSwitch{{Scope: types.Scopes.Shared}},
})
disk, err := iaas.NewDiskOp(client).Create(ctx, "is1a", &iaas.DiskCreateRequest{
Name: "web-server-disk",
SizeMB: 100 * 1024,
DiskPlanID: types.DiskPlans.SSD,
Connection: types.DiskConnections.VirtIO,
ServerID: server.ID,
}, nil, 0)
リソースの取得と更新
server, err := iaas.NewServerOp(client).Read(ctx, "is1a", serverID)
server, err = iaas.NewServerOp(client).Update(ctx, "is1a", serverID, &iaas.ServerUpdateRequest{
Name: "my-server-renamed",
Description: "更新された説明",
Tags: types.Tags{"tag1"},
})
リソースの一覧と検索
FindConditionを使用して検索・フィルタリング:
import (
"github.com/sacloud/iaas-api-go"
"github.com/sacloud/iaas-api-go/search"
)
result, err := iaas.NewServerOp(client).Find(ctx, "is1a", nil)
condition := &iaas.FindCondition{
Filter: search.Filter{
search.Key("Name"): search.PartialMatch("example"),
search.Key("Tags"): search.AndEqual("production"),
search.Key("Zone.Name"): search.OrEqual("is1a", "is1b"),
},
Count: 20,
From: 0,
Sort: search.SortKeys{{Key: "CreatedAt", Order: search.SortDesc}},
}
result, err := iaas.NewServerOp(client).Find(ctx, "is1a", condition)
for _, server := range result.Servers {
fmt.Printf("Server: %s (ID: %d)\n", server.Name, server.ID)
}
検索フィルタ:
search.PartialMatch(str) - 部分一致
search.OrEqual(val1, val2...) - いずれかに一致
search.AndEqual(val1, val2...) - すべてに一致
search.KeyWithOp(key, search.OpLessThan) - 数値比較(<, >, <=, >=)
helper/query - 便利な検索クエリ
import "github.com/sacloud/iaas-api-go/helper/query"
archive, err := query.FindArchiveByOSType(ctx, archiveOp, "is1a", ostype.Ubuntu)
plan, err := query.FindServerPlan(ctx, serverPlanOp, "is1a", &query.FindServerPlanRequest{
CPU: 2,
MemoryGB: 4,
Commitment: types.Commitments.Standard,
Generation: types.PlanGenerations.Default,
})
dbPlan, err := query.FindDatabasePlan(ctx, databasePlanOp, "is1a", &query.FindDatabasePlanRequest{
CPU: 2,
MemoryGB: 4,
})
nfsPlan, err := query.FindNFSPlan(ctx, nfsPlanOp, "is1a", &query.FindNFSPlanRequest{
SizeGB: 100,
Plan: types.NFSPlans.HDD,
})
リソースの削除
err := iaas.NewServerOp(client).Delete(ctx, "is1a", serverID)
helper/cleanup - クリーンアップ削除
リソースと関連リソースをまとめて削除:
import "github.com/sacloud/iaas-api-go/helper/cleanup"
err := cleanup.DeleteServer(ctx, client, "is1a", serverID, true)
err := cleanup.DeleteServer(ctx, client, "is1a", serverID, false)
err := cleanup.DeleteSwitch(ctx, client, "is1a", switchID)
err := cleanup.DeleteDisk(ctx, client, "is1a", diskID)
err := cleanup.DeleteInternet(ctx, client, "is1a", routerID)
err := cleanup.DeleteBridge(ctx, client, "is1a", bridgeID)
注意: DeleteServer はサーバーが起動中の場合、強制シャットダウンしてから削除します。
電源操作
ヘルパーパッケージを使用:
import "github.com/sacloud/iaas-api-go/helper/power"
err = power.BootServer(ctx, serverOp, "is1a", serverID)
err = power.ShutdownServer(ctx, serverOp, "is1a", serverID, true)
利用可能な電源操作:
power.BootServer() / power.ShutdownServer() - サーバー
power.BootLoadBalancer() / power.ShutdownLoadBalancer() - ロードバランサー
power.BootDatabase() / power.ShutdownDatabase() - データベース
power.BootVPCRouter() / power.ShutdownVPCRouter() - VPCルーター
power.BootNFS() / power.ShutdownNFS() - NFS
power.BootMobileGateway() / power.ShutdownMobileGateway() - モバイルゲートウェイ
待機処理
リソースの準備ができるまで待機:
import "github.com/sacloud/iaas-api-go/helper/wait"
server, err := wait.UntilServerIsUp(ctx, serverOp, "is1a", serverID)
disk, err := wait.UntilDiskIsReady(ctx, diskOp, "is1a", diskID)
db, err := wait.UntilDatabaseIsUp(ctx, dbOp, "is1a", dbID)
router, err := wait.UntilVPCRouterIsUp(ctx, routerOp, "is1a", routerID)
helper/plans - プラン変更
サーバーやルーターのプランを変更:
import "github.com/sacloud/iaas-api-go/helper/plans"
server, err := plans.ChangeServerPlan(ctx, client, "is1a", serverID, &iaas.ServerChangePlanRequest{
CPU: 4,
MemoryMB: 8 * 1024,
})
router, err := plans.ChangeRouterPlan(ctx, client, "is1a", routerID, 100)
エラーハンドリング
if iaas.IsNotFoundError(err) {
}
if iaas.IsNoResultsError(err) {
}
if iaas.IsStillCreatingError(err) {
}
if apiErr, ok := err.(iaas.APIError); ok {
responseCode := apiErr.ResponseCode()
errorCode := apiErr.Code()
message := apiErr.Message()
}
カスタムHTTPリクエスト
通常はOpを使用しますが、生のHTTPリクエストが必要な場合:
client := iaas.NewClientFromEnv()
url := "https://secure.sakura.ad.jp/cloud/zone/is1a/api/cloud/1.1/zone"
data, err := client.Do(ctx, http.MethodGet, url, nil)
var result struct {
Zones []*naked.Zone
}
err = json.Unmarshal(data, &result)
フェイクモード(テスト)
実際のさくらクラウドAPIを呼び出さずにテストするためのモックモードです。テストや開発時に使用します。
FakeModeとは
FakeModeでは:
- 実際のAPIサーバーには通信しません
- メモリ上でデータを管理します(デフォルト)
- 必要に応じてファイルに永続化可能です
- すべてのAPI操作が即座に完了します(待機不要)
- IDはFakeMode内部で自動採番されます
基本的な使い方
import (
"github.com/sacloud/api-client-go"
"github.com/sacloud/iaas-api-go/helper/api"
)
opts := &api.CallerOptions{
Options: &client.Options{
AccessToken: "dummy",
AccessTokenSecret: "dummy",
},
FakeMode: true,
}
caller := api.NewCallerWithOptions(opts)
serverOp := iaas.NewServerOp(caller)
server, err := serverOp.Create(ctx, "is1a", &iaas.ServerCreateRequest{
CPU: 1,
MemoryMB: 1024,
Name: "test-server",
Commitment: types.Commitments.Standard,
Generation: types.PlanGenerations.Default,
ConnectedSwitches: []*iaas.ConnectedSwitch{},
})
fmt.Printf("Created server with ID: %d\n", server.ID)
ファイル永続化(オプション)
テストデータをファイルに保存する場合はFakeStorePathを指定します:
opts := &api.CallerOptions{
Options: &client.Options{
AccessToken: "dummy",
AccessTokenSecret: "dummy",
},
FakeMode: true,
FakeStorePath: "/tmp/my-fake-store.json",
}
caller := api.NewCallerWithOptions(opts)
server, err := iaas.NewServerOp(caller).Create(ctx, "is1a", &iaas.ServerCreateRequest{...})
注意: FakeStorePathを使用すると、DataStoreがグローバルに変更されます。テスト間でデータを共有する場合は、同じcallerインスタンスを使用するか、ファイルを明示的に読み込み直してください。
実践的なテスト例
package main
import (
"context"
"fmt"
"testing"
"github.com/sacloud/api-client-go"
"github.com/sacloud/iaas-api-go"
"github.com/sacloud/iaas-api-go/helper/api"
"github.com/sacloud/iaas-api-go/helper/power"
"github.com/sacloud/iaas-api-go/types"
)
func TestServerLifecycle(t *testing.T) {
ctx := context.Background()
caller := api.NewCallerWithOptions(&api.CallerOptions{
Options: &client.Options{
AccessToken: "test",
AccessTokenSecret: "test",
},
FakeMode: true,
})
serverOp := iaas.NewServerOp(caller)
server, err := serverOp.Create(ctx, "is1a", &iaas.ServerCreateRequest{
CPU: 1,
MemoryMB: 1024,
Name: "test-server",
Commitment: types.Commitments.Standard,
Generation: types.PlanGenerations.Default,
ConnectedSwitches: []*iaas.ConnectedSwitch{},
})
if err != nil {
t.Fatalf("Failed to create server: %v", err)
}
t.Logf("Created server: ID=%d, Name=%s", server.ID, server.Name)
if err := power.BootServer(ctx, serverOp, "is1a", server.ID); err != nil {
t.Fatalf("Failed to boot server: %v", err)
}
server, _ = serverOp.Read(ctx, "is1a", server.ID)
if server.InstanceStatus != types.ServerInstanceStatuses.Up {
t.Errorf("Server should be up, got %s", server.InstanceStatus)
}
if err := power.ShutdownServer(ctx, serverOp, "is1a", server.ID, true); err != nil {
t.Fatalf("Failed to shutdown server: %v", err)
}
if err := serverOp.Delete(ctx, "is1a", server.ID); err != nil {
t.Fatalf("Failed to delete server: %v", err)
}
_, err = serverOp.Read(ctx, "is1a", server.ID)
if !iaas.IsNotFoundError(err) {
t.Errorf("Expected NotFoundError after delete, got: %v", err)
}
t.Log("Server deleted successfully")
}
FakeModeの特徴と注意点
メリット:
- ネットワークに依存せず、高速にテストできる
- 実際のAPI利用料金がかからない
- 副作用なしでCRUD操作を試せる
注意点:
- AccessToken/Secretは必須:FakeModeでも
CallerOptions.Optionsにダミー値を設定する必要があります
- データはプロセス内で共有される:デフォルトのInMemoryStoreでは、同じプロセス内のすべてのFakeModeクライアントでデータが共有されます。テスト間でデータを独立させたい場合は、明示的にクリーンアップしてください
- JSONFileStoreはグローバルに変更される:
FakeStorePathを指定するとfake.DataStoreがグローバルに書き換わり、すべてのFakeModeクライアントが同じファイルを参照します
- 一部の機能制限:実際のネットワーク接続検証などはできません
テストユーティリティとの組み合わせ
func NewFakeCaller(t *testing.T) iaas.APICaller {
t.Helper()
return api.NewCallerWithOptions(&api.CallerOptions{
Options: &client.Options{
AccessToken: "fake-test",
AccessTokenSecret: "fake-test",
},
FakeMode: true,
})
}
func TestCreateSwitch(t *testing.T) {
caller := NewFakeCaller(t)
switchOp := iaas.NewSwitchOp(caller)
sw, err := switchOp.Create(context.Background(), "is1a", &iaas.SwitchCreateRequest{
Name: "test-switch",
})
if err != nil {
t.Fatal(err)
}
if sw.Name != "test-switch" {
t.Errorf("Expected name 'test-switch', got %s", sw.Name)
}
if sw.ID <= 0 {
t.Errorf("Expected positive ID, got %d", sw.ID)
}
}
スタートアップスクリプト(cloud-config / UserData)
サーバー起動時にcloud-configやシェルスクリプトを実行できます。
スタートアップスクリプト(Note)の作成
import "github.com/sacloud/iaas-api-go"
noteOp := iaas.NewNoteOp(client)
cloudConfigContent := `#cloud-config
hostname: my-server
fqdn: my-server.example.com
packages:
- nginx
- git
runcmd:
- systemctl start nginx
`
note, err := noteOp.Create(ctx, &iaas.NoteCreateRequest{
Name: "cloud-config-example",
Content: cloudConfigContent,
Class: "cloud-config",
Tags: types.Tags{"env:production"},
})
スクリプトクラスの種類
cloud-config - cloud-init形式の設定
shell - シェルスクリプト
yaml_kernel - YAMLカーネルパラメータ
ディスク作成時にUserDataを設定
diskOp := iaas.NewDiskOp(client)
disk, err := diskOp.CreateWithConfig(ctx, "is1a",
&iaas.DiskCreateRequest{
Name: "server-disk",
SizeMB: 20 * 1024,
DiskPlanID: types.DiskPlans.SSD,
},
&iaas.DiskEditRequest{
HostName: "my-server",
Password: "initial-password",
Notes: []*iaas.DiskEditNote{
{
ID: note.ID,
Variables: map[string]interface{}{
"SERVER_ROLE": "web",
"ENV": "production",
},
},
},
SSHKeys: []*iaas.DiskEditSSHKey{
{PublicKey: "ssh-rsa AAAAB3..."},
},
DisablePWAuth: true,
},
false,
nil,
0,
)
既存ディスクにUserDataを適用
err = diskOp.Config(ctx, "is1a", diskID, &iaas.DiskEditRequest{
HostName: "renamed-server",
DisablePWAuth: true,
Notes: []*iaas.DiskEditNote{
{ID: noteID},
},
SSHKeys: []*iaas.DiskEditSSHKey{
{PublicKey: "ssh-rsa AAAAB3..."},
},
})
一般的な定数
import "github.com/sacloud/iaas-api-go/types"
"is1a"
"is1b"
"tk1a"
"tk1b"
types.DiskPlans.HDD
types.DiskPlans.SSD
types.Commitments.Standard
types.Scopes.Shared
types.Scopes.User
types.InterfaceDrivers.VirtIO
types.InterfaceDrivers.E1000
types.ServerInstanceStatuses.Up
types.ServerInstanceStatuses.Down
実践例:完全なCRUDフロー
package main
import (
"context"
"log"
"os"
"github.com/sacloud/iaas-api-go"
"github.com/sacloud/iaas-api-go/helper/power"
"github.com/sacloud/iaas-api-go/types"
)
func main() {
ctx := context.Background()
client := iaas.NewClientFromEnv()
serverOp := iaas.NewServerOp(client)
server, err := serverOp.Create(ctx, "is1a", &iaas.ServerCreateRequest{
CPU: 1,
MemoryMB: 1024,
Name: "example-server",
Commitment: types.Commitments.Standard,
Generation: types.PlanGenerations.Default,
ConnectedSwitches: []*iaas.ConnectedSwitch{},
})
if err != nil {
log.Fatal(err)
}
if err := power.BootServer(ctx, serverOp, "is1a", server.ID); err != nil {
log.Fatal(err)
}
server, err = serverOp.Update(ctx, "is1a", server.ID, &iaas.ServerUpdateRequest{
Name: "example-server-renamed",
})
if err != nil {
log.Fatal(err)
}
if err := power.ShutdownServer(ctx, serverOp, "is1a", server.ID, true); err != nil {
log.Fatal(err)
}
if err := serverOp.Delete(ctx, "is1a", server.ID); err != nil {
log.Fatal(err)
}
log.Println("Complete!")
}