どもー。某ブログでクラウディアさんの隠れファン疑惑をかけられている@ag0u3 です。
Azure 触っている人で、クラウディアさんが嫌いな人なんているんですかね~?
3/12と13 に MS 北海道支店で開催のDevOps ハッカソンに参加してきました。
めっちゃ楽しいイベントでした。
■Connpass [札幌開催] DevOps ハッカソンhttp://devopsjp.connpass.com/event/24267/
このDevOps ハッカソンは全国巡業しながらやってまして、次は東京で 4/15 にやるみたいですよ~。
http://devopsjp.connpass.com/event/28195/
イベント概要
タイムスケジュールは、↓な感じだったと思います。
1日目
| 時間 | 内容 |
| 09:00-12:00 | DevOpsセッション |
| 12:00-13:00 | 昼食 |
| 13:00-13:30 | チーム分け&テーマ決め |
| 13:30-17:00 | ハッカソン |
2日目
| 時間 | 内容 |
| 09:00-12:00 | ハッカソン |
| 12:00-13:00 | 昼食 |
| 13:00-15:00 | ハッカソン |
| 15:00-16:00 | チーム発表 |
| 15:00-16:00 | 講評 |
DevOpsセッションでは、DevOpsとは的な概要セッション、あと今回は特別に午後からのハッカソンに向けて、Microsoft Azure の ARM の解説セッションがありました。
概要セッションは、いくつか刺さるキーワードがありまして、かなり楽しかったです。うちの会社の運用部門の人たち(Ops)にもこのセッションは聞かせたいなー、って思いつつ聞いてました。
チーム分け
チーム分けは、名前とやりたいことを書いた付箋をホワイトボードに貼り、全員が付箋を貼った後に、そのアイデアを一緒にやりたいと思ったところに参加者が名前を記入し、記入数が多いものをやるという感じです。
自分が書いたのは、午前中のセッションを聞いていて、Azure の App Service を構成する ARM にチャレンジしてみたいと思ったので、そんなことを書きました。
人気があったのは、以下の3つ
- 朝、忘れ物とかをしないように、アシスタントをしてくれるアプリ
- Twitterから情報をかき集めてくれるアプリ(ちゃうかな。。。)
- 美女が Azure を教えてくれるソリューション
自分は、美女というキーワードで 3 番目のソリューションにしました。
ハッカソン
チームのメンバは、3人でした。
- 発案者の北海道大学の学生の方(以降、リーダー)
- きたあずのAzure MVP の @DarkCrash3 さん(フリー素材なので)
- きたあずの雑用係の自分 ( @ag0u3 )
まず、最初の課題は、美女にどうやって Azure を教えてもらうか?ってことです。
そもそも、美女どうする?みたいな。
美女については、1時間くらい白熱した議論の結果、クラウディアさん推しで行くことになりました。
その結果、出来上がったアプリは以下のものです。
開く際は、PCの音量を最大にしてお楽しみください。
■美女とAzure(びじょとあじゅー)
http://devops0312dosanko.azurewebsites.net/
ほんで、目に見える成果物は「美女とAzure」のコンテンツなのですが、今回はDevOpsハッカソンですので、いかにDevOpsを回したかということが評価されます。
僕らがやった構成は、ざっくり書くと下記のとおりです。

クライアントは、Visual Studio 2015 で、デバッグが終わったらソース管理にチェックインします。
ソース管理は、Visual Studio Team Service を使い、チェックインされると自動ビルドが走り、そのままWeb Appのスロットにデプロイされます。
Web App のスロットで特に問題がなければ、swap し本番環境として公開されます。
本番環境は、クラウディアさんの素敵なボイスを聞くためにアクセスが集中することが予想されますので、1~10インスタンスのオートスケールにしました。
ということで、なんか大きな人的ミスはスロットのところで発見して食い止めるけど、あとはスピード命でガンガンソースを直してデプロイかけていくし、なんか変だったら古いソースでビルドしなおして、デプロイしなおすという使い捨て的なサイト開発の発想です。
ですので、バックアップは、今思うとただのオマケで、運用上使われることはないですね。
メンバも少ないので、環境回りの作業を減らしたかったので、
PaaSのWeb Apps推しな構成っすね。
ただ、この構成には、非常に大きな問題点があります。
それは、今回の DevOps の要件である、 Infrastructure as Code の要素が全くないこと!!
考えた結果、僕らのチームはキャンペーンサイトを作る企業設定とし、Web アプリの名称を登録すると、スロット付き Web App を自動的に作成する Web アプリをもう一つ作成することにしました。
システム構成は、以下のとおりです。

