ごった煮

色々な事を書いてます

GitHub Actions で、PHP のアプリケーションを Azure WebApps にデプロイする

ほぼ静的で一部 PHP が使われているアプリケーションを Web Apps にデプロイする仕組みを GitHub Actions で用意する必要が出たので、備忘録に残します。

やりたいこと

  • 特定のブランチにソースコードが push されたらステージング環境へデプロイ
  • Pull request が通って特定のブランチにマージされたら本番環境へデプロイ

やりたいことと言えば別に簡単な事ですね では、さっそくやってみましょう

Environment に Web Apps の Publish profiles を登録する

始めに Publish profiles を Azure ポータルから取得してください。 次に、下図のように、GitHub の Settings > Environments > New environment で新しい Environment を作ります。

f:id:papemk2:20210219192536p:plain

Environment が作成出来たら、Environment secrets で新しい Secret を登録します。

f:id:papemk2:20210219192807p:plain

シークレットは、適当な名前を付けたうえで、Value に Publish profile の中身を入れてください。

これで、GitHub Actions の YAML 内から、Publish profile が参照できるようになります。

YAML を書く

次のような YAML になります。

name: Deploy PHP

on:
  push:
    branches: 
      - staging
  pull_request:
    branches:
      - master
    types: [closed]

env:
  STAGING_WEBAPP_NAME: 'Your staging web apps name' # ステージングの Web Apps 名
  PRODUCTION_WEBAPP_NAME: 'Your production web apps name' # 本番の Web Apps 名
  AZURE_WEBAPP_PACKAGE_PATH: '.' # デプロイしたい成果物のパス

jobs:
  # ステージングデプロイ用 Job
  deploy-staging:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/staging'
    steps:
      - uses: actions/checkout@v2
      - name: 'Deploy to staging'
        uses: azure/webapps-deploy@v2
        with:
          app-name: ${{ env.STAGING_WEBAPP_NAME }}
          publish-profile: ${{ secrets.STAGING_PUBLISH_PROFILE }}
          package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

  # 本番デプロイ用 Job
  deploy-production:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == true
    steps:
      - uses: actions/checkout@v2
      - name: 'Deploy to production'
        uses: azure/webapps-deploy@v2
        with:
          app-name: ${{ env.PRODUCTION_WEBAPP_NAME }}
          publish-profile: ${{ secrets.PRODUCTION_PUBLISH_PROFILE }}
          package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

ワークフローの実行は、staging ブランチに push された場合と、master ブランチへの Pull request がクローズされて且つ、マージされた場合になっています。 GitHub Actions では、明示的に Pull request がマージされたというイベントを取ることが現状出来ないため、

  pull_request:
    branches:
      - master
    types: [closed]

として、Pull request がクローズされた際にワークフローが実行されるようにして、

if: github.event.pull_request.merged == true

で対象の Pull request の状態が merged かどうかを判定して処理を実行しています。 単純に closed だけで取得すると、却下されて closed になった場合などもワークフローが実行されるので注意が必要です。

まとめ

GitHub Actions は、GitHub を使っていると非常に便利です。

Azure Pipelines と比べると、機能的に足りなかったりといった部分もありますが、Approval ワークフローが使えるようになったりと、着実に便利になっているので、 覚えて損は無いと思います。

これだけの設定で、わざわざ毎回手動でデプロイをする必要がなくなる等、ちょっとした面倒な作業を人の手から引き剥がせるのは、とても便利ですね

Azure の Blob から Blob へファイルをコピーしたい

Blob ストレージを移行するといった理由で元々ある Blob から別の Blob へファイルをコピーしたい場合があるかと思いますが、 そういった場合に使えるコマンドを備忘録として残します。

使う物

  • Azure CLI (今回は、2.18.0 を基にします)

やってみる

下記のスクリプトを実行します。

PowerShell で実行しているので、他のシェルを使う場合は、適宜改行等を調整してください。

