All skills
aktsmm avatar

/azure-env-builder

@848fd9b
by yamapanaktsmm/agent-skills26 stars
4

[Alpha] Experimental Azure environment builder for infrastructure and deployment design. Use when building Azure infrastructure, generating Bicep with AVM modules, deploying apps to App Service/AKS/Container Apps, designing Hub-Spoke/AKS/AI Foundry architectures, or creating low-cost Azure operations demos.

Use this Skill: https://skilld.dev/gh/aktsmm/agent-skills/azure-env-builder

This session only. Nothing lands on disk.

referencesapp-deploy-patterns.md

≈5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

アプリデプロイパターン

Azure App Service、AKS、Container Apps へのアプリケーションデプロイパターン。

目次

  1. App Service デプロイ
  2. AKS デプロイ
  3. Container Apps デプロイ
  4. CI/CD 統合

App Service デプロイ

デプロイ方式一覧

方式 用途 推奨シナリオ
ZIP デプロイ コードパッケージ .NET, Node.js, Python 等
コンテナデプロイ Docker イメージ カスタムランタイム
GitHub Actions CI/CD 自動化 継続的デプロイ
スロットデプロイ Blue-Green / Canary 本番環境のゼロダウンタイム
Run From Package 読み取り専用パッケージ実行 高速起動、一貫性

1. ZIP デプロイ (コードベース)

# ビルド & ZIP 作成
dotnet publish -c Release -o ./publish
cd publish && zip -r ../app.zip .

# Azure CLI でデプロイ
az webapp deploy \
  --resource-group rg-myapp-prod \
  --name app-web-prod \
  --src-path app.zip \
  --type zip

2. コンテナデプロイ

Bicep でコンテナ App Service 構成
// App Service (Linux Container)
module appService 'br/public:avm/res/web/site:0.15.1' = {
  name: 'appServiceDeployment'
  params: {
    name: 'app-${environment}-${location}'
    kind: 'app,linux,container'
    serverFarmResourceId: appServicePlan.outputs.resourceId

    // コンテナ設定
    siteConfig: {
      linuxFxVersion: 'DOCKER|${acrName}.azurecr.io/${imageName}:${imageTag}'
      acrUseManagedIdentityCreds: true  // ACR への MI 認証
      appSettings: [
        {
          name: 'WEBSITES_PORT'
          value: '8080'
        }
        {
          name: 'DOCKER_REGISTRY_SERVER_URL'
          value: 'https://${acrName}.azurecr.io'
        }
      ]
    }

    // Managed Identity (ACR Pull 用)
    managedIdentities: {
      systemAssigned: true
    }
  }
}

// ACR への AcrPull ロール割り当て
module acrRoleAssignment 'br/public:avm/ptn/authorization/resource-role-assignment:0.1.1' = {
  name: 'acrPullRoleAssignment'
  params: {
    principalId: appService.outputs.systemAssignedMIPrincipalId
    roleDefinitionId: '7f951dda-4ed3-4680-a7ca-43fe172d538d'  // AcrPull
    resourceId: acr.outputs.resourceId
  }
}

3. スロットデプロイ (Blue-Green)

// デプロイスロット定義
module stagingSlot 'br/public:avm/res/web/site/slot:0.4.0' = {
  name: 'stagingSlotDeployment'
  params: {
    name: 'staging'
    appServiceName: appService.outputs.name
    kind: 'app,linux,container'
    siteConfig: {
      linuxFxVersion: 'DOCKER|${acrName}.azurecr.io/${imageName}:${newImageTag}'
    }
  }
}
# スロットへデプロイ
az webapp deploy \
  --resource-group rg-myapp-prod \
  --name app-web-prod \
  --slot staging \
  --src-path app.zip

# スワップ(本番切り替え)
az webapp deployment slot swap \
  --resource-group rg-myapp-prod \
  --name app-web-prod \
  --slot staging \
  --target-slot production

4. Run From Package

// Run From Package 設定
siteConfig: {
  appSettings: [
    {
      name: 'WEBSITE_RUN_FROM_PACKAGE'
      value: '1'  // または Blob URL
    }
  ]
}

AKS デプロイ

デプロイ方式一覧

方式 用途 複雑度 推奨シナリオ
kubectl 直接マニフェスト適用 低 シンプルなアプリ
Helm パッケージ管理 中 再利用可能なチャート
Kustomize 環境別オーバーレイ 中 環境差分管理
GitOps Git ベース自動同期 高 大規模運用、監査要件

1. kubectl 直接デプロイ

