mito’s blog

IT技術メインの雑記。思い立ったが吉日。

技術書典16にサークル参加(売り子)してきました

はじめに

技術書典には一般参加を何度も経験していますが、今回は初めてサークル参加をしました。執筆のきっかけやその覚悟につながることを期待して、書き留めておきます。


技術書典とは

技術書典は、ITや機械工作、その周辺領域に関する技術系同人誌の即売会です。
エンジニアやクリエイターが自ら執筆した本を販売し、最新の技術情報やノウハウを直接共有できる場でもあります。

techbookfest.org


オンラインマーケット開催中(6/9まで)

techbookfest.org



当日の感想

知り合いの顔も見れたし、OAuthて何?という方に売り子として拙いながらも説明したり、その場で検索して買ってくださりと参加してよかったです。 私も数冊買いましたが、これから勉強しないとと思っていたジャンルの本がピンポイントであって嬉しかったです。さすが技術書典!!
また、なにより良い刺激になりました。次回も技術書典に参加する方針で!


何で参加しようと思ったの?

以前の職場では、チームの半数が執筆経験者でした。その影響もあり、私もいつか書いてみたいと思っていました。そして、ちょうど個人的に新しいことに挑戦したいと考える時期に入り、タイミングよくAuth屋(@authyasan)さんの売り子募集のツイートを見かけ、勢いで応募しました。
売り子なので書くわけではないですが、いろいろお話も聞けたらいいなと思って。


顔合わせと打ち合わせ

オンラインでの打ち合わせを経て、顔合わせも兼ねて食事会が開かれました。私を含め4人が集まりましたが、オフラインでは全員初対面でした。
学生や若者、おじさん二人というメンバーでしたが、みんなすごく勉強熱心で感心しました。 むしろ私だけ分野が違うのでちょっと申し訳ないなと・・・自動化を広めるの楽しいよ!

お肉は最高でした。。。


当日の対応

昼頃に到着し、2周ほど各サークルを回って本を購入しました。培養肉を作っているサークルが今回は培養肉のエナジードリンクを作っていたりと話すのも楽しかったです。
売り子としては、後半はサークルに来る人も落ち着いてくるだろうとの見込みでしたが、全くそんなことはなく、改めてAuth屋さんの人気を実感しました。 上にも書きましたが、OAuthて何?という方に説明したり、その場で検索して買ってくださりと売り子をしてよかったなと。


その他

あの布PLUSのことを教えてもらったり、技術書典と技術書同人誌博覧会(技書博)の違いを聞けたのはありがたかったです。
また、TechBoosterさんがGitHubで執筆ノウハウ本を公開されています。

AI駆動開発勉強会(第2回)に現地参加してきた

はじめに

こちらに参加してきました!


参加の動機は、社内Slackで紹介されていたことと、現在の業務とは直接関係ないけど将来的には分からないと思ったからです。 あと勉強会に初めて連れ出してくれた昔の先輩が参加するので(無事会えました)。
ちなみに、私の生成AI・LLMの知識は、ChatGPTなどを使ったり用語などを調べてフンフンフンと頷いてみた程度です。



セッション動画の資料感想


GitHub Copilot Enterprise と今後のロードマップ - GitHub Copilot の最新情報とちょっと先の未来について、お知らせします

  • 登壇者
  • メモ
    • よく聞く「開発生産性」という言葉は、マネージャや管理者よりの視点
    • CopilotはIDE(開発)に留まらない、生産性にブーストをかける
      • 現在はGitHub.comすべてがCopilotを開発している
    • Copilot Workspaceのデモを実施
      • 電卓アプリに「べき乗の機能を追加して」で実装


新たなAI駆動開発の潮流 〜Devin, AutoDev, SWE Agent, GitHub Copilot Workspace等の登場と将来の開発スタイル 〜

www.docswell.com


  • 登壇者
  • メモ
    • SWE Agent
      • GPT-4などの大規模なモデルをソフトウェアエンジニアリングエージェントに変換することによって動作
    • AutoDev
    • Devin/OpenDevin
      • 自律的にシステム開発を実現する能力を持つAIによるソフトウェアエンジニア
    • GitHub Copilot
    • 最新AI駆動開発の潮流
      • ほとんどのツールが似たようなコンセプトで同じことができる
      • 企業として、社内の開発コードが外部のクラウド上経由で漏れないかが不安視されている


女子大生が100日連続で生成AIで100本のプログラムを書いたらどうなったか?

www.magicaidesk.com

  • 登壇者
    • 大塚あみ さん
  • メモ
    • ChatGPTを3000時間使って分かったこと
      • 生成AIはあなたを映し出す鏡、etc
      • コミュニケーション・継続学習・自己分析の3つが重要、常に意識して
    • 周りはChatGPTで作った低品質なレポートばかりだったので、品質の良いレポートを早く作るにはどうしたらいいか考えた
      • 楽をするために、効率の良い自動化を目指して時間を費やした
      • 海外の論文も読んだ
      • 学会で論文を発表し成功
    • ソフトウェア工学を上流工程から理解できた
    • プログラミングをAIで学んだ第一世代