ARMに関しては、MSの松崎さん、牛尾さんに質問したところ、ドンピシャな情報を教えて頂いたのでほぼそのまま使いました。
下記の PowerShell を Power Shell ISE にコピペして実行すると staging という名のスロットがついた Web App が作成されます。
#Requires -Version 3.0
#Requires -Module AzureRM.Resources
#Requires -Module Azure.Storage
Param(
[string] [Parameter(Mandatory=$true)] $ResourceGroupLocation,
[string] $ResourceGroupName = 'AzureResourceGroupDemo',
[switch] $UploadArtifacts,
[string] $StorageAccountName,
[string] $StorageAccountResourceGroupName,
[string] $StorageContainerName = $ResourceGroupName.ToLowerInvariant() + '-stageartifacts',
[string] $TemplateFile = 'https://raw.githubusercontent.com/azuredk/azure-arm-hol/master/lab1-azure-webapps/step02-add-deployment-slots/complete/website.json',
[string] $ArtifactStagingDirectory = '..binDebugstaging',
[string] $AzCopyPath = '..ToolsAzCopy.exe',
[string] $DSCSourceFolder = '..DSC'
)
Import-Module Azure -ErrorAction SilentlyContinue
try {
[Microsoft.Azure.Common.Authentication.AzureSession]::ClientFactory.AddUserAgent("VSAzureTools-$UI$($host.name)".replace(" ","_"), "2.8")
} catch { }
Set-StrictMode -Version 3
$OptionalParameters = New-Object -TypeName Hashtable
#$TemplateFile = [System.IO.Path]::Combine($PSScriptRoot, $TemplateFile)
#$TemplateParametersFile = [System.IO.Path]::Combine($PSScriptRoot, $TemplateParametersFile)
if ($UploadArtifacts) {
# Convert relative paths to absolute paths if needed
$AzCopyPath = [System.IO.Path]::Combine($PSScriptRoot, $AzCopyPath)
$ArtifactStagingDirectory = [System.IO.Path]::Combine($PSScriptRoot, $ArtifactStagingDirectory)
$DSCSourceFolder = [System.IO.Path]::Combine($PSScriptRoot, $DSCSourceFolder)
Set-Variable ArtifactsLocationName '_artifactsLocation' -Option ReadOnly -Force
Set-Variable ArtifactsLocationSasTokenName '_artifactsLocationSasToken' -Option ReadOnly -Force
$OptionalParameters.Add($ArtifactsLocationName, $null)
$OptionalParameters.Add($ArtifactsLocationSasTokenName, $null)
# Parse the parameter file and update the values of artifacts location and artifacts location SAS token if they are present
$JsonContent = Get-Content $TemplateParametersFile -Raw | ConvertFrom-Json
$JsonParameters = $JsonContent | Get-Member -Type NoteProperty | Where-Object {$_.Name -eq "parameters"}
if ($JsonParameters -eq $null) {
$JsonParameters = $JsonContent
}
else {
$JsonParameters = $JsonContent.parameters
}
$JsonParameters | Get-Member -Type NoteProperty | ForEach-Object {
$ParameterValue = $JsonParameters | Select-Object -ExpandProperty $_.Name
if ($_.Name -eq $ArtifactsLocationName -or $_.Name -eq $ArtifactsLocationSasTokenName) {
$OptionalParameters[$_.Name] = $ParameterValue.value
}
}
$StorageAccountKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $StorageAccountResourceGroupName -Name $StorageAccountName).Key1
$StorageAccountContext = (Get-AzureRmStorageAccount -ResourceGroupName $StorageAccountResourceGroupName -Name $StorageAccountName).Context
# Create DSC configuration archive
if (Test-Path $DSCSourceFolder) {
Add-Type -Assembly System.IO.Compression.FileSystem
$ArchiveFile = Join-Path $ArtifactStagingDirectory "dsc.zip"
Remove-Item -Path $ArchiveFile -ErrorAction SilentlyContinue
[System.IO.Compression.ZipFile]::CreateFromDirectory($DSCSourceFolder, $ArchiveFile)
}
# Generate the value for artifacts location if it is not provided in the parameter file
$ArtifactsLocation = $OptionalParameters[$ArtifactsLocationName]
if ($ArtifactsLocation -eq $null) {
$ArtifactsLocation = $StorageAccountContext.BlobEndPoint + $StorageContainerName
$OptionalParameters[$ArtifactsLocationName] = $ArtifactsLocation
}
# Use AzCopy to copy files from the local storage drop path to the storage account container
& $AzCopyPath """$ArtifactStagingDirectory""", $ArtifactsLocation, "/DestKey:$StorageAccountKey", "/S", "/Y", "/Z:$env:LocalAppDataMicrosoftAzureAzCopy$ResourceGroupName"
if ($LASTEXITCODE -ne 0) { return }
# Generate the value for artifacts location SAS token if it is not provided in the parameter file
$ArtifactsLocationSasToken = $OptionalParameters[$ArtifactsLocationSasTokenName]
if ($ArtifactsLocationSasToken -eq $null) {
# Create a SAS token for the storage container - this gives temporary read-only access to the container
$ArtifactsLocationSasToken = New-AzureStorageContainerSASToken -Container $StorageContainerName -Context $StorageAccountContext -Permission r -ExpiryTime (Get-Date).AddHours(4)
$ArtifactsLocationSasToken = ConvertTo-SecureString $ArtifactsLocationSasToken -AsPlainText -Force
$OptionalParameters[$ArtifactsLocationSasTokenName] = $ArtifactsLocationSasToken
}
}
Login-AzureRMAccount
# Create or update the resource group using the specified template file and template parameters file
New-AzureRmResourceGroup -Name $ResourceGroupName -Location $ResourceGroupLocation -Verbose -Force -ErrorAction Stop
New-AzureRmResourceGroupDeployment -Name $ResourceGroupName `
-ResourceGroupName $ResourceGroupName `
-TemplateUri $TemplateFile `
@OptionalParameters `
-Force -Verbose
そんで、本当に作り切ったのは、下記の赤い部分。
Automationをやりきれなかったのがちょっと残念。