Kubernetes マニフェスト
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: myacr.azurecr.io/myapp:v1.0.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: myapp-secrets
                  key: database-url
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
  namespace: production
spec:
  type: ClusterIP
  selector:
    app: myapp
  ports:
    - port: 80
      targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  namespace: production
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
    appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  tls:
    - hosts:
        - myapp.example.com
      secretName: myapp-tls
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapp-service
                port:
                  number: 80
# AKS 認証情報取得
az aks get-credentials --resource-group rg-aks-prod --name aks-prod

# デプロイ
kubectl apply -f k8s/deployment.yaml

# 確認
kubectl get pods -n production
kubectl get svc -n production

2. Helm チャートデプロイ

Chart 構造
helm/myapp/
├── Chart.yaml
├── values.yaml
├── values-dev.yaml
├── values-prod.yaml
└── templates/
    ├── deployment.yaml
    ├── service.yaml
    ├── ingress.yaml
    ├── configmap.yaml
    └── secret.yaml
Chart.yaml
apiVersion: v2
name: myapp
description: My Application Helm Chart
version: 1.0.0
appVersion: "1.0.0"
values.yaml (デフォルト)
# アプリケーション設定
replicaCount: 2

image:
  repository: myacr.azurecr.io/myapp
  tag: latest
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80
  targetPort: 8080

ingress:
  enabled: true
  className: azure-application-gateway
  annotations:
    appgw.ingress.kubernetes.io/ssl-redirect: "true"
  hosts:
    - host: myapp.example.com
      paths:
        - path: /
          pathType: Prefix

resources:
  requests:
    memory: "128Mi"
    cpu: "100m"
  limits:
    memory: "256Mi"
    cpu: "500m"

# 環境変数
env:
  - name: ASPNETCORE_ENVIRONMENT
    value: Production

# ConfigMap から読み込む設定
configMap:
  enabled: true
  data:
    APP_CONFIG: "production"

# Secrets (外部参照推奨)
secrets:
  enabled: false

# Azure Key Vault CSI Driver
keyVault:
  enabled: true
  name: kv-myapp-prod
  tenantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  secrets:
    - name: database-connection-string
      alias: DATABASE_URL
values-prod.yaml (本番オーバーライド)
replicaCount: 5

image:
  tag: v1.2.0

resources:
  requests:
    memory: "256Mi"
    cpu: "250m"
  limits:
    memory: "512Mi"
    cpu: "1000m"