プロダクトオーナー向け生成AI支援サービス:仮説検証の事例

speakerdeck.com

  • 登壇者
    • 松浦洋介 さん
  • メモ
    • ゴール:新規サービス、プロダクト開発を効率的に進める仮説検証の手法と事例を知る
    • AIの利活用で、企画から開発着手までの期間を短縮
    • 生成AIを使いながら、ジャベリンボードで仮説検証を実施した事例
      • 各Stepで生成AIを取り入れた
        • 前提条件を明らかにして、本当の課題を見つける、etc
    • 生成AIを活用したPBI補完サービス
    • 生成AIは技術革新が早い


【LT枠】Copilot Workspaceで“管制官”になろう!

speakerdeck.com

  • 登壇者
    • @eltociear さん
  • メモ
    • Copilotの機能の所感
      • 工数が30%削減できた、開発スピードが圧倒的に上がった
      • 1行のプロンプトでも簡単なものを作ってくれる、実例紹介
      • 多数の資料作成にも生かせそう


【LT枠】AIが無いと開発できない人のお話

  • 登壇者
    • @lemilemilemio さん
  • メモ
    • 今までのAI主導開発手法の推移
    • がっつりコーディングするならClaudae3がおすすめ
      • 200k Tokenまで入る
      • エラー解決パターン
        • 10週位すると解決
        • perplexityでWeb検索
        • AIでだめなら地道に解決!
      • 生成AIは成長速度をn倍にしてくれる!


【LT枠】 現地参加のみ共有


交流会に参加

いろいろとお話しできました!ありがとうございました!
また、次回も参加したいと思います。

主催:AI駆動開発勉強会 運営委員会
協力:KDDIアジャイル開発センター株式会社、クリエーションライン株式会社

PulumiのIaCコードをPythonで出力した

Pulumiとは
使い慣れたプログラミング言語を使用してインフラストラクチャコードを作成します。
オートコンプリート、型チェック、ドキュメントを備えた IDE を使用して、インフラストラクチャを定義するステートメントを作成します。


はじめに

PulumiのIaCコードは、様々な言語で出力することができます。
本記事では、Pythonで出力してみました。

参考 mitomito.hatenablog.jp

所感

今のところ、使い勝手はTerraformと変わりはなさそうという感触。
SaaSのPulumi Cloudの利用が必須で、そこでterraformでいうtfstateを管理している。
Pythonなどの言語でIaCコードを書けるので、開発者には向いているかもしれない。


単一のWebサーバを構築するコード

以下のリソースを作成するコードです。
IaC触ったことがある人は、Python知らなくても何となく読める気がします。



$ cat __main__.py 
import pulumi
import pulumi_aws as aws

# Get some configuration values or set default values.
config = pulumi.Config()
instance_type = config.get("instanceType")
if instance_type is None:
    instance_type = "t3.micro"
vpc_network_cidr = config.get("vpcNetworkCidr")
if vpc_network_cidr is None:
    vpc_network_cidr = "10.0.0.0/16"

# Look up the latest Amazon Linux 2 AMI.
ami = aws.ec2.get_ami(filters=[aws.ec2.GetAmiFilterArgs(
        name="name",
        values=["amzn2-ami-hvm-*"],
    )],
    owners=["amazon"],
    most_recent=True).id

# User data to start a HTTP server in the EC2 instance
user_data = """#!/bin/bash
echo "Hello, World from Pulumi!" > index.html
nohup python -m SimpleHTTPServer 80 &
"""

# Create VPC.
vpc = aws.ec2.Vpc("vpc",
    cidr_block=vpc_network_cidr,
    enable_dns_hostnames=True,
    enable_dns_support=True)

# Create an internet gateway.
gateway = aws.ec2.InternetGateway("gateway", vpc_id=vpc.id)

# Create a subnet that automatically assigns new instances a public IP address.
subnet = aws.ec2.Subnet("subnet",
    vpc_id=vpc.id,
    cidr_block="10.0.1.0/24",
    map_public_ip_on_launch=True)

# Create a route table.
route_table = aws.ec2.RouteTable("routeTable",
    vpc_id=vpc.id,
    routes=[aws.ec2.RouteTableRouteArgs(
        cidr_block="0.0.0.0/0",
        gateway_id=gateway.id,
    )])

# Associate the route table with the public subnet.
route_table_association = aws.ec2.RouteTableAssociation("routeTableAssociation",
    subnet_id=subnet.id,
    route_table_id=route_table.id)

# Create a security group allowing inbound access over port 80 and outbound
# access to anywhere.
sec_group = aws.ec2.SecurityGroup("secGroup",
    description="Enable HTTP access",
    vpc_id=vpc.id,
    ingress=[aws.ec2.SecurityGroupIngressArgs(
        from_port=80,
        to_port=80,
        protocol="tcp",
        cidr_blocks=["0.0.0.0/0"],
    )],
    egress=[aws.ec2.SecurityGroupEgressArgs(
        from_port=0,
        to_port=0,
        protocol="-1",
        cidr_blocks=["0.0.0.0/0"],
    )])

