TerraformでAWS上のASAvを構築/破壊してみた。

Fujitsu Advent Calendarの10日目です。
今年一番「これめっちゃええやん…」と感じた出来事なのでまとめようと思います。

# 背景
「 **あーASAvをサクッと立てて検証したいなー** 」

「ライセンスやイメージも用意出来てない。
出来れば会社のFWとか意識したくないので、CML,GNS3,EVE-NGは無し」
　　　　　　↓
「せや。AWSで構築したろ。あれ。作り方忘れた。
また一から調べて構築せんとあかんのか…」

こんな時ありますよね？僕はありました。

と言うことで今回は、AWSにASAvを楽に構築した方法を書いていきます。

# 概要
①**AWS** 上で**ASAv** を使える様にする
②**Terraform** で構成を設定/構築
③`terraform destroy` で課金されるAWS上のリソースが消える事を確認
こんな流れでいきます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730261/98305fe1-859c-094a-6da4-4e6ca3205be4.jpeg" width="700">


# 環境
Windows 10 Enterprise 上でWSL2を動かしています。
Ubuntu、Pythonを利用しています。

### Version
```
$cat
 /etc/os-release
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"

$python3 -V
Python 3.8.10

>wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Running         2
```
# Terraformとは？
>Terraform は、HashiCorp によって作成されたオープンソースの構成としてのインフラストラクチャ ソフトウェア ツールです。

マルチクラウド上のコンピュータやネットワークの構築を自動化する事ができます。

Terraformを利用すると
「**とりあえずAWSでASAvを起動したけどインターネット繋がらない…何が足りないんだ…**」ってのが無くなります。
今回は”インターネットに接続するまでに必要な設定”を**Terraform**を利用して**ASAv**や**AWS**の設定を事前に用意できます。
一度完成できれば、次使う時には完成された設定なので設定不足は無いわけですね。
いやー精神的に良いですね。

この記事を読んでる人は、サクッと構築したい人が多いと思いますので詳細説明を割愛します。

https://www.terraform.io/


# 実践編
AWS用のアカウントが無い人はまず作りましょう。

https://aws.amazon.com/jp/

## ①**AWS** 上で**ASAv** を使える様にする
AWSのサービスで[AWS Marketplace]を利用します。

[製品を検出]>「ASAv」で検索すれば一番上にでてくる、
**Cisco Secure Firewall ASA Virtual - BYOL**を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730261/c2c2eef3-a344-1f54-bccf-41b607b4707e.jpeg" width="700">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730261/6a2224fc-4f1b-d69f-0934-3bc0698e5074.jpeg" width="700">

上記の画面が出てくると思います。
そのまま

"**Countinue to Subscribe**"を選択
"**Accept Termsn**"で規約に同意

**Thank you for subscribing**が出てくれば問題ないと思います。

:::note info
Subscirbingと書いてますが、すぐに料金が発生するわけではありません。
Ciscoが定義した条件に同意しますって事を意味っぽいです。
ASAvをインスタンスとして起動している間は勿論課金されます。
:::

## ASAのSSHキーを生成
[EC2]>キーペア>キーペア作成
ここでは「cisco_asav_keypair」と言う名前でpemファイルを生成してます。
後で出てくるTerraformのコードの中で利用します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730261/07da6d52-c155-1a5b-a9e1-dcbcfd669f85.jpeg" width="700">

自身の端末からSSHする時、怒られない様に`/.ssh`に先程生成したpemファイルを格納しておきます。

``` terminal: Terminal
hmasayuk@:Downloads$ cp cisco_asav_keypair.pem ~/.ssh/cisco_asav_keypair.pem
hmasayuk@:Downloads$
hmasayuk@:Downloads$ cd ~/.ssh
hmasayuk@:.ssh$
hmasayuk@:.ssh$ ls
cisco_asav_keypair.pem  id_git_rsa      id_rsa      known_hosts
config                  id_git_rsa.pub  id_rsa.pub  known_hosts.old

hmasayuk@:.ssh$ sudo chmod 0400 cisco_asav_keypair.pem
hmasayuk@:.ssh$
```

