ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

2019 年振り返り

今年も、しばやんさんが作った 2019 年の人気記事ランキング生成 を使わせてもらい、1年を振り返ってみます。

  1. HttpClient を使って同期で通信する
  2. ASP.NET でクライアントの IP アドレスを取得する
  3. ASP.NET Web API で multipart / form-data を使ってファイルをアップロードする
  4. プロキシ環境下で Web API を呼び出す
  5. ASP.NET MVC の Ajax 通信で例外を処理する
  6. ASP.NET MVC で JSON の一部として PartialView を返す方法
  7. ファイルをアップロードする API の Swagger ドキュメントを書く
  8. ASP.NET Web API を経由して Azure Blob Storage にアクセスする
  9. ASP.NET Web API で返す JSON のプロパティを指定する
  10. ASP.NET Web API で MediaTypeFormatter を追加する

例年通り、ASP.NET 関連の記事が、多く読まれています。Azure の記事がもっと増えてほしいですが、なかなか PV が伸びないですね。

イベント登壇

イベント登壇は、JAZUG札幌支部(きたあず)と Ignite The Tour Tokyo の2回でした。

Ignite The Tour のセッション資料は、運営側から公開される予定です。ちなみに、来月の大阪でも同じ内容で登壇します。
ここ数年は Azure Kubernetes Service のテーマで登壇することが多かったですが、これからは Serverless & JAMstack の方向にシフトしていきたいです。どちらもマイクロサービス なアプローチですが、Kubernetes と比べると速くて安くてシンプルなので、より多くの人たちにリーチできると考えています。

コミュニティ運営

東京の JAZUG でのセッション登壇はありませんでしたが、運営をお手伝いしました。例年通りのイベント以外にも、Ignite The Tour でコミュニティブースを出しました。登壇も運営もどちらも楽しかったので、来年も継続して活動していきたいです。

  • Tokyo Jazug Night
  • Japan Azure User Group 9 周年イベント
  • Global Azure Bootcamp 2019@Tokyo
  • Ignite The Tour Tokyo

来年は JAZUG 10 周年なので、何か楽しいイベントにしたいですね。

Microsoft MVP

3月には、2回目の Microsoft MVP Global Summit に参加しました。今回もたくさんの刺激を受けて楽しかった。英語を話せたら何倍も楽しいはずですが、結局今年もほとんど勉強しなかったので、年明けから勉強したい。
gooner.hateblo.jp

昨年からのコミュニティ活動が評価されて、7月には Microsoft MVP for Microsoft Azure を無事に更新できたので、また来年の3月に参加できそうです。

仕事

おかげさまで15 周年ということで、家族を連れてハワイに社員旅行に行ったことが印象に残っています。
gooner.hateblo.jp
転職して3年が経ち、今年の目標だった「自分でやりたい提案を書いて、仕事ができるようになる」は達成できたし、長くお付き合いできるお客さんとの出会いもありました。ただ、案件を一人で担当することが多いので、来年は社内社外を問わずに、一緒に仕事ができる仲間を増やしたいです。

まとめ

コミュニティや仕事で多くの方々と出会う機会に恵まれ、新しいことにも挑戦することができ、充実した1年だったと思います。
本年もお世話になりました。よい年をお迎えください。

おまけ

2019年自分が選ぶ今年の4枚。

f:id:TonyTonyKun:20191110115429j:plain
紅葉の小樽運河
f:id:TonyTonyKun:20190812012109j:plain
ダイヤモンドヘッド山頂からの景色
f:id:TonyTonyKun:20190727013937j:plain
立山連峰の雄山
f:id:TonyTonyKun:20190327203938j:plain
Microsoft MVP Global Summit 2019

Azure DevOps の Multi-Stage Pipelines で Azure Web Apps のパイプラインを構築する

今年の5月に、Azure DevOps の Build と Release のパイプラインに代わって、Multi-Stage Pipelines で構築できるようになる発表がありました。
devblogs.microsoft.com
現時点では、Multi-Stage Pipelines はプレビュー機能ですが、従来の Build と Release のパイプラインは Classic 扱いとなっているので、そろそろ触っておかねばと思い、試してみました。

前準備

Azure DevOps の右上のユーザーアイコンから、Preview features で Multi-Stage Pipelines を有効にします。

f:id:TonyTonyKun:20191219143946p:plain

あとは、デプロイ先の Azure Web Apps のサブスクリプション情報を service connection として登録しておきます。

パイプラインの全体設計

