circleciでterraformを扱う


## 参考
https://circleci.com/developer/orbs/orb/circleci/terraform?utm_medium=SEM&utm_source=gnb&utm_campaign=SEM-gb-DSA-Eng-japac&utm_content=&utm_term=dynamicSearch-&gclid=CjwKCAjw87SHBhBiEiwAukSeUQVbyc2ZZHOMAcBGPFyoB1MyjBXAlPXpN8ns1B8FSCIiahIRMYcasxoCPu0QAvD_BwE

## ディレクトリ構成
```
 yuta   add-subnet  ~  aws-terraform  tree -a -L 2
.
├── .circleci
│   └── config.yml
├── .git
│   ├── COMMIT_EDITMSG
│   ├── FETCH_HEAD
│   ├── HEAD
│   ├── ORIG_HEAD
│   ├── branches
│   ├── config
│   ├── description
│   ├── hooks
│   ├── index
│   ├── info
│   ├── logs
│   ├── objects
│   ├── packed-refs
│   └── refs
├── .gitignore
├── .terraform
│   └── providers
├── .terraform.lock.hcl
├── README.md
└── main.tf

```

- terraformはVPCを作るだけのもの
- s3にremote stateをセットできるようにしておく

```main.tf
provider "aws" {
  region  = "ap-northeast-1"
  profile = "yuta"
}

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 3.36.0"
    }
  }
  backend "s3" {
    bucket  = "vamdemic-circleci"
    region  = "ap-northeast-1"
    profile = "yuta"
    key     = "terraform.tfstate"
    encrypt = true
  }
}

resource "aws_vpc" "main" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"

  tags = {
    Name = "circleci-test-vpc"
  }
}

resource "aws_subnet" "main" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"

  tags = {
    Name = "Main"
  }
}
```

## 準備すること
### CircleCI用のコンフィグを作る

```.circleci/config.yml
version: 2.1
orbs:
  terraform: "circleci/terraform@2.1.0"
workflows:
  deploy_infrastructure:
    jobs:
      - terraform/fmt:
          checkout: true
          context: terraform
      - terraform/validate:
          checkout: true
          context: terraform
          requires:
            - terraform/fmt
      - terraform/plan:
          checkout: true
          context: terraform
          persist-workspace: true
          requires:
            - terraform/validate
      - terraform/apply:
          attach-workspace: true
          context: terraform
          filters:
            branches:
              only: main
          requires:
            - terraform/plan
```

### AWSCredencialをCircleCIの環境変数にセットする
- CircleCI上で作成したプロジェクトでProject Settingsを選び入力する
- それぞれ次の通りそのまま入力する
    - AWS_ACCESS_KEY_ID
    - AWS_SECRET_ACCESS_KEY
- 今回の場合、指定した資格情報がterraform plan,applyのときに利用される

### Contextをセットしておく
- Organaization SettingsでContext→terraformを作る
- このContextはyamlファイルから指定されていて、これがないと、NotFoundみたいな感じのメッセージが出て失敗する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/3a965aa2-fa11-5e6f-46cc-32f21a3e4348.png)

## 試す

### main.tfに足す
```
resource "aws_subnet" "private" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.2.0/24"

  tags = {
    Name = "private"
  }
}
```

### remoteブランチへpushする
```
git checkout -b add-subnet 
git commit -m "init"
git push 
```

### 実行結果
ちゃんと動いている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/5b3a67fd-05fb-19ea-c3db-e5d8fbe6f822.png)

### mainブランチへマージする
この際に、fmt,validate,planのCIが通過していることがわかる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/4f21e636-e1a5-10bc-7710-bd3e365d1749.png)

### CircleCIが再度動作する
- といのは、以下の記述があるから
    - ブランチがmainのときのみterraform applyが実行されるということ

```
      - terraform/apply:
          attach-workspace: true
          context: terraform
          filters:
            branches:
              only: main
```

### 完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/ce4b6e32-8ad6-78aa-5272-1b805bf543db.png)

サブネットも出来上がっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/336faf44-bcf9-937d-fae9-016634f34e92.png)