## IAMユーザを作成する
[IAM]>[アクセス管理]>[ユーザを追加]で追加できます。
管理者権限を持ったIAMを作成します。

*アクセスキー・プログラムによるアクセス*にチェックを入れましょう。
TerraformからAWSに通信するためのアクセスキーとシークレットキーを発行します。
ユーザ名は「TerraformAdminUser」にしました。

![rapture_202212081705202.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730261/9833dc6c-07b7-10a3-15ff-0af279112d0b.jpeg)

![rapture_20221208170600s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730261/34945ae4-59ba-a637-66ef-fe5bd4404ad5.jpeg)

tagの項目はそのままStep進めて大丈夫です。
（空欄のまま）
Stepを進めると以下が表示されます。

**・アクセスキーID**
**・シークレットアクセスキー**

閉じないでおくか、ひっそりメモしましょう。

本来、IAMはできるだけ限定的な権限を付けてあげましょう！！！

環境変数の設定をします。
Terminalで先程取得した値をExportします。

``` terminal:Terminal
hmasayuk@:$ export AWS_ACCESS_KEY_ID="アクセスキーID"
hmasayuk@:$ export AWS_SECRET_ACCESS_KEY="シークレットアクセスキー"
hmasayuk@:$ export AWS_DEFAULT_REGION="us-east-1"
```
リージョンをus-eastにしている理由は参考にしているコードに合わせているからです。
コード上のリージョンと設定を変えれば動きますが、今回はこのまま行きます。

これでローカルのTerminalからTerraformを実行できる準備ができました。


# ②**Terraform** で構成を設定/構築
こちらのコードを利用しました。

https://github.com/KyMidd/AWSCiscoASAvTerraform

venvを使って仮想環境で実行します。
``` terminal: 準備編
hmasayuk@:Codes$ python3 -m venv Terraform
hmasayuk@:Codes$
hmasayuk@:Codes$
hmasayuk@:Codes$ source Terraform/bin/activate
(Terraform) hmasayuk@:Terraform$ git clone https://github.com/KyMidd/AWSCiscoASAvTerraform.git
Cloning into 'AWSCiscoASAvTerraform'...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (16/16), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 16 (delta 6), reused 14 (delta 4), pack-reused 0
Unpacking objects: 100% (16/16), 3.71 KiB | 14.00 KiB/s, done.
hmasayuk@:Codes$
```

格納されている`main.tf`の12~17行目の部分を見ていきます。
・my_pyblic_ip (AWSのセキュリティグループに関係してくる)
・ssh_key_name
上記は各設定に合わせて編集しましょう。

内容については長くなるので、コードを眺めて「あーここがあの設定ね」と納得しててください。

``` tf: main.tf 12行~17行
locals {
  cisco_asav_name       = "CiscoASAv_hmasayuk"  # Just for fun, name your ASAv anything you'd like!
  my_public_ip          = "自端末のIP"  # Update this to your public IP when deploying
  ssh_key_name          = "cisco_asav_keypair"  # Update only if you've created an SSH key with a different name than cisco_asav_keypair
  asav_public_facing_ip = "172.16.20.10"
}
```
中身はASAの設定やリージョンについて記載されています。
設定変更したい場合はこのファイルを編集します。

::: note info
`aws_cisco_asav_config.txt`
上記のファイルはDay0のConfigです。
中身を見ると`username admin nopassword privilege 15`と記載あります。
ログイン情報なので覚えておきましょう。
:::

## Terraform実行！

`main.tf`が格納されているディレクトリで`terraform init`を実行。
``` Terminal: Terminal
(Terraform) hmasayuk@:AWSCiscoASAvTerraform$ terraform init
terraform: command not found
```
インストール忘れてるとこういう風に怒られます。
インストールしましょう。
私はbrewで`brew install terraform`しました。

https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli

改めて実行
`terraform init`