# Create and launch an EC2 instance into the public subnet.
server = aws.ec2.Instance("server",
    instance_type=instance_type,
    subnet_id=subnet.id,
    vpc_security_group_ids=[sec_group.id],
    user_data=user_data,
    ami=ami,
    tags={
        "Name": "webserver",
    })

# Export the instance's publicly accessible IP address and hostname.
pulumi.export("ip", server.public_ip)
pulumi.export("hostname", server.public_dns)
pulumi.export("url", server.public_dns.apply(lambda public_dns: f"http://{public_dns}"))
$ 





環境構築&プロジェクト作成

前回同様、VScodeのDevcontainerでPulumiのコンテナイメージを使用しています。 環境はGitHubに上げています。

まず、適当なディレクトリを作成し、移動します。
次に、pulumi new aws-pythonを実行します。これが便利で、プロジェクトの作成はもちろん、必要なpkgのインストールも実行してくれました。
なお、Purumiコマンドの初回実行時の場合は、アクセストークンの入力が必要です。

$ mkdir get_started/python
$ cd get_started/python/
$ 
$ pulumi new aws-python
This command will walk you through creating a new Pulumi project.

Enter a value or leave blank to accept the (default), and press <ENTER>.
Press ^C at any time to quit.

project name (python):    // ブランクのままエンターを推すと、(デフォルト値)が入る
project description (A minimal AWS Python Pulumi program):  
Created project 'python'

Please enter your desired stack name.
To create a stack in an organization, use the format <org-name>/<stack-name> (e.g. `acmecorp/dev`).
stack name (dev):   // エンター
Created stack 'dev'

aws:region: The AWS region to deploy into (us-east-1): ap-northeast-1    // 東京リージョンを指定
Saved config

Installing dependencies...

