Skip to content

Commit

Permalink
Merge pull request #47 from showwin/terraform
Browse files Browse the repository at this point in the history
コンテスト用Terraformの改善
  • Loading branch information
showwin authored Oct 19, 2024
2 parents b758d90 + 83ad599 commit 133677d
Show file tree
Hide file tree
Showing 24 changed files with 340 additions and 152 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ ISUCONは3人チームで取り組むことを基準に課題が作られてい

## 問題詳細
* マニュアル: [ISHOCON1マニュアル](https://github.com/showwin/ISHOCON1/blob/master/doc/manual.md)
* AMI: `ami-06cda439fc5c0da1b`
* インスタンスタイプ: `c5.xlarge`
* AMI: `ami-0df9d6920cdfce51b`
* インスタンスタイプ: `c7i.xlarge`
* 参考実装言語: Ruby, Go, Python
* メンテナンス外: Node.js(TypeScript), Crystal(by [@Goryudyuma](https://github.com/Goryudyuma)), Scala(by [@Goryudyuma](https://github.com/Goryudyuma))
* 推奨実施時間: 1人で8時間
Expand Down
2 changes: 1 addition & 1 deletion admin/ami/scripts/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ echo 'ishocon ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/ishocon
sudo mkdir -m 775 /home/ishocon/webapp
sudo mkdir -m 777 /home/ishocon/data
sudo chown -R ishocon:ishocon /home/ishocon
sudo chmod 777 /home/ishocon
sudo chmod 750 /home/ishocon
1 change: 1 addition & 0 deletions contest/terraform/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.terraform
terraform.tfstate*
2 changes: 1 addition & 1 deletion contest/terraform/.terraform-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.15.0
1.9.7
1 change: 1 addition & 0 deletions contest/terraform/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform 1.9.7
37 changes: 19 additions & 18 deletions contest/terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## 概要

terraformでISHOCON1の環境が構築できます。
社内ISUCON等のコンテストの開催準備として使うと便利です。
開催者(以下admins)と参加者(以下players)のロールに分けて、サーバーを複数台準備できます。
terraformでISHOCON1の環境が構築できます。
社内ISUCON等のコンテストの開催準備として使うと便利です。
開催者(以下admins)と参加者(以下teams)のロールに分けて、サーバーを複数台準備できます。

## 必要なもの

Expand All @@ -16,41 +16,42 @@ terraformでISHOCON1の環境が構築できます。
### 1. AWSアカウントの登録

```shell
$ aws configure --profile ishocon1
$ aws configure
```

### 2. adminsとplayersに、GitHubにて秘密鍵を登録してもらう

playerはコンテストで使用するインスタンスにログインするために、GitHubに登録されている秘密鍵を使用する。
playerはコンテストで使用するインスタンスにログインするために、GitHubに登録されている秘密鍵を使用する。
GitHubにて秘密鍵を登録後、各自のPCで以下のコマンドを実行し自身のGitHubのアカウントIDが表示されることを確認する。

```shell
$ ssh -T [email protected]
```

### 3. stateファイルを入れるS3バケットを作成
tfstateの管理をローカルで行う場合には、作成不要。
### 3. main/main.tf を編集

### 4. FIXMEを直す

- [ ] terraform.tfの中のbucketに、先ほど作成したS3のbucket nameを入れる
- ローカルでtfstateを管理し、S3を使わない場合にはterraform.tfを削除する
- [ ] users.tfにadmins, playersのGitHubアカウントIDを入れる
- [ ] (必須) `admins``teams`(チーム名と参加者名)に各々のGitHubアカウントIDを記述
- 詳細は[ドキュメント](https://docs.github.com/ja/github/authenticating-to-github/connecting-to-github-with-ssh)を参照のこと
- adminsは全インスタンスに入ることができる

### 5. terraform apply してリソースの作成
- [ ] (任意) module/variables.tf を参考に変更したいパラメーターを main/main.tf に定義

### 4. terraform apply してリソースの作成

```shell
$ cd main
$ terraform apply
```

outputに競技で使用するインスタンスのIPアドレスが入っているので、playerの人に渡す。
outputに競技で使用するインスタンスのIPアドレスが出力されるので、参加者に共有する。

```
$ ssh ishocon@<instance_ip>
```

でインスタンスにSSHできる。

## 注意点

- spot instanceで立てるようにしてコストの削減を図っています
- コンテスト中に絶対に落ちて欲しくないなどの理由により spot instanceを使わない場合、main.tfの `aws_spot_instance_request``aws_instance` に変えてください
- デフォルトでは、ISHOCON1の推奨インスタンスタイプである `c5.xlarge` でインスタンスが起動します
- デフォルトでは、ISHOCON1の推奨インスタンスタイプである `c7i.xlarge` でインスタンスが起動します
- このterraformを使用することで発生した問題に対して責任は一切取りません
- コードをよく読んだ上で、自己責任でご使用ください
73 changes: 0 additions & 73 deletions contest/terraform/main.tf

This file was deleted.

25 changes: 25 additions & 0 deletions contest/terraform/main/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions contest/terraform/main/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// FIXME
locals {
admins = [
"admin_github_id",
]

teams = {
"team1" = [
"user1_github_id",
"user2",
"user3",
],
"team2" = [
"user4",
"user5",
],
}
}

module "main" {
source = "../module"

admins = local.admins
teams = local.teams

use_spot_instance = false
}
3 changes: 3 additions & 0 deletions contest/terraform/main/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "ip_addr" {
value = module.main.ip_addr
}
21 changes: 21 additions & 0 deletions contest/terraform/main/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
terraform {
required_version = "1.9.7"

required_providers {
aws = {
source = "hashicorp/aws"
version = "5.69.0"
}
}
}

provider "aws" {
region = "ap-northeast-1"

default_tags {
tags = {
Service = "ISHOCON1"
ManagedBy = "Terraform"
}
}
}
51 changes: 51 additions & 0 deletions contest/terraform/module/ec2.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
resource "aws_instance" "main" {
for_each = var.use_spot_instance ? {} : { for idx, team in local.team_list : team => team }

ami = var.ami_id
instance_type = var.instance_type

subnet_id = module.vpc.public_subnets[0]
associate_public_ip_address = true

vpc_security_group_ids = [
aws_security_group.main.id
]

user_data = <<-EOF
#!/bin/bash
mkdir /home/ishocon/.ssh
${join("\n", [for player_in_team in var.teams[each.value] : "curl https://github.com/${player_in_team}.keys >> /home/ishocon/.ssh/authorized_keys"])}
${join("\n", [for admin in var.admins : "curl https://github.com/${admin}.keys >> /home/ishocon/.ssh/authorized_keys"])}
chown -R ishocon:ishocon /home/ishocon/.ssh
useradd -u 1001 -g 1001 -o -N -d /home/ishocon -s /bin/bash ${each.value}
EOF

root_block_device {
volume_size = 8
}
}

resource "aws_ec2_tag" "instance_name" {
for_each = aws_instance.main

resource_id = each.value.id
key = "Name"
value = "ISHOCON1 - ${each.key}"
}

resource "aws_ec2_tag" "instance_team_name" {
for_each = aws_instance.main

resource_id = each.value.id
key = "team_name"
value = each.key
}

resource "aws_ec2_tag" "instance_players" {
for_each = aws_instance.main

resource_id = each.value.id
key = "players"
value = join(",", var.teams[each.key])
}
53 changes: 53 additions & 0 deletions contest/terraform/module/ec2_spot.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
resource "aws_spot_instance_request" "main" {
for_each = var.use_spot_instance ? { for idx, team in local.team_list : team => team } : {}

ami = var.ami_id
instance_type = var.instance_type

subnet_id = module.vpc.public_subnets[0]
associate_public_ip_address = true

vpc_security_group_ids = [
aws_security_group.main.id
]

user_data = <<-EOF
#!/bin/bash
mkdir /home/ishocon/.ssh
${join("\n", [for player_in_team in var.teams[each.value] : "curl https://github.com/${player_in_team}.keys >> /home/ishocon/.ssh/authorized_keys"])}
${join("\n", [for admin in var.admins : "curl https://github.com/${admin}.keys >> /home/ishocon/.ssh/authorized_keys"])}
chown -R ishocon:ishocon /home/ishocon/.ssh
useradd -u 1001 -g 1001 -o -N -d /home/ishocon -s /bin/bash ${each.value}
EOF

root_block_device {
volume_size = 8
}

wait_for_fulfillment = true
}

resource "aws_ec2_tag" "spot_instance_name" {
for_each = aws_spot_instance_request.main

resource_id = each.value.spot_instance_id
key = "Name"
value = "ISHOCON1 - ${each.key}"
}

resource "aws_ec2_tag" "spot_instance_team_name" {
for_each = aws_spot_instance_request.main

resource_id = each.value.spot_instance_id
key = "team_name"
value = each.key
}

resource "aws_ec2_tag" "spot_instance_players" {
for_each = aws_spot_instance_request.main

resource_id = each.value.spot_instance_id
key = "players"
value = join(",", var.teams[each.key])
}
3 changes: 3 additions & 0 deletions contest/terraform/module/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
locals {
team_list = keys(var.teams)
}
6 changes: 6 additions & 0 deletions contest/terraform/module/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
output "ip_addr" {
value = {
for team in local.team_list :
team => try(aws_instance.main[team]["public_ip"] , aws_spot_instance_request.main[team]["public_ip"])
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
terraform {
required_version = "1.9.7"

required_providers {
aws = {
source = "hashicorp/aws"
version = "3.37.0"
version = "~> 5.69"
}
}
}

provider "aws" {
profile = "ishocon1"
region = "ap-northeast-1"
}
Loading

0 comments on commit 133677d

Please sign in to comment.