``` Terminal: Terminal
(Terraform) hmasayuk@:AWSCiscoASAvTerraform$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 2.36.0"...
- Installing hashicorp/aws v2.36.0...
- Installed hashicorp/aws v2.36.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

╷
│ Warning: Version constraints inside provider configuration blocks are deprecated
│
│   on main.tf line 9, in provider "aws":
│    9:   version = "~> 2.36.0"
│
│ Terraform 0.13 and earlier allowed provider version constraints inside the provider
│ configuration block, but that is now deprecated and will be removed in a future version of
│ Terraform. To silence this warning, move the provider version constraint into the
│ required_providers block.
╵

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
(Terraform) hmasayuk@:AWSCiscoASAvTerraform$

```

**Terraform has been successfully initialized!**
が出力されてれば大丈夫そうですね。

warning出てますが「非推奨の設定で将来のバージョンでなくなるので気を付けて」との事でした。
`main.tf`のprovider "aws"でversionの部分ですね。
気になる人はコメントアウトしましょう。

``` tf:main.tf
# Download any stable version in AWS provider of 2.36.0 or higher in 2.36 train
#provider "aws" {
#  region  = "us-east-1a"
#  version = "~> 2.36.0"
#}

```

続いて`terraform apply`を実行します。
Terraformが設定内容を解析してAWSに構築する内容を準備します。
以下の質問に`yes`でEnterすると構築が開始されます。
``` Terminal: Terminal
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes 👈自分で入力！！
```

問題なく進むとパブリックIPが出力されます。

``` Terminal: Terminal
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_instance.cisco_asav: Creating...
aws_instance.cisco_asav: Still creating... [10s elapsed]
aws_instance.cisco_asav: Still creating... [20s elapsed]
aws_instance.cisco_asav: Creation complete after 20s [id=i-018b5564b6b2d0fdf]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

asav_public_ip = "34.194.120.227"
```

時間が結構かかるのでパブリックIPにPingを打ち続けて待ちましょう。

```Terminal: Terminal
(Terraform) hmasayuk@:AWSCiscoASAvTerraform$ ping 34.194.120.227
PING 34.194.120.227 (34.194.120.227) 56(84) bytes of data.
64 bytes from 34.194.120.227: icmp_seq=249 ttl=232 time=186 ms
64 bytes from 34.194.120.227: icmp_seq=250 ttl=232 time=183 ms
64 bytes from 34.194.120.227: icmp_seq=251 ttl=232 time=188 ms
64 bytes from 34.194.120.227: icmp_seq=252 ttl=232 time=189 ms
64 bytes from 34.194.120.227: icmp_seq=253 ttl=232 time=187 ms
```
ｷﾀ━(ﾟ∀ﾟ)━!

AWS側で勝手に作ってくれてますね。


ASAvへのSSHも問題なさそう。
```Terminal: Terminal
(Terraform) hmasayuk@:AWSCiscoASAvTerraform$ ssh -i ~/.ssh/cisco_asav_keypair.pem admin@34.194.120.227
User admin logged in to AwsCiscoASAv
Logins over the last 1 days: 2.  Last login: 09:08:39 UTC Dec 8 2022 from 64.104.44.104
Failed logins since the last login: 0.
Type help or '?' for a list of available commands.
AwsCiscoASAv>
```

# ③`terraform destroy` で課金されるAWS上のリソースが消える事を確認

構築後のリソース↓
![rapture_20221209181828.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730261/90049e6c-5d66-4a3a-2841-a3b13ad43b49.jpeg)

今回作成したリソースすべてが削除されてるのか確認しましょう。
`terraform destroy`を実行。

```Terminal: Terminal
(Terraform) hmasayuk@:AWSCiscoASAvTerraform$ terraform destroy
・
・（省略）
・
Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes👈自分で入力

・
・（省略）
・

Destroy complete! Resources: 12 destroyed.
```
Destroy語のリソース↓
（インスタンス:1とありますが、ステータスは「終了済み」でキチンと削除されてました）
![rapture_20221209182715.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730261/e5b91201-0178-8abb-bc3f-3f8ba337640e.jpeg)

楽すぎる…

# まとめ
AWSのリソースって削除する順番があったり、削除し忘れてて課金されてる事があって怖いですよね。
実際に請求書見てから気づくとか割と皆さんあるんじゃないでしょうか。

この記事が誰かの為になりますように。。