autoscaling:
  enabled: true
  minReplicas: 3
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70
templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "myapp.fullname" . }}
  labels:
    {{- include "myapp.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "myapp.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "myapp.selectorLabels" . | nindent 8 }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - containerPort: {{ .Values.service.targetPort }}
          {{- if .Values.env }}
          env:
            {{- toYaml .Values.env | nindent 12 }}
          {{- end }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
          {{- if .Values.keyVault.enabled }}
          volumeMounts:
            - name: secrets-store
              mountPath: "/mnt/secrets-store"
              readOnly: true
          {{- end }}
      {{- if .Values.keyVault.enabled }}
      volumes:
        - name: secrets-store
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: {{ include "myapp.fullname" . }}-secrets
      {{- end }}
# Helm デプロイ
helm upgrade --install myapp ./helm/myapp \
  --namespace production \
  --create-namespace \
  -f ./helm/myapp/values-prod.yaml \
  --set image.tag=v1.2.0

# ロールバック
helm rollback myapp 1 --namespace production

# 履歴確認
helm history myapp --namespace production

3. Kustomize デプロイ

kustomize/
├── base/
│   ├── kustomization.yaml
│   ├── deployment.yaml
│   └── service.yaml
└── overlays/
    ├── dev/
    │   ├── kustomization.yaml
    │   └── patch-replicas.yaml
    └── prod/
        ├── kustomization.yaml
        └── patch-replicas.yaml
base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml

commonLabels:
  app: myapp
overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: production

resources:
  - ../../base

images:
  - name: myacr.azurecr.io/myapp
    newTag: v1.2.0

replicas:
  - name: myapp
    count: 5

patches:
  - path: patch-replicas.yaml
# Kustomize でデプロイ
kubectl apply -k kustomize/overlays/prod/

4. GitOps (Flux v2)

Flux インストール
# Flux CLI インストール
curl -s https://fluxcd.io/install.sh | sudo bash

# AKS に Flux 拡張機能インストール
az k8s-extension create \
  --resource-group rg-aks-prod \
  --cluster-name aks-prod \
  --cluster-type managedClusters \
  --name flux \
  --extension-type microsoft.flux
GitRepository & Kustomization
# flux-system/git-repository.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: myapp-repo
  namespace: flux-system
spec:
  interval: 1m
  url: https://github.com/myorg/myapp-k8s
  ref:
    branch: main
  secretRef:
    name: github-token
---
# flux-system/kustomization.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: myapp-production
  namespace: flux-system
spec:
  interval: 5m
  path: ./kustomize/overlays/prod
  prune: true
  sourceRef:
    kind: GitRepository
    name: myapp-repo
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: myapp
      namespace: production

Container Apps デプロイ

Bicep でアプリデプロイ

// Container Apps 環境
module containerAppsEnv 'br/public:avm/res/app/managed-environment:0.8.1' = {
  name: 'containerAppsEnvDeployment'
  params: {
    name: 'cae-${environment}-${location}'
    logAnalyticsWorkspaceResourceId: logAnalytics.outputs.resourceId
    infrastructureSubnetId: subnet.outputs.resourceId
  }
}

// Container App
module containerApp 'br/public:avm/res/app/container-app:0.12.0' = {
  name: 'containerAppDeployment'
  params: {
    name: 'ca-myapp-${environment}'
    environmentResourceId: containerAppsEnv.outputs.resourceId

    // コンテナ設定
    containers: [
      {
        name: 'myapp'
        image: '${acrName}.azurecr.io/myapp:${imageTag}'
        resources: {
          cpu: json('0.5')
          memory: '1Gi'
        }
        env: [
          {
            name: 'DATABASE_URL'
            secretRef: 'database-url'
          }
          {
            name: 'REDIS_URL'
            secretRef: 'redis-url'
          }
        ]
      }
    ]

    // スケール設定
    scaleMinReplicas: 1
    scaleMaxReplicas: 10
    scaleRules: [
      {
        name: 'http-scaling'
        http: {
          metadata: {
            concurrentRequests: '100'
          }
        }
      }
    ]

    // Ingress 設定
    ingressExternal: true
    ingressTargetPort: 8080
    ingressTransport: 'auto'

    // シークレット
    secrets: {
      secureList: [
        {
          name: 'database-url'
          keyVaultUrl: '${keyVault.properties.vaultUri}secrets/database-url'
          identity: 'system'
        }
        {
          name: 'redis-url'
          keyVaultUrl: '${keyVault.properties.vaultUri}secrets/redis-url'
          identity: 'system'
        }
      ]
    }

    // Managed Identity
    managedIdentities: {
      systemAssigned: true
    }

    // Dapr 設定 (オプション)
    dapr: {
      enabled: true
      appId: 'myapp'
      appPort: 8080
      appProtocol: 'http'
    }
  }
}

az containerapp コマンド

# イメージ更新
az containerapp update \
  --resource-group rg-myapp-prod \
  --name ca-myapp-prod \
  --image myacr.azurecr.io/myapp:v1.2.0

# リビジョン確認
az containerapp revision list \
  --resource-group rg-myapp-prod \
  --name ca-myapp-prod \
  --output table

# トラフィック分割 (Canary)
az containerapp ingress traffic set \
  --resource-group rg-myapp-prod \
  --name ca-myapp-prod \
  --revision-weight myapp--v1=90 myapp--v2=10

CI/CD 統合

GitHub Actions - App Service

# .github/workflows/deploy-appservice.yml
name: Deploy to App Service

on:
  push:
    branches: [main]
    paths: ["src/**"]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # ビルド
      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: "8.0.x"

      - name: Build and publish
        run: |
          dotnet publish -c Release -o ./publish
          cd publish && zip -r ../app.zip .

      # Azure ログイン
      - uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      # デプロイ (スロット)
      - name: Deploy to staging slot
        run: |
          az webapp deploy \
            --resource-group ${{ vars.RESOURCE_GROUP }} \
            --name ${{ vars.APP_NAME }} \
            --slot staging \
            --src-path app.zip

      # スワップ
      - name: Swap to production
        run: |
          az webapp deployment slot swap \
            --resource-group ${{ vars.RESOURCE_GROUP }} \
            --name ${{ vars.APP_NAME }} \
            --slot staging \
            --target-slot production

GitHub Actions - AKS

# .github/workflows/deploy-aks.yml
name: Deploy to AKS

on:
  push:
    branches: [main]
    paths: ["src/**", "helm/**"]

env:
  ACR_NAME: myacr
  IMAGE_NAME: myapp
  CLUSTER_NAME: aks-prod
  RESOURCE_GROUP: rg-aks-prod

jobs:
  build:
    runs-on: ubuntu-latest
    outputs:
      image_tag: ${{ steps.meta.outputs.tags }}
    steps:
      - uses: actions/checkout@v4

      - uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      # ACR ログイン
      - name: Login to ACR
        run: az acr login --name ${{ env.ACR_NAME }}

      # Docker ビルド & プッシュ
      - name: Build and push
        id: meta
        run: |
          IMAGE_TAG="${{ env.ACR_NAME }}.azurecr.io/${{ env.IMAGE_NAME }}:${{ github.sha }}"
          docker build -t $IMAGE_TAG .
          docker push $IMAGE_TAG
          echo "tags=$IMAGE_TAG" >> $GITHUB_OUTPUT

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      # AKS 認証
      - name: Get AKS credentials
        run: |
          az aks get-credentials \
            --resource-group ${{ env.RESOURCE_GROUP }} \
            --name ${{ env.CLUSTER_NAME }}

      # Helm デプロイ
      - name: Deploy with Helm
        run: |
          helm upgrade --install myapp ./helm/myapp \
            --namespace production \
            --create-namespace \
            -f ./helm/myapp/values-prod.yaml \
            --set image.tag=${{ github.sha }} \
            --wait --timeout 5m

      # デプロイ確認
      - name: Verify deployment
        run: |
          kubectl rollout status deployment/myapp -n production
          kubectl get pods -n production -l app=myapp

GitHub Actions - Container Apps

# .github/workflows/deploy-containerapp.yml
name: Deploy to Container Apps

on:
  push:
    branches: [main]

env:
  ACR_NAME: myacr
  IMAGE_NAME: myapp
  CONTAINERAPP_NAME: ca-myapp-prod
  RESOURCE_GROUP: rg-myapp-prod

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      # ACR ビルド (サーバーサイドビルド)
      - name: Build on ACR
        run: |
          az acr build \
            --registry ${{ env.ACR_NAME }} \
            --image ${{ env.IMAGE_NAME }}:${{ github.sha }} \
            .

      # Container App 更新
      - name: Update Container App
        run: |
          az containerapp update \
            --resource-group ${{ env.RESOURCE_GROUP }} \
            --name ${{ env.CONTAINERAPP_NAME }} \
            --image ${{ env.ACR_NAME }}.azurecr.io/${{ env.IMAGE_NAME }}:${{ github.sha }}

      # リビジョン確認
      - name: Check revision
        run: |
          az containerapp revision list \
            --resource-group ${{ env.RESOURCE_GROUP }} \
            --name ${{ env.CONTAINERAPP_NAME }} \
            --output table

設定連携チェックリスト

App Service デプロイ時

項目 確認内容
ACR 認証 Managed Identity + AcrPull ロール
App Settings Key Vault 参照または環境変数
Connection Strings SQL/Redis/Storage の接続文字列
Startup Command コンテナ起動コマンド
Health Check /health エンドポイント設定

AKS デプロイ時

項目 確認内容
ACR 統合 az aks update --attach-acr
Namespace 環境別 namespace 分離
Secrets Key Vault CSI Driver または Sealed Secrets
Ingress AGIC または Nginx Ingress
Pod Identity Workload Identity 設定
HPA CPU/メモリ/カスタムメトリクス

Container Apps デプロイ時

項目 確認内容
Environment VNet 統合、Log Analytics 接続
Secrets Key Vault 参照
Scale Rules HTTP / CPU / KEDA
Dapr サイドカー有効化
Revision Mode Single / Multiple

Source: SKILL.md on GitHub

2 warnings4mo4 checks · Risk SAFE
  • Gen Agent Trust Hub4mo

    The skill is a comprehensive Azure infrastructure automation tool that uses Azure Bicep and Azure Verified Modules (AVM) to scaffold and deploy enterprise environments. It follows security best practices, such as using Managed Identities and Azure Key Vault for secret management. No malicious patterns, obfuscation, or unauthorized data access were detected. All external references target official Microsoft domains or well-known infrastructure tools like Flux CD.

  • Socket4mo

    No alerts

  • Snyk4mo

    Risk: MEDIUM · 2 issues

  • Runlayer7mo

    17/17 files flagged

Signed by skilld at 848fd9b. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 18 hours ago.

Activeupdated 3 months ago
argument-hint
構築したい Azure 構成、アプリ、制約条件
user-invocable
true
metadata
{
  "author": "yamapan (https://github.com/aktsmm)"
}

README badge

README badge for aktsmm/agent-skills/azure-env-builder