
Bicep ユーザーの皆様こんにちは。
皆さんBicepでKubernetesリソースの作成をできるのをご存知ですか?AKSの作成ではありません。kubectl apply相当のことができるのです。
2023年4月現在まだプレビューの機能ですが、こちらをご紹介したいと思います。ちなみにMicrosoftのドキュメントはこちらです。
プレビュー機能を有効にする
まだプレビュー機能ということで、プレビューの拡張機能を使うよ という宣言をしなければなりません。bicepconfig.jsonでその宣言を行います。lintの指定を行っている方はすでにファイルは存在していると思いますのでそちらに追加してください。それ以外の方はローカルフォルダ、またはその上位のフォルダのどこかにbicepconfig.jsonというファイルを作成してください。
{ "experimentalFeaturesEnabled": { "extensibility": true } }
YamlからBicepへの変換
VSCodeのbicep extensionでKuberentes manifestをBicepファイルに変換する機能が備わっています。
コマンドパレットを開き bicep と入力すると、候補の中に Import Kubernetes Manifest (EXPERIMENTAL)` というものがあります。KubernetesのYamlファイルを選択しこちらを実行すると、bicepファイルに変換してくれます。

例えば つぎのようなServiceAccount作成のものを指定した場合
apiVersion: v1 kind: ServiceAccount metadata: annotations: azure.workload.identity/client-id: ${APP_CLIENT_ID} labels: azure.workload.identity/use: "true" app: app name: ${APP_SA} namespace: ${APP_NAMESPACE}
Importを実行すると
@secure()
param kubeConfig string
import 'kubernetes@1.0.0' with {
namespace: 'default'
kubeConfig: kubeConfig
}
resource coreServiceAccount_APP_SA 'core/ServiceAccount@v1' = {
metadata: {
annotations: {
'azure.workload.identity/client-id': '\${APP_CLIENT_ID}'
}
labels: {
'azure.workload.identity/use': 'true'
app: 'app'
}
name: '\${APP_SA}'
namespace: '\${APP_NAMESPACE}'
}
}
と変換されます。このbicepファイルをあとは普通に利用するだけ。例えばnamespaceも一緒に作成するのであれば以下のようなものを作ればよいことになります(namespaceのyamlからimport実施済みの想定)
@secure()
param kubeConfig string
param clientId string
param namespace string
param serviceAccountName string
param labels object = {}
import 'kubernetes@1.0.0' with {
namespace: 'default'
kubeConfig: kubeConfig
}
resource coreNamespace_NAMESPACE 'core/Namespace@v1' = {
metadata: {
name: namespace
}
}
var actualLabels = union(labels, { 'azure.workload.identity/use': 'true' })
resource coreServiceAccount_SA 'core/ServiceAccount@v1' = {
metadata: {
annotations: {
'azure.workload.identity/client-id': applicationId
}
labels: actualLabels
name: serviceAccountName
namespace: namespace
}
}
KubernetesConfigって・・・
上記で作成したBicepファイルで
import 'kubernetes@1.0.0' with {
namespace: 'default'
kubeConfig: kubeConfig
}
という部分があったと思います。これが今回の機能の肝で、Kubernetesプロバイダーというものになります。 Microsoftのドキュメントを見ると、ここのnamespaceはプロバイダーの名前空間、kubeConfigは Kubernetesクラスター管理者資格情報のbase64でエンコードされた値を指定することになっています。
kubeConfigはつぎのように渡すとよいそうです(Microsoftドキュメントより)
resource aks 'Microsoft.ContainerService/managedClusters@2022-05-02-preview' existing = {
name: 'demoAKSCluster'
}
module kubernetes './kubernetes.bicep' = {
name: 'buildbicep-deploy'
params: {
kubeConfig: aks.listClusterAdminCredential().kubeconfigs[0].value
}
}
なにが嬉しいか
AKSへのデプロイはkubectlでやればいいじゃないか?とも思いますが、次のようなケースで便利です。 例えば、Workload identityを利用する場合、AzureでユーザーマネージドIDを作成し、それとAKS内のServiceAccountを紐付けるということを行います。ServiceAccountにはユーザーマネージドIDのClientIDを指定する必要がありますが、すべてをBicepで実行できれば次のように一連の作業で登録することが可能になります。
すべてのAKSリソースをBicepで作成する必要はないと思いますが、今回のようにAzureのリソースを作成し、その内容をベースにYamlの設定に反映してリソース作成するといったケースではこうしたオプションがあると便利です。
param name string = 'sample'
param location string = resourceGroup().location
param giteaIdentityName string = 'app-${aksClusterName}'
param federetedCredentialName string = appIdentityName
param aksClusterName string = '${name}-aks'
param k8sNamespace string = 'app'
param k8sServiceAccount string = 'app-sa'
param keyvaultName string = '${name}-kv'
// ユーザーマネージドID作成
module userIdentity './user-managed-id.bicep' = {
name: 'app-id-assign-${appIdentityName}'
params: {
name: giteaIdentityName
location: location
tags: tags
}
}
resource aks 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' existing = {
name: aksClusterName
}
// Federated Credentialの作成
module federatedCredential './user-id-federeted-credential.bicep' = {
name: 'app-id-federation-${federetedCredentialName}'
params: {
federationName: federetedCredentialName
issuerUrl: aks.properties.oidcIssuerProfile.issuerURL
subject: 'system:serviceaccount:${k8sNamespace}:${k8sServiceAccount}'
userIdentityName: userIdentity.outputs.idName
}
}
// assigned keyvault access control
module assignKvAcceccPolicy './kv-access-policies.bicep' = {
name: 'app-${name}-policy-${keyvaultName}'
params: {
kvName: keyvaultName
principalId: userIdentity.outputs.principalId
keys: [ 'get' ]
secrets: [ 'get' ]
certificates: [ 'get' ]
}
}
module kubernetes './k8s-service-account.bicep' = {
name: 'app-id-${aksClusterName}-resource'
params: {
clientId: userIdentity.outputs.clientId
kubeConfig: aks.listClusterAdminCredential().kubeconfigs[0].value
namespace: k8sNamespace
serviceAccountName: k8sServiceAccount
}
}
まだベータ版なので今後変更されるかもしれませんが、オプションが広がるのはよいことなのでGAになることを期待しましょう。
ACS事業部のご紹介
私たちACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。ぜひお声がけください。
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。