$DestinationStorageName = "コピー先のストレージアカウント名"
$DestinationStorageKey = "コピー先のストレージアカウントキー"
$DestinationContainerName = "コピー先のコンテナ名"

$SourceStorageName = "コピー元のストレージアカウント名"
$SourceStorageKey = "コピー元のストレージアカウントキー"
$SourceContainerName = "コピー元のコンテナ名"

az storage blob copy start-batch `
--destination-container $DestinationContainerName `
--account-name $DestinationStorageName `
--account-key $DestinationStorageKey `
--source-container $SourceContainerName `
--source-account-name $SourceContainerName `
--source-account-key $SourceStorageKey

このコマンドで、コピー元のコンテナに含まれる Blob をまとめてコピー先の Blob へコピーすることが出来ます。

コピーされた Blob の状態を確認したい場合は、

az storage blob show --container-name $DestinationContainerName --name "Blob の名前" --account-key $DestinationStorageKey --account-name $DestinationStorageName

で確認が出来ます。

まとめ

start-batch を実行すると、Azure 側でコピー処理をしてくれるのでクライアントであるこちらを介す必要が無く処理が出来るのでとても簡単です。

Azure CLI を使用するとこのような処理が簡単に出来るので、ぜひ覚えてみましょう。

SQL Database に Service Endpoint で接続しようとしたらどハマりした話

Service Endpoint 便利ですよね

ところが、Azure の VM から Service Endpoint 経由で接続しようとしたところ、超どハマりしたので、備忘録に残します。

今回の構成

  • 仮想マシン : 東日本リージョンにデプロイ
  • SQL Database : 東日本リージョンにデプロイ

何が起きていたか

  • VM から Azure Data Studio を経由して SQL Database に繋ぎに行こうとしたところ接続が上手くいかなかった
  • NSG を確認しても、Service Tag で Sql.JapanEast からのアクセスをポート 1433 に対して許可していた

原因

  • そもそもポート 1433 で繋ぎに行っていなかった

理由

SQL Database の接続モードは、「リダイレクト」と「プロキシ」の二つが用意されていますが、既定で「リダイレクト」モードになっています。 このモード、使用するポートが 1433 では、無いんですね

このモードの場合、ポート 11000 ~ 11999 の範囲のポートを使用するので NSG のアウトバウンド設定でこのポート範囲を指定してあげないと、繋ぎに行けないんですね そのため、NSG でポート範囲などを絞る場合は、SQL Database のゲートウェイが使用するポートの 1433 と、11000 ~ 11999 の範囲でポートを開放しないといけません。

docs.microsoft.com

まとめ

しっかりドキュメントを読もう

2020年買って良かったもの

2020年は、結構あっという間に過ぎて行ってしまったので、備忘録も兼ねて書いてみようかと思います。

年末に新築を買いました。

一人暮らし前提で借りていた 1LDK に結婚後もそのまま住んでましたが、流石にちょっと手狭だよねということで引っ越しを決意したところ、 あれよあれよという間に家を買うことになりました。

1LDK から、4LDK に大幅ランクアップしたので、やりたい放題出来るのが有難い今日この頃です。

テレビ

WFH の流れになった辺りで、大きめのディスプレイで仕事したいなあという心境になり、今まで自宅の仕事用にしていた 29インチのウルトラワイド + 27インチのフルHD から、 自宅で使っていた 43インチの 4k Regza に仕事用ディスプレイを置き換えました。

その時に、じゃあテレビ新しくしようとなって、55インチの有機EL ブラビアを購入しました。 満足度は、かなり高いのですが、Xbox Series X 、PS5 がまさかの 4K/120FPS でのゲームプレイに対応してきたものの、このテレビは、フルHD/120FPS までしか対応しておらずゲーム機の性能を生かし切れていないので、 2021年は、LG の 4k/120FPS 対応テレビの買い足しを検討中です。

www.sony.jp

ディスプレイ