ハッカソンの結果
3チームの中で、一番 Infrastructure as Code と向き合ったということで、優勝することができました。
他のチームは、Microsoft Azure を使ったことがある人があまりいない(というか、ほとんどいない)という状況もありましたね。
あと、参加者はMac 使いの人も結構いたので、その辺も苦労したんじゃないかな??
僕らのチームがまず最初にやったことは、リーダーが Mac だったので、ひとまずAzure の仮想マシンで Visual Studio を使えるようにしました。これで、VS から VSTS を使う横並びの環境を早くから手に入れたってことは、地味効果が大きかったかも。
多分、↓に優勝チームってことで写真がupされると思います。(upされたら、このブログにも貼りたいな~)
まとめ
今回のハッカソン、すごい楽しかったです。
時間に追われるドキドキ感がよかったっすねー。
是非、次回の札幌開催も参加したいです。
個人的にも、App Service の ARM に取り込むことができたので満足。
作りきれなかったところは、ぼっちソンして作りたいけど。
HPH 2015 一次産業 × IT ハッカソンに参加した時に感じたのですが、ハッカソンって色んなレイアの人が来て面白いですね。
HPH 一次産業ハッカソンは、確か今年は漁業をターゲットにするってことでしたので、また何か考えよーっと
前回のハッカソンのURLを貼っておこう
https://hph2015.doorkeeper.jp/events/36183


コメント