LoginSignup
0
0

More than 1 year has passed since last update.

Azure Web App から Managed Identity で SQL Database にアクセスする

Last updated at Posted at 2021-10-31

プロジェクトを作成して起動

PowerShell
$app = "ManagedIdentityTestApp"
mkdir $app
cd $app
dotnet new sln --name $app
dotnet new webapi --output $app --framework net5.0
dotnet sln add $app\$app.csproj
start .\$app.sln

NuGet パッケージインストール

パッケージマネージャーコンソール
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Tools

コーディング

Entities/Book.cs
namespace ManagedIdentityTestApp.Entities
{
    public class Book
    {
        public int BookId { get; set; }
        public string Title { get; set; }
        public string Author { get; set; }
    }
}

Data/AppDbContext.cs
using ManagedIdentityTestApp.Entities;
using Microsoft.EntityFrameworkCore;

namespace ManagedIdentityTestApp.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions options) : base(options)
        {
        }

        public DbSet<Book> Books { get; set; }
    }
}

Controllers/BookController.cs
using ManagedIdentityTestApp.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;

namespace ManagedIdentityTestApp.Controllers
{
    [Route("api/books")]
    [ApiController]
    public class BookController : ControllerBase
    {
        private readonly AppDbContext context;

        public BookController(AppDbContext context)
        {
            this.context = context;
        }

        [HttpGet]
        public async Task<IActionResult> ListAsync()
        {
            var books = await context.Books.ToListAsync();
            return Ok(books);
        }
    }
}

Startup.cs
using ManagedIdentityTestApp.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;

namespace ManagedIdentityTestApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "ManagedIdentityTestApp", Version = "v1" });
            });
            services.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); //追加
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ManagedIdentityTestApp v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

appsettings.json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=ManagedIdentityTestAppDb;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

データ準備

パッケージマネージャーコンソール
Add-Migration init
Update-Database

SQL Server でレコード追加クエリ実行。

INSERT INTO Books (Title, Author) VALUES (N'たったひとつの冴えたやりかた',N'ジェイムズ・ティプトリー・ジュニア');
INSERT INTO Books (Title, Author) VALUES (N'アンドロイドは電気羊の夢を見るか?',N'フィリップ・K・ディック');
INSERT INTO Books (Title, Author) VALUES (N'夏への扉',N'ロバート・A. ハインライン');
INSERT INTO Books (Title, Author) VALUES (N'幼年期の終り',N'アーサー C クラーク');
INSERT INTO Books (Title, Author) VALUES (N'われはロボット',N'アイザック・アシモフ');

動作確認

ローカル実行して api/books にアクセスしてデータが取得できることを確認。

[
    {
        "bookId": 1,
        "title": "たったひとつの冴えたやりかた",
        "author": "ジェイムズ・ティプトリー・ジュニア"
    },
    {
        "bookId": 2,
        "title": "アンドロイドは電気羊の夢を見るか?",
        "author": "フィリップ・K・ディック"
    },
    {
        "bookId": 3,
        "title": "夏への扉",
        "author": "ロバート・A. ハインライン"
    },
    {
        "bookId": 4,
        "title": "幼年期の終り",
        "author": "アーサー C クラーク"
    },
    {
        "bookId": 5,
        "title": "われはロボット",
        "author": "アイザック・アシモフ"
    }
]

Azure リソース作成

PowerShell
# Azure にログイン
az login

# リソースグループ作成
az group create --location japaneast --name ManagedIdentityTestRG

# App Service Plan 作成
az appservice plan create --name ManagedIdentityTestAppServicePlan --resource-group ManagedIdentityTestRG --location japaneast --sku FREE

# Web App 作成
$random = Get-Random
az webapp create --name web-app-$random --plan ManagedIdentityTestAppServicePlan --resource-group ManagedIdentityTestRG --runtime "DOTNET:5.0"

# SQL Server 作成
az sql server create --name sql-server-$random --resource-group ManagedIdentityTestRG --enable-ad-only-auth --external-admin-name SqlServerAdministrators --external-admin-principal-type Group --external-admin-sid 3329c7ca-75c6-4823-a9b0-8932a900fd37 --minimal-tls-version 1.2

# SQL Database 作成
az sql db create --name ManagedIdentityTestDb --resource-group ManagedIdentityTestRG --server sql-server-$random --collation Japanese_CI_AS --edition Free