仕事用のディスプレイを 43インチ Regza にしたところ、8月頃にまさかの Regza が壊れました。 画面の下半分が映らなくなる致命的なもので、2年半ほど使ったため保証期間も切れており、修理に7万円ほど掛かるの所で買い替えを決意しました。 正直 43インチは、大きすぎるなと思っていたタイミングでもあったので、32インチの LG の 4K ディスプレイを購入しました。

丁度新型が出たタイミングだったらしく、新型を買おうとしたら、グレア液晶だっため一世代前のノングレア液晶を選択しました。

www.lg.com

ホームシアター

お国から10万円給付してもらったタイミングで、なぜか唐突にホームシアターが欲しくなり、Dolby Atmos のホームシアターを構築しました。

Sony のアンプを中心に、適当に YAMAHA のスピーカーなどをかき集めて、8万円程で構築できました。

丁度新しく買ったブラビアが、アンプを繋ぐとセンタースピーカーになれるという面白い機能を搭載していたので、中々に迫力のあるホームシアターが構築できました。 子供のころからホームシアターに憧れていたのですが、案外すんなり作れるのかと感心しました。

www.sony.jp

仕事用デスク

WFH ということで、家で仕事する機会が増えたので、学生時代から使っていたニトリの安い作業デスクを処分して、普段事務所で使っているものと同じタイプの机の大きいサイズを購入しました。 この机、サイズの割に値段もそこそこで使い勝手も良いので、次に机を新調する時にも同じものをリピートしようかなと思うくらいお気に入りの机です。

item.rakuten.co.jp

まとめ

振り返るとエンタメ用のものばかり買ってた一年だったなあと思いました。 これ以外にもクラシックゲーム機なども含めて4 ~ 5 台ほどゲーム機が増えたりしました。

毎年一応、メインの携帯電話は、買い換えているのですが、昨年は、Pixel 5 がかなり残念だったこともあり数年振りにメインの携帯電話を買い換えない珍しい年でした。(お遊びで楽天 mini は、買いましたが) 2021年は、良さげな携帯電話が出るといいなあと思う今日この頃。

App Service と VNET のお話

この投稿は、Azure Advent Calendar 2020 の 16日目の記事になります。

今回のお話は、タイトルの通り App Service と VNET 関連のお話です。

WAF でアプリケーションを保護したい!

App Service は、言わずもがな Web アプリケーションをデプロイして、動かすための箱です。 基本的にインターネットを介してアプリケーションにアクセスすると思いますが、インターネットには、悪い人たちがたくさんいるわけです。

そのような悪い人達からシステムを守るためにアクセス制限したいというのが世の常です。 よくあるパターンだと、

  • アクセス元 IP の制限
  • イントラ or 特定のネットワークからのみ繋がるようにする

みたいなことが挙げられます。 ですがこの場合、不特定多数にアクセスされる前提のシステムだと構築が難しくなります。

そこで、WAF をアプリケーションの前段に置いて WAF で、ある程度悪意のあるリクエストを防ぐというアプローチが考えられます。 App Service の前段には、Application Gateway を WAF として配置することが出来ます。

下記のような、Application Gateway を経由して App Service へアクセスする構成です。

f:id:papemk2:20201216155308p:plain
WAF01

ですがこの場合、WAF 以外からのアクセスを制限しておかないと、WAF を経由せずに App Service と通信することが可能です。

現在は、VNET Service Endpoint を使用して、特定の VNET のサブネットからの通信のみを許可する設定が可能です。

f:id:papemk2:20201216172622p:plain
WAF02

以前は、このような構成を取りたい場合、非常に高い App Service Environment を使用してインフラを構成する必要がありましたが、多くの場面でこの構成は、オーバースペックでした。 それが、現在では、VNET と通常の App Service も連携できるようになっているので、

SQL Database を安全に管理したい!

SQL Database は、言わずもがなマネージドな SQL Server です。

DB は、システムの要であり、一番に保護しないといけない対象です。 ですが SQL Database もまた、インターネット経由でアクセスするサービスなわけです。 最初に書いた通り、インターネットには、悪い人がいっぱいいます。 あなたの DB も日夜狙われているわけです。