今回は、リポジトリのブランチとデプロイ先の関係が分かりやすい GitLab flow を想定しています。
パイプラインは、自動デプロイされる開発環境向け(Commit Stage)と承認デプロイされる本番環境向け(Production Stage)を作ります。

f:id:TonyTonyKun:20191219144724p:plain

YAML を Build と Release を分けて、可変部をパラメータで切り替えできるテンプレートを作ることで再利用性を向上させます。

f:id:TonyTonyKun:20191220105519p:plain

開発環境向けパイプライン

まずは、パイプライン起動用の azure-pipelines.yml です。

trigger:
- master

variables:
  imageName: 'windows-2019'
  buildConfiguration: 'Release'
  projects: '**/WebApplication.csproj'
  testProjects: '**/WebApplication.Tests.csproj'
  azureSubscription: 'AzureSponsorships'
  webAppsName: '<Web Apps Name>'
  webAppsType: 'webApp'
  environment: 'Commit-Stage'

stages:
- stage: Build
  jobs:
  - template: pipelines/build-pipelines.yml
    parameters:
      imageName: $(imageName)
      buildConfiguration: $(buildConfiguration)
      projects: $(projects)
      testProjects: $(testProjects)
    
- stage: Release
  dependsOn:
  - Build
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
  jobs:
  - template: pipelines/release-pipelines.yml
    parameters:
      imageName: $(imageName)
      azureSubscription: $(azureSubscription)
      webAppsName: $(webAppsName)
      webAppsType: $(webAppsType)
      environment: $(environment)

ポイントは、template で Build と Release のYAMLを指定している箇所です。condition で、Build ステージが成功した場合のみ、Release ステージを実行する条件指定も忘れずに設定します。
リリースの JOB は、Environments を使います。
開発環境向けパイプラインでは、自動デプロイしたいので、空の Environments を Commit-Stage で登録しておきます。

f:id:TonyTonyKun:20191219144756p:plain

次に、ビルド用の build-pipelines.yml です。

parameters:
  imageName: ''
  buildConfiguration: ''
  projects: ''
  testProjects: ''

jobs:
- job: Build
  pool:
    vmImage: ${{parameters.imageName}}
  steps:
  - task: DotNetCoreCLI@2
    displayName: 'Build'
    inputs:
      command: 'build'
      projects: ${{parameters.projects}}
      arguments: '--configuration ${{parameters.buildConfiguration}}'
  - task: DotNetCoreCLI@2
    displayName: 'Test'
    inputs:
      command: 'test'
      projects: ${{parameters.testProjects}}
      arguments: '--configuration ${{parameters.buildConfiguration}}'
  - task: DotNetCoreCLI@2
    displayName: 'Publish'
    inputs:
      command: 'publish'
      publishWebProjects: true
      arguments: '--configuration ${{parameters.buildConfiguration}} --output $(System.DefaultWorkingDirectory)/publish'
      zipAfterPublish: true
  - publish: publish
    displayName: 'Publish artifact'
    artifact: webapp

.NET Core CLI taskDotNetCoreCLI@2 を使って、ビルド→テスト→発行を行っています。

最後に、リリース用の release-pipelines.yml です。

parameters:
  imageName: ''
  azureSubscription: ''
  webAppsName: ''
  webAppsType: ''
  webAppsSlotName: 'production'
  environment: ''

jobs:
- deployment: Deploy_WebApps
  displayName: 'Release'
  pool:
    vmImage: ${{parameters.imageName}}
  environment: ${{parameters.environment}}
  strategy:
    runOnce:
      deploy:
        steps:
        - task: AzureWebApp@1
          displayName: 'Deploy to Azure Web Apps'
          inputs:
            azureSubscription: ${{parameters.azureSubscription}}
            appType: ${{parameters.webAppsType}}
            appName: ${{parameters.webAppsName}}
            slotName: ${{parameters.webAppsSlotName}}
            package: '$(Pipeline.Workspace)/**/*.zip'
            deploymentMethod: runFromPackage

Azure Web App taskAzureWebApp@1 を使って、デプロイを行っています。
Azure Web Apps の Deployment Slot 機能にも対応したいので、slotName を指定しますが、必須にはしたくないので、初期値で production を設定しています。

本番環境向けパイプライン

パイプライン起動用の azure-pipelines-production.yml です。

trigger:
- production

variables:
  imageName: 'windows-2019'
  buildConfiguration: 'Release'
  projects: '**/WebApplication.csproj'
  testProjects: '**/WebApplication.Tests.csproj'
  azureSubscription: 'AzureSponsorships'
  webAppsName: '<Web Apps Name>'
  webAppsType: 'webApp'
  environment: 'Production-Stage'
  webAppsSlotName: 'staging'