# Azure サービスからのアクセスを許可
az sql server firewall-rule create --resource-group ManagedIdentityTestRG --server sql-server-$random --name allowAzureService --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0

# システム割り当てマネージド ID 有効化
az webapp identity assign --resource-group ManagedIdentityTestRG --name web-app-$random

# マネージド ID を管理者グループに追加
az ad group member add --group SqlServerAdministrators --member-id 24d820ca-8e3a-4b4d-987c-36fdd10e021b

# 接続文字列追加
az webapp config connection-string set --connection-string-type SQLServer --name web-app-$random --resource-group ManagedIdentityTestRG --settings DefaultConnection="Server=tcp:sql-server-$random.database.windows.net;Authentication=Active Directory Managed Identity; Database=ManagedIdentityTestDb;"

データ登録

DDL を取得する。

パッケージマネージャーコンソール
Script-Migration

こんなのが出力される。

IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL
BEGIN
    CREATE TABLE [__EFMigrationsHistory] (
        [MigrationId] nvarchar(150) NOT NULL,
        [ProductVersion] nvarchar(32) NOT NULL,
        CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
    );
END;
GO

BEGIN TRANSACTION;
GO

CREATE TABLE [Books] (
    [BookId] int NOT NULL IDENTITY,
    [Title] nvarchar(max) NULL,
    [Author] nvarchar(max) NULL,
    CONSTRAINT [PK_Books] PRIMARY KEY ([BookId])
);
GO

INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20211031085850_init', N'5.0.11');
GO

COMMIT;
GO

出力された DDL を SQL Database に流し込む。Azure Portal のクエリエディタを使用。

レコードも追加する。

INSERT INTO Books (Title, Author) VALUES (N'たったひとつの冴えたやりかた',N'ジェイムズ・ティプトリー・ジュニア');
INSERT INTO Books (Title, Author) VALUES (N'アンドロイドは電気羊の夢を見るか?',N'フィリップ・K・ディック');
INSERT INTO Books (Title, Author) VALUES (N'夏への扉',N'ロバート・A. ハインライン');
INSERT INTO Books (Title, Author) VALUES (N'幼年期の終り',N'アーサー C クラーク');
INSERT INTO Books (Title, Author) VALUES (N'われはロボット',N'アイザック・アシモフ');

NuGet パッケージを追加しておく。

パッケージマネージャーコンソール
Install-Package Microsoft.Data.SqlClient

Visual Studio から Web App に発行する。

api/books にアクセスしてデータが取得できることを確認。

[
    {
        "bookId": 1,
        "title": "たったひとつの冴えたやりかた",
        "author": "ジェイムズ・ティプトリー・ジュニア"
    },
    {
        "bookId": 2,
        "title": "アンドロイドは電気羊の夢を見るか?",
        "author": "フィリップ・K・ディック"
    },
    {
        "bookId": 3,
        "title": "夏への扉",
        "author": "ロバート・A. ハインライン"
    },
    {
        "bookId": 4,
        "title": "幼年期の終り",
        "author": "アーサー C クラーク"
    },
    {
        "bookId": 5,
        "title": "われはロボット",
        "author": "アイザック・アシモフ"
    }
]

VNet 統合

PowerShell
# 仮想ネットワーク作成
az network vnet create --name virtualnetwork --resource-group ManagedIdentityTestRG

# サブネット作成
az network vnet subnet create --address-prefixes 10.0.0.0/24 --name subnet1 --resource-group ManagedIdentityTestRG --vnet-name virtualnetwork

# サービスエンドポイント追加
az network vnet subnet update --name subnet1 --resource-group ManagedIdentityTestRG --vnet-name virtualnetwork --service-endpoints Microsoft.Sql

# 仮想ネットワークルール追加
az sql server vnet-rule create --server sql-server-$random --name vnetrule --resource-group ManagedIdentityTestRG --subnet subnet1 --vnet-name virtualnetwork

# App Service Plan スケールアップ
az appservice plan update --name ManagedIdentityTestAppServicePlan --resource-group ManagedIdentityTestRG --sku S1

# VNet 統合
az webapp vnet-integration add --name web-app-$random --resource-group ManagedIdentityTestRG --subnet subnet1 --vnet virtualnetwork

# Azure サービスからのアクセスを拒否
az sql server firewall-rule delete --name allowAzureService --resource-group ManagedIdentityTestRG --server sql-server-$random
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0