SQL Database には、元々

  • IP 制限
  • Azure 内からの通信だけ許可

といったアクセス制限によりセキュリティを向上させる方法がありました。

ローカルからの作業時は、許可されている IP からのみ、Azure からは、Azure 内のリソースを許可してアクセスという方法が、長い間 App Service + SQL Database でアプリケーションを運用する際のよくある構成でした。

では、例えば Azure 内の仮想マシンから悪意ある第三者がアクセスしようとしたらどうなるでしょうか。

Azure 内からの通信だけ許可を有効にしていると、何事もなく繋がります。 これだと少し不安が残ります。

それならば Azure 内でも特定のリソースからしかアクセスできないようにしたいというのが人の常です。

そこで使用できるのが、Private Endpoint を用いたアクセスです。

Private Link を使用すると、Azure 内の特定の VNET に属したサブネットからのみアクセスといった制限を設けることが出来ます。

App Service の Regional VNET Integration を有効にすると、アプリは、リージョンにある VNET 内のリソースに対してアクセスすることが出来るようになります。

Private Link を使用して SQL Database に Private Endpoint を設定すると、VNET を経由して接続するための NICSQL Database に設定されます。 その Private IP に対して、Private DNS Zone で名前解決をすると、VNET Integration を有効にした App Service のアプリから、VNET を経由して SQL Database へ接続できるようになります。

f:id:papemk2:20201216185315p:plain

この構成に、先ほどの Application Gateway の構成を追加して下図のような構成にすると、アプリを WAF で保護しつつ、SQL Database を VNET からのアクセスのみに制限するといった構成が取れます。

f:id:papemk2:20201216185747p:plain
Private02

ローカルから SQL Database に繋ぎたい場合などは、VNET に VPN Gateway や、Express Route を使用して、VNET へのアクセスを確保することで接続することが出来ます。

まとめ

Private Endpoint を使用すると、インターネットを辿ることなく各リソースにアクセスが出来るようになります。 対応サービスも順次増えていっているので、よく使うものは、この方法での接続に切り替えていく方が良いかなと思います。

今までは、App Service でインターネットからのアクセスを遮断するといった構成は、難しかったですが、VNET Integration が出てきた辺りから流れが変わったように思われます。 セキュリティの意味でも、今後は、App Service でも VNET を活用して構成していくと良いかなと思います。

Visual Studio でアルファベットの大文字と小文字を変換する

文字列を大文字と小文字で変換したい場合は、結構あるあるな場面かと思います。

Visual Studio には、その機能が実は、あるのでメモ書きとして残します。

やり方

ショートカットキーが存在します。

大文字への変換

Ctrl + Shift + U

小文字への変換

Ctrl + U

※ 小文字への変換は、ドキュメント等には、Ctrl + U で明記されていますが自分の環境では、デフォルトでショートカットキーが割り当てられていませんでした。

まとめ

下記のような配列を全部大文字にしたいとなると結構面倒ですが、この機能を使えば一発なので是非覚えておきましょう。

"a","b","c","d","e","f","g","h","i","j","k","m","n","p","q","r","s","t","u","v","w","x","y","z","2","3","4","5","6","7","8","9"

Windows 環境の PHP でビルトインサーバを使用するときに環境変数をセットする方法

とある事情で PHP を書く必要に迫られたのですが Windows 環境 + ビルトインサーバで環境変数を扱う方法を忘れていたのでメモとして残します

やり方

よくある方法だと以下のような感じですよね

Foo=Bar php localhost:8000 -t パス

コマンドプロンプトPowerShell で Foo=Bar ~ みたいなことは、出来ないですよね ということで普通に set コマンドを使って環境変数を指してあげましょう

SET Foo=Bar
php localhost:8000 -t パス

Set コマンドは、使用したセッション中のみ有効な環境変数を設定してくれるコマンドです 確かに普通に環境変数をセットしてあげれば使えますね

まとめ

意外と忘れがちですよねこういうの