stages:
- stage: Build
  jobs:
  - template: pipelines/build-pipelines.yml
    parameters:
      imageName: $(imageName)
      buildConfiguration: $(buildConfiguration)
      projects: $(projects)
      testProjects: $(testProjects)
    
- stage: Release
  dependsOn:
  - Build
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/production'))
  jobs:
  - template: pipelines/release-pipelines.yml
    parameters:
      imageName: $(imageName)
      azureSubscription: $(azureSubscription)
      webAppsName: $(webAppsName)
      webAppsType: $(webAppsType)
      environment: $(environment)
      webAppsSlotName: $(webAppsSlotName)

トリガーとなるブランチが production となっている箇所が開発環境向けパイプラインとの違いです。
本番環境では、Azure Web Apps の Deployment Slot 機能を利用したいので、staging を設定しています。また、承認デプロイもしたいので、承認設定した Environments を Production-Stage で登録しておきます。

f:id:TonyTonyKun:20191219144048p:plain

結果確認

リポジトリの master ブランチへの更新がトリガーとなり、ビルドとリリースのパイプラインが実行され、Azure Web Apps へのデプロイまでが自動で実行されます。

f:id:TonyTonyKun:20191219145206p:plain

master ブランチから production ブランチへプルリクエストのマージがトリガーとなり、ビルドとリリースのパイプラインが実行されます。Azure Web Apps へのデプロイは承認が必須となっているので、Waiting になっていることが分かります。

f:id:TonyTonyKun:20191219144408p:plain

この後、リリースを承認すると、Deployment Slot の staging へデプロイされます。最終動作確認後、Azure Portal などからの Swap することを想定しています。万が一、リリースによる障害が発生した場合には、旧バージョンに切り戻すこともできます。

まとめ

Azure DevOps の Multi-Stage Pipelines を使って、Azure Web Apps 向けのパイプラインを構築してみました。
可変部をパラメータで切り替えできるようにテンプレート化しているので、これからの CI/CD が捗りそうです。

紅葉が見頃な北海道に行ってきました

先月末、JAZUG札幌支部(きたあず)第23回勉強会に参加しつつ、紅葉が見頃な北海道を2泊3日で観光してきました。
きたあずのことは前回の記事に書いたので、今回は観光した話を書きます。
gooner.hateblo.jp

1日目

きたあずの当日は、昼前に札幌に着いたので、早速雲丹を食べに行きました。

f:id:TonyTonyKun:20191109220343j:plain

2年前にも行ったお店で、いいお値段しますが、奮発して雲丹丼を注文しました。
tabelog.com
お腹も満たされたので、会場となるサッポロファクトリーまで、札幌の街を散策しながら歩いて行きました。

f:id:TonyTonyKun:20191109220434j:plain
赤れんが庁舎
f:id:TonyTonyKun:20191109220502j:plain
時計台
f:id:TonyTonyKun:20191109220610j:plain
さっぽろテレビ塔
f:id:TonyTonyKun:20191109220645j:plain
サッポロファクトリー

最近ハマっているドラゴンクエストウォークのお土産のジンギスカンをゲット。地域限定モンスターが2匹いるのですが、ツンドラキーしかエンカウントできず残念。

f:id:TonyTonyKun:20191110115930j:plain

勉強会後の懇親会は、すすきのにある「かわず池」というお店に行きました。
お通しで出てきたお椀の汁物が美味しかった。北海道の海鮮料理もリーズナブルで美味しく、プレミアムモルツのマスターズドリームが進む楽しい懇親会でした。
tabelog.com

2日目

翌日は、札幌でレンタカーを借りて、美瑛にある青い池へ向かいました。iOS の壁紙にも採用された青い池ですが、地下から湧き出たアルミニウムを含む水が混じった白ひげの滝が美瑛川に流れ込み、コロイドという物質が生成され、太陽光の散乱によって青く見えるそうです。そのため、天気や時間帯によって青色が変わるらしいです。あいにくの曇り空でしたが、十分に綺麗に見えました。

f:id:TonyTonyKun:20191110102415j:plain
f:id:TonyTonyKun:20191110102349j:plain
f:id:TonyTonyKun:20191110102445j:plain

昼食は、青い池のすぐ近くにあるソーセージのレストラン「歩人(ほびっと)」に行きました。自家製のソーセージやハムが食べられる素敵なお店でした。2人でシェアして食べても十分なボリュームで美味しかったです。