Creating virtual environment...
Finished creating virtual environment
Updating pip, setuptools, and wheel in virtual environment...
(略)
Downloading attrs-23.2.0-py3-none-any.whl (60 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 60.8/60.8 kB 59.0 MB/s eta 0:00:00
Downloading typing_extensions-4.10.0-py3-none-any.whl (33 kB)
Installing collected packages: arpeggio, typing-extensions, six, semver, pyyaml, protobuf, grpcio, dill, attrs, pulumi, parver, pulumi-aws

Successfully installed arpeggio-2.0.2 attrs-23.2.0 dill-0.3.8 grpcio-1.60.1 parver-0.5 protobuf-4.25.3 pulumi-3.111.1 pulumi-aws-6.27.0 pyyaml-6.0.1 semver-2.13.0 six-1.16.0 typing-extensions-4.10.0
Finished installing dependencies
Finished installing dependencies

Your new project is ready to go! 

To perform an initial deployment, run `pulumi up`

$ 


Pythonで出力したIaCコード

作成された各ファイルを確認していきます。

$ ls -la
total 0
drwxr-xr-x 1 vscode vscode 512 Apr 30 12:45 .
drwxr-xr-x 1 vscode vscode 512 Apr 30 12:42 ..
-rw-r--r-- 1 vscode vscode  12 Apr 30 12:45 .gitignore
-rw-r--r-- 1 vscode vscode  37 Apr 30 12:45 Pulumi.dev.yaml
-rw-r--r-- 1 vscode vscode 186 Apr 30 12:45 Pulumi.yaml
-rw-r--r-- 1 vscode vscode 219 Apr 30 12:45 __main__.py
-rw-r--r-- 1 vscode vscode  46 Apr 30 12:45 requirements.txt
drwxr-xr-x 1 vscode vscode 512 Apr 30 12:45 venv
$ ls -l ./venv/
total 0
drwxr-xr-x 1 vscode vscode 512 Apr 30 12:48 bin
drwxr-xr-x 1 vscode vscode 512 Apr 30 12:45 include
drwxr-xr-x 1 vscode vscode 512 Apr 30 12:45 lib
lrwxrwxrwx 1 vscode vscode   3 Apr 30 12:45 lib64 -> lib
-rw-r--r-- 1 vscode vscode  76 Apr 30 12:45 pyvenv.cfg
$ 


  • Pulumi.yaml
    • Yamlファイルではあるのですが、Yamlで出力した内容とは異なり、環境と言語が指定されているのみです
    • Yamlで出力した場合は、例えばS3バケットなどAWSリソース情報が記載されます。
$ cat Pulumi.yaml 
name: python
runtime:
  name: python
  options:
    virtualenv: venv
description: A minimal AWS Python Pulumi program
config:
  pulumi:tags:
    value:
      pulumi:template: aws-python
$


  • Pulumi.dev.yaml
    • Yamlで出力した内容と同じで、リージョン情報のみが記載されています。
$ cat Pulumi.dev.yaml 
config:
  aws:region: ap-northeast-1


  • requirements.txt
$ cat requirements.txt 
pulumi>=3.0.0,<4.0.0
pulumi-aws>=6.0.2,<7.0.0


$ cat __main__.py 
"""An AWS Python Pulumi program"""

import pulumi
from pulumi_aws import s3

# Create an AWS resource (S3 Bucket)
bucket = s3.Bucket('my-bucket')

# Export the name of the bucket
pulumi.export('bucket_name', bucket.id)


Pulumi CloudでプロジェクトをYaml出力と比較したところ、言語の違いだけでこれといった差異はありませんでした。




スタックのデプロイ

pulumiコマンドで、リソースを作成します。

$ pulumi up
Previewing update (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/python/dev/previews/***

     Type                 Name        Plan       
 +   pulumi:pulumi:Stack  python-dev  create     
 +   └─ aws:s3:Bucket     my-bucket   create     

Outputs:
    bucket_name: output<string>

Resources:
    + 2 to create

Do you want to perform this update? yes
Updating (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/python/dev/updates/1

     Type                 Name        Status           
 +   pulumi:pulumi:Stack  python-dev  created (5s)     
 +   └─ aws:s3:Bucket     my-bucket   created (2s)     

Outputs:
    bucket_name: "my-bucket-e5e00c1"

Resources:
    + 2 created

Duration: 9s

$ 



スタックのデストロイ

pulumiコマンドで、作成したリソースを削除します。

$ pulumi destroy
Previewing destroy (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/python/dev/previews/e75bfeab-cb2b-4086-b33b-22a0d77bad9e

     Type                 Name        Plan       
 -   pulumi:pulumi:Stack  python-dev  delete     
 -   └─ aws:s3:Bucket     my-bucket   delete     

Outputs:
  - bucket_name: "my-bucket-e5e00c1"

Resources:
    - 2 to delete

Do you want to perform this destroy? yes
Destroying (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/python/dev/updates/2

     Type                 Name        Status              
 -   pulumi:pulumi:Stack  python-dev  deleted (0.49s)     
 -   └─ aws:s3:Bucket     my-bucket   deleted (0.81s)     

Outputs:
  - bucket_name: "my-bucket-e5e00c1"

Resources:
    - 2 deleted

Duration: 4s

The resources in the stack have been deleted, but the history and configuration associated with the stack are still maintained. 
If you want to remove the stack completely, run `pulumi stack rm dev`.
$ 

Pulimi Cloudのスタックの削除

Pulimi Cloudにはスタックが残っているので、pulumi stack rm devで完全に削除します。
なお、IaCコードファイルは残ります。

$ pulumi stack rm dev
This will permanently remove the 'dev' stack!
Please confirm that this is what you'd like to do by typing `dev`: dev
Stack 'dev' has been removed!
$  
$ ls
Pulumi.yaml  __main__.py  __pycache__  requirements.txt  venv
$ 


その他

AWSクレデンシャルを登録しなかった場合のエラー

この程度のエラーであれば分かりやすいです。対応方法も提示されています。

error: pulumi:providers:aws resource 'default_6_32_0' has a problem: No valid credential sources found.

$ pulumi up
Previewing update (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/python/dev/previews/b74b3442-46fc-4bf7-955f-5aed8248d705

Downloading plugin: 229.75 MiB / 229.75 MiB [======================] 100.00% 23s

[resource plugin aws-6.32.0] installing
     Type                     Name            Plan       Info
 +   pulumi:pulumi:Stack      python-dev      create     
     └─ pulumi:providers:aws  default_6_32_0             1 error

Diagnostics:
  pulumi:providers:aws (default_6_32_0):
    error: pulumi:providers:aws resource 'default_6_32_0' has a problem: No valid credential sources found.
    Please see https://www.pulumi.com/registry/packages/aws/installation-configuration/ for more information about providing credentials.
    NEW: You can use Pulumi ESC to set up dynamic credentials with AWS OIDC to ensure the correct and valid credentials are used.
    Learn more: https://www.pulumi.com/registry/packages/aws/installation-configuration/#dynamically-generate-credentials

IaCツールのPulumiに入門、IaCコードをYamlで出力した


はじめに

PulumiはオープンソースのIaCツールで、クラウドリソースのプロビジョニングとデプロイを行います。
TerraformやOpenTofu相当の役割を担えます。
それらとの大きな違いの一つは、定義ファイルが複数のプログラミング言語で書けるという点です。そこが気になって触ってみました。

Pulumi - Infrastructure as Code in Any Programming Language


主な特徴は以下の通りです。


Pulumi Cloudのダッシュボードです。Pulumiの利用に登録必須で、個人利用は無料です。


基本的なコマンドの流れです。

Pulumi.yamlの有無 Pulumi Cloud登録の有無 AWSリソースの有無 実行コマンド 結果
なし なし なし pulumi new aws-yaml Pulumi.yamlを作成し、Pulumi Cloudにも登録する
あり あり なし pulumi up Yesでリソースを作成する
あり あり あり pulumi destroy Yesでリソースを削除する
あり あり なし pulumi stack rm dev スタック名の入力で、Pulumi Cloudの登録を削除する
あり なし なし rm Pulumi.yaml Pulumi.yamlを削除する



Get Started(S3バケットの構築)

PulumiでAWSのS3バケットを構築し、静的Webサイトをホスティングする手順です。
本記事では、s3バケットの構築までを行います。

Get started with Pulumi & AWS | Pulumi Docs


環境の構築

まず、公式ページでPulumi Cloudのアカウントを作成します。

Pulumi - Infrastructure as Code in Any Programming Language

次にPulumiをインストールしますが、Pulumi公式のコンテナイメージがDockerhubで公開されていますので、それをVscodeのDevcontaierで利用します。

今回Pulumiの定義ファイルはYamlで書くので、言語ランタイムのインストールは不要です。

環境変数に、AWSのアクセスキーとシークレットアクセスキーを設定します。
なお、aws cliはコンテナイメージにインストール済みです。

$ aws --version
aws-cli/2.15.30 Python/3.11.8 Linux/5.15.146.1-microsoft-standard-WSL2 exe/x86_64.debian.11 prompt/off


$ export AWS_ACCESS_KEY_ID="<YOUR_ACCESS_KEY_ID>"
$ export AWS_SECRET_ACCESS_KEY="<YOUR_SECRET_ACCESS_KEY_ID>"


適当な作業ディレクトリを作成します。

$ mkdir -p get_started/yaml   // 適当なディレクトリを作成
$ cd get_started/yaml         // yamlディレクトリは他の言語と環境が混ざらないように


プロジェクトの作成

Pulumi CLIコマンドを実行し、プロジェクトを作成します。

$ pulumi new aws-yaml
Manage your Pulumi stacks by logging in.
Run `pulumi login --help` for alternative login options.
Enter your access token from https://app.pulumi.com/account/tokens  // URLを開いてトークンを作成する
    or hit <ENTER> to log in using your browser                   : **********


  Welcome to Pulumi!

  Pulumi helps you create, deploy, and manage infrastructure on any cloud using
  your favorite language. You can get started today with Pulumi at:

      https://www.pulumi.com/docs/get-started/

  Tip: Resources you create with Pulumi are given unique names (a randomly
  generated suffix) by default. To learn more about auto-naming or customizing resource
  names see https://www.pulumi.com/docs/intro/concepts/resources/#autonaming.


This command will walk you through creating a new Pulumi project.

Enter a value or leave blank to accept the (default), and press <ENTER>.
Press ^C at any time to quit.

project name (yaml):      // ブランクでEnterを押すと、デフォルト名のyamlが入力される。以降、デフォルトで進める
project description (A minimal AWS Pulumi YAML program):  
Created project 'yaml'

Please enter your desired stack name.
To create a stack in an organization, use the format <org-name>/<stack-name> (e.g. `acmecorp/dev`).
stack name (dev):     // エンター
Created stack 'dev'

aws:region: The AWS region to deploy into (us-east-1): ap-northeast-1   // 東京リージョンを指定
Saved config

Your new project is ready to go! 

To perform an initial deployment, run `pulumi up`

$ 


Pulumi.yamlPulumi.dev.yamlが作成されます。

  • Pulumi.yaml
    • プロジェクトとスタック リソースを管理するプログラムの両方を定義します。
  • Pulumi.dev.yaml
    • 初期化したスタックの構成値が含まれています。
$ ls -la
total 0
drwxr-xr-x 1 vscode vscode 512 Mar 20 09:11 .
drwxr-xr-x 1 vscode vscode 512 Mar 20 07:42 ..
-rw-r--r-- 1 vscode vscode  37 Mar 20 09:11 Pulumi.dev.yaml
-rw-r--r-- 1 vscode vscode 298 Mar 20 09:08 Pulumi.yaml


それぞれの内容は以下になります。

$ cat Pulumi.yaml 
name: yaml
runtime: yaml
description: A minimal AWS Pulumi YAML program
config:
  pulumi:tags:
    value:
      pulumi:template: aws-yaml
outputs:
  # Export the name of the bucket
  bucketName: ${my-bucket.id}
resources:
  # Create an AWS resource (S3 Bucket)
  my-bucket:
    type: aws:s3:Bucket


  • Pulumi.dev.yaml
    • 東京リージョンを指定します。
    • 環境変数にリージョンを設定していても、プロンプトで聞かれます。
$ cat Pulumi.dev.yaml 
config:
  aws:region: ap-northeast-1


作成したプロジェクトは、Pulumi Cloudでは以下のように表示されます。
GitHubアカウントでサインインしたからか、クローンしたGitHubリポジトリでプロジェクトを作成したからなのか、GitHubリポジトリも表示されています。




リソースの構築

pulumiコマンドで、リソースを作成します。

$ pulumi up
Previewing update (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/yaml/dev/previews/******-****-****-****-******

Downloading plugin: 215.98 MiB / 215.98 MiB [======================] 100.00% 44s

[resource plugin aws-6.27.0] installing
     Type                 Name       Plan       
 +   pulumi:pulumi:Stack  yaml-dev   create     
 +   └─ aws:s3:Bucket     my-bucket  create     

Outputs:
    bucketName: output<string>

Resources:
    + 2 to create

Do you want to perform this update?  [Use arrows to move, type to filter]
  yes
> no
  details


定義ファイルを実行した場合のプレビューを表示します。
Terraform plan相当の意味を持ち、作成/差分/削除のリソースが表示されます。
その後に実行するコマンドは、3つの選択があります。

  • yes
    • 表示したリソースを構築します。
  • no
    • 構築せず、プロンプトに戻ります。
  • details
    • 差分リソースの詳細を表示します。


矢印キーで yes を選択します。

Do you want to perform this update? yes
Updating (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/yaml/dev/updates/1

     Type                 Name       Status           
 +   pulumi:pulumi:Stack  yaml-dev   created (4s)     
 +   └─ aws:s3:Bucket     my-bucket  created (2s)     

Outputs:
    bucketName: "my-bucket-******"

Resources:
    + 2 created

Duration: 6s

$
$ pulumi stack output bucketName
my-bucket-******
$ 




もう一度pulumi upを実行すると、プレビューの結果が2 unchangedに変わりました。

$ pulumi up
Previewing update (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/yaml/dev/previews/******-****-****-****-**********

     Type                 Name      Plan     
     pulumi:pulumi:Stack  yaml-dev           

Resources:
    2 unchanged

Do you want to perform this update?  [Use arrows to move, type to filter]
  yes
> no
  details


リソースの削除

pulumiコマンドで、作成したリソースを削除します。

$ pulumi destroy
Previewing destroy (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/yaml/dev/previews/******-****-****-****-**********

     Type                 Name       Plan       
 -   pulumi:pulumi:Stack  yaml-dev   delete     
 -   └─ aws:s3:Bucket     my-bucket  delete     

Outputs:
  - bucketName: "my-bucket-******"

Resources:
    - 2 to delete

Do you want to perform this destroy?  [Use arrows to move, type to filter]
  yes
> no
  details

Do you want to perform this destroy? yes
Destroying (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/yaml/dev/updates/2

     Type                 Name       Status              
 -   pulumi:pulumi:Stack  yaml-dev   deleted (0.51s)     
 -   └─ aws:s3:Bucket     my-bucket  deleted (0.88s)     

Outputs:
  - bucketName: "my-bucket-******"

Resources:
    - 2 deleted

Duration: 4s

The resources in the stack have been deleted, but the history and configuration associated with the stack are still maintained. 
If you want to remove the stack completely, run `pulumi stack rm dev`.
$ 



Pulimi Cloudにはスタックが残っているので、pulumi stack rm devで完全に削除します。

$ pulumi stack rm dev
This will permanently remove the 'dev' stack!
Please confirm that this is what you'd like to do by typing `dev`: dev
Stack 'dev' has been removed!
$



EC2の構築

テンプレートvm-aws-yamlを使って、EC2を構築します。

プロジェクトの作成

コマンドの流れはS3バケットの構築と変わりません。

$ mkdir -p my-virtual-machine/yaml && cd my-virtual-machine/yaml
$ 
$ pulumi new vm-aws-yaml
This command will walk you through creating a new Pulumi project.

Enter a value or leave blank to accept the (default), and press <ENTER>.
Press ^C at any time to quit.

project name (yaml):  
project description (A Pulumi YAML program to deploy a virtual machine on Amazon EC2):  
Created project 'yaml'

Please enter your desired stack name.
To create a stack in an organization, use the format <org-name>/<stack-name> (e.g. `acmecorp/dev`).
stack name (dev):  
Created stack 'dev'

aws:region: The AWS region to deploy into (us-west-2): ap-northeast-1 
instanceType: The Amazon EC2 instance type (t3.micro):  
vpcNetworkCidr: The network CIDR to use for the VPC (10.0.0.0/16):  
Saved config

Your new project is ready to go! 

To perform an initial deployment, run `pulumi up`

$ 


作成したPulumi.yamlです。
テンプレートでは、シンプルなWEBサーバを公開するために、VPC、Subnet、SG、InternetGW、EC2などを構築します。

$ cat Pulumi.yaml 
name: yaml
runtime: yaml
description: A Pulumi YAML program to deploy a virtual machine on Amazon EC2
config:
  instanceType:
    type: string
    default: t3.micro
  pulumi:tags:
    value:
      pulumi:template: vm-aws-yaml
  vpcNetworkCidr:
    type: string
    default: 10.0.0.0/16
# Export the instance's publicly accessible IP address and hostname.            
outputs:
  hostname: ${server.publicDns}
  ip: ${server.publicIp}
  url: http://${server.publicDns}
resources:
  # Create an internet gateway.
  gateway:
    properties:
      vpcId: ${vpc.id}
    type: aws:ec2:InternetGateway
  # Create a route table.
  routeTable:
    properties:
      routes:
        - cidrBlock: 0.0.0.0/0
          gatewayId: ${gateway.id}
      vpcId: ${vpc.id}
    type: aws:ec2:RouteTable
  # Associate the route table with the public subnet.
  routeTableAssociation:
    properties:
      routeTableId: ${routeTable.id}
      subnetId: ${subnet.id}
    type: aws:ec2:RouteTableAssociation
  # Create a security group allowing inbound access over port 80 and outbound
  # access to anywhere.
  secGroup:
    properties:
      description: Enable HTTP access
      egress:
        - cidrBlocks:
            - 0.0.0.0/0
          fromPort: 0
          protocol: -1
          toPort: 0
      ingress:
        - cidrBlocks:
            - 0.0.0.0/0
          fromPort: 80
          protocol: tcp
          toPort: 80
      vpcId: ${vpc.id}
    type: aws:ec2:SecurityGroup
  # Create and launch an EC2 instance into the public subnet.
  server:
    properties:
      ami: ${ami}
      instanceType: ${instanceType}
      subnetId: ${subnet.id}
      tags:
        Name: webserver
      userData: ${userData}
      vpcSecurityGroupIds:
        - ${secGroup}
    type: aws:ec2:Instance
  # Create a subnet that automatically assigns new instances a public IP address.
  subnet:
    properties:
      cidrBlock: 10.0.1.0/24
      mapPublicIpOnLaunch: true
      vpcId: ${vpc.id}
    type: aws:ec2:Subnet
  # Create VPC.
  vpc:
    properties:
      cidrBlock: ${vpcNetworkCidr}
      enableDnsHostnames: true
      enableDnsSupport: true
    type: aws:ec2:Vpc
variables:
  # Look up the latest Amazon Linux 2 AMI.
  ami:
    fn::invoke:
      arguments:
        filters:
          - name: name
            values:
              - "amzn2-ami-hvm-*"
        mostRecent: true
        owners:
          - "amazon"
      function: aws:ec2:getAmi
      return: id
  # User data to start a HTTP server in the EC2 instance
  userData: |
    #!/bin/bash
    echo "Hello, World from Pulumi!" > index.html
    nohup python -m SimpleHTTPServer 80 &
$ 


リソースの構築

pulumi upでデプロイします。

$ pulumi up
Previewing update (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/yaml/dev/previews/********-****-****-****-**********

     Type                              Name                   Plan       
 +   pulumi:pulumi:Stack               yaml-dev               create     
 +   ├─ aws:ec2:Vpc                    vpc                    create     
 +   ├─ aws:ec2:Subnet                 subnet                 create     
 +   ├─ aws:ec2:SecurityGroup          secGroup               create     
 +   ├─ aws:ec2:InternetGateway        gateway                create     
 +   ├─ aws:ec2:RouteTable             routeTable             create     
 +   ├─ aws:ec2:RouteTableAssociation  routeTableAssociation  create     
 +   └─ aws:ec2:Instance               server                 create     

Outputs:
    hostname: output<string>
    ip      : output<string>
    url     : output<string>

Resources:
    + 8 to create

Do you want to perform this update? yes
Updating (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/yaml/dev/updates/1

     Type                              Name                   Status              
 +   pulumi:pulumi:Stack               yaml-dev               created (40s)       
 +   ├─ aws:ec2:Vpc                    vpc                    created (12s)       
 +   ├─ aws:ec2:InternetGateway        gateway                created (0.95s)     
 +   ├─ aws:ec2:Subnet                 subnet                 created (11s)       
 +   ├─ aws:ec2:SecurityGroup          secGroup               created (3s)        
 +   ├─ aws:ec2:RouteTable             routeTable             created (1s)        
 +   ├─ aws:ec2:RouteTableAssociation  routeTableAssociation  created (0.76s)     
 +   └─ aws:ec2:Instance               server                 created (13s)       

Outputs:
    hostname: "ec2-13-112-244-67.ap-northeast-1.compute.amazonaws.com"
    ip      : "13.112.244.67"
    url     : "http://ec2-13-112-244-67.ap-northeast-1.compute.amazonaws.com"

Resources:
    + 8 created

Duration: 41s

$ 


無事にアクセスできました。



リソースの削除

確認後は、リソースを削除します。

$ pulumi destroy
Previewing destroy (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/yaml/dev/previews/*********-****-****-****-*********

     Type                              Name                   Plan       
 -   pulumi:pulumi:Stack               yaml-dev               delete     
 -   ├─ aws:ec2:RouteTableAssociation  routeTableAssociation  delete     
 -   ├─ aws:ec2:RouteTable             routeTable             delete     
 -   ├─ aws:ec2:Instance               server                 delete     
 -   ├─ aws:ec2:SecurityGroup          secGroup               delete     
 -   ├─ aws:ec2:InternetGateway        gateway                delete     
 -   ├─ aws:ec2:Subnet                 subnet                 delete     
 -   └─ aws:ec2:Vpc                    vpc                    delete     

Outputs:
  - hostname: "ec2-13-112-244-67.ap-northeast-1.compute.amazonaws.com"
  - ip      : "13.112.244.67"
  - url     : "http://ec2-13-112-244-67.ap-northeast-1.compute.amazonaws.com"

Resources:
    - 8 to delete

Do you want to perform this destroy? yes
Destroying (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/mito-201/yaml/dev/updates/2

     Type                              Name                   Status              
 -   pulumi:pulumi:Stack               yaml-dev               deleted (0.26s)     
 -   ├─ aws:ec2:RouteTableAssociation  routeTableAssociation  deleted (0.76s)     
 -   ├─ aws:ec2:RouteTable             routeTable             deleted (0.95s)     
 -   ├─ aws:ec2:Instance               server                 deleted (61s)       
 -   ├─ aws:ec2:Subnet                 subnet                 deleted (0.70s)     
 -   ├─ aws:ec2:SecurityGroup          secGroup               deleted (1s)        
 -   ├─ aws:ec2:InternetGateway        gateway                deleted (1s)        
 -   └─ aws:ec2:Vpc                    vpc                    deleted (1s)        

Outputs:
  - hostname: "ec2-13-112-244-67.ap-northeast-1.compute.amazonaws.com"
  - ip      : "13.112.244.67"
  - url     : "http://ec2-13-112-244-67.ap-northeast-1.compute.amazonaws.com"

Resources:
    - 8 deleted

Duration: 1m9s

The resources in the stack have been deleted, but the history and configuration associated with the stack are still maintained. 
If you want to remove the stack completely, run `pulumi stack rm dev`.
$
$ pulumi stack rm dev
This will permanently remove the 'dev' stack!
Please confirm that this is what you'd like to do by typing `dev`: でdev
Stack 'dev' has been removed!
$ 


その他

コマンドフロー

リソース作成から削除のコマンドフローを、定義ファイルとクラウドの登録状況の遷移と合わせてまとめました。

Pulumi.yamlの有無 Pulumi Cloud登録の有無 AWSリソースの有無 実行コマンド 結果
なし なし なし pulumi new aws-yaml Pulumi.yamlを作成し、Pulumi Cloudにも登録する
あり あり なし pulumi up Yesでリソースを作成する
あり あり あり pulumi destroy Yesでリソースを削除する
あり あり なし pulumi stack rm dev スタック名の入力で、Pulumi Cloudの登録を削除する
あり なし なし pulumi stack init スタック名の入力で、Pulumi Cloudに登録する
あり なし なし pulumi up <org-name>/スタック名の入力でPulumi Cloudに登録し、Yesでリソースを作成する
あり あり あり pulumi down Yesでリソースを削除する。Pulumi Cloudは削除しない
あり あり あり pulumi stack rm dev スタック名を入力しても、エラーで失敗する
なし なし なし pulumi up Pulumi.yamlがないため、コマンドエラー


新規プロジェクトは、空のディレクトリで作成できる

ファイルがあるディレクトリで、新規プロジェクトを作成しようとしても失敗します。
Pulumi.yamlのファイル名を変更しても、作成に失敗しました。

$ pulumi new aws-yaml
error: /workspaces/pulumi_learning/get_started/yaml is not empty; rerun in an empty directory, pass the path to an empty directory to --dir, or use --force
$ 

VScodeのDevContainerでC言語に再入門した

はじめに

新卒時代にCで組み込み系に携わっていたけど、それ以降はたまにVBAやShellScriptを、業務ではAnsibleやTeraformで定義ファイルを書いていました。 最近、プログラミングを学びなおすのに良さそうな複数の理由ができたので、経験のあるCで100本ノックを始めてみました。



感想

普通に楽しい。草で可視化されていくのもいい、草原にしたい。
気分転換にもいいかもしれない。
もう少しやったらGoあたりに手を出してみようかなと。


環境

VScodeのDevcontainerを使い、Cの開発環境を用意しています。
Dockerコンテナイメージは、Microsoft公式のイメージを利用します。
c以外も用意されているので、他言語で100本ノックを実施するとき参考になります。

  1. Docker Desktopをインストールする
  2. VScode をインストールする
  3. VScode のエクステンション「Dev Containers」をインストールする
  4. リポジトリをクローンする
  5. DevContainerに接続する


GitHubの設定

特に公開する気がなければ不要です。
トークンやメールアドレスの非表示設定などをGitHubのReadmeに載せています。


ファイルを作成後、コンパイル、実行するまでの流れ

knock00のHello World表示例です。

$ ls
main.c
$
$ more main.c
#include <stdio.h>

int main(void)
{
    printf("Hello World\n");
}
$
$ gcc main.c
$
$ ls
a.out  main.c
$
$ ./a.out
Hello World