f:id:TonyTonyKun:20191110102520j:plain
tabelog.com
このあと、車窓から北海道らしい風景を楽しみながら、富良野方面へ向かいました。

f:id:TonyTonyKun:20191110102557j:plain
f:id:TonyTonyKun:20191110102625j:plain

富良野では、いくつかの観光スポットに立ち寄りました。

f:id:TonyTonyKun:20191110102740j:plain
ふらのワイン工場
f:id:TonyTonyKun:20191110102918j:plain
ぶどう畑
f:id:TonyTonyKun:20191110102847j:plain
カンパーナ六花亭

新富良野プリンスホテルの敷地内にあるニングルテラスには、10棟ほどのログハウスが並び、雑貨店や喫茶店があります。とくに買い物はしなかったのですが、紅葉が綺麗で雰囲気のいい場所でした。

f:id:TonyTonyKun:20191110103030j:plain
f:id:TonyTonyKun:20191110103055j:plain
f:id:TonyTonyKun:20191110103126j:plain

札幌に戻り、夕飯はすすきのにある「ビーストキッチン」に行きました。初めて食べたサメガレイが美味しかった。日本酒を飲みながら、北海道の美味しい肴をいただきました。

f:id:TonyTonyKun:20191110103225j:plain
ヒラメのなめろう
f:id:TonyTonyKun:20191110103302j:plain
刺身の盛り合わせ
tabelog.com

3日目

最終日の朝食は、札幌中央市場に行きました。焼き立ての真ほっけとご飯と味噌汁の組み合わせが最高でした。

f:id:TonyTonyKun:20191110114515j:plain
真ほっけ
f:id:TonyTonyKun:20191110114607j:plain
根ぼっけの刺身
f:id:TonyTonyKun:20191110114640j:plain
ししゃもの刺身
tabelog.com

朝食のあと、おたる水族館に行きました。この日は良い天気で、水族館の入り口から石狩湾の対岸が見えるくらい眺めがよかったです。

f:id:TonyTonyKun:20191110214215j:plain

少し前に SNS で話題になったらしい「鮭は飲み物」を見れたので満足です。トドの鳴き声がまるでおっさんだった(笑)

f:id:TonyTonyKun:20191110114717j:plain
f:id:TonyTonyKun:20191110114745j:plain

こんなクイズもあって、割と楽しめた水族館でした。

f:id:TonyTonyKun:20191110114812j:plain
otaru-aq.jp

続いて、余市にあるニッカウヰスキー の蒸留所に行きました。紅葉と蒸留所の建物の風景がいい感じでした。

f:id:TonyTonyKun:20191110115013j:plain
f:id:TonyTonyKun:20191110115044j:plain
f:id:TonyTonyKun:20191110115113j:plain
f:id:TonyTonyKun:20191110115149j:plain
f:id:TonyTonyKun:20191110115227j:plain

ウイスキーの歴史や製造工程が展示されていて、自由見学でも十分に楽しめました。

f:id:TonyTonyKun:20191110115301j:plain
f:id:TonyTonyKun:20191110115340j:plain

無料と有料の試飲スペースがあって、オススメの割り方なんかも紹介されていました。お土産に限定ウイスキーを買って帰りました。
www.nikka.com

蒸留所のすぐ近くにある柿崎商店でいくら丼を食べて、小樽運河に向かいました。
tabelog.com

小樽運河では、小樽ビール醸造所の小樽倉庫 No.1 を見学したり、堺町通り商店街を散策したりしました。

f:id:TonyTonyKun:20191110115429j:plain
小樽運河
f:id:TonyTonyKun:20191110115505j:plain
小樽倉庫 No.1
f:id:TonyTonyKun:20191110115539j:plain
飲み放題のあるレストラン

新千歳空港でレンタカーを返して、らーめん空で味噌ラーメンを食べてから、東京へ帰りました。

f:id:TonyTonyKun:20191110115703j:plain

新千歳空港にはなんでもありますね。きたあずに来ていた方の話によれば、空港だけ観光に来る人もいるらしいです。

まとめ

北海道には夏や冬に行くことが多く、紅葉シーズンは初めてでした。気温は例年よりも暖かかったらしく、観光するにはいい気候でした。
きたあずの勉強会自体も楽しかったですし、紅葉を観て美味しいものを食べて、北海道を満喫できた2泊3日でした。
帰りの空港で買った富良野ヴィンテージのサッポロクラッシクビールが美味しかったので、もっとたくさん買えばよかった。