0
1

GitHubActions + TerraformでNWを作成してみた

Last updated at Posted at 2024-07-22

背景・目的

以前、下記の記事でTerraform+GitHubActionsを使用してS3を構築してみました。
今回は、AWSのNWを同様に作成します。

実践

今回、構築したい環境は下記のとおりです。

image.png

ディレクトリ構造は、下記のとおりです。terraform-modules配下に、vpcモジュールを用意しています。

terraform-modules/
└── s3/
    ├── main.tf
    ├── variables.tf
    ├── outputs.tf
└── vpc/
    ├── main.tf
    ├── variables.tf
    ├── outputs.tf
├── main.tf
├── variables.tf
├── terraform.tfvars
├── backend.tf

IAMポリシー

  1. AWSにサインインし、IAMに移動します
  2. 対象のIAMロールをクリックします
  3. VPCが作成できるように、IAMポリシーを追加します
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:DeleteSubnet",
                "ec2:DeleteTags",
                "ec2:CreateVpc",
                "ec2:AttachInternetGateway",
                "ec2:DescribeVpcAttribute",
                "ec2:ReplaceRoute",
                "ec2:DeleteRouteTable",
                "ec2:ModifySubnetAttribute",
                "ec2:AssociateRouteTable",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribeAvailabilityZones",
                "ec2:CreateRoute",
                "ec2:CreateInternetGateway",
                "ec2:RevokeSecurityGroupEgress",
                "ec2:CreateSecurityGroup",
                "ec2:DescribeAccountAttributes",
                "ec2:ModifyVpcAttribute",
                "ec2:DeleteInternetGateway",
                "ec2:DescribeRouteTables",
                "ec2:AuthorizeSecurityGroupEgress",
                "ec2:CreateTags",
                "ec2:DescribeVpcPeeringConnections",
                "ec2:DeleteRoute",
                "ec2:CreateRouteTable",
                "ec2:DetachInternetGateway",
                "ec2:DisassociateRouteTable",
                "ec2:DescribeSecurityGroups",
                "ec2:RevokeSecurityGroupIngress",
                "ec2:DescribeVpcs",
                "ec2:DeleteSecurityGroup",
                "ec2:DeleteVpc",
                "ec2:CreateSubnet",
                "ec2:DescribeSubnets"
            ],
            "Resource": "*"
        }
    

VPCモジュール

  1. terraform-modules配下に、vpcフォルダを作成します

main.tf

  1. main.tfを作成します
    resource "aws_vpc" "this" {
      cidr_block = var.vpc_cidr
      tags       = var.tags
    }
    
    resource "aws_internet_gateway" "this" {
      vpc_id = aws_vpc.this.id
      tags   = var.tags
    }
    
    resource "aws_subnet" "public" {
      count                   = length(var.azs)
      vpc_id                  = aws_vpc.this.id
      cidr_block              = cidrsubnet(var.vpc_cidr, 3, count.index)
      availability_zone       = var.azs[count.index]
      map_public_ip_on_launch = true
      tags                    = merge(var.tags, { "Name" = format("%s-public-subnet-%d", var.project_name, count.index + 1) })
    }
    
    resource "aws_subnet" "private" {
      count             = length(var.azs)
      vpc_id            = aws_vpc.this.id
      cidr_block        = cidrsubnet(var.vpc_cidr, 3, count.index + length(var.azs))
      availability_zone = var.azs[count.index]
      tags              = merge(var.tags, { "Name" = format("%s-private-subnet-%d", var.project_name, count.index + 1) })
    }
    
    resource "aws_subnet" "db" {
      count             = length(var.azs)
      vpc_id            = aws_vpc.this.id
      cidr_block        = cidrsubnet(var.vpc_cidr, 3, count.index + 2 * length(var.azs))
      availability_zone = var.azs[count.index]
      tags              = merge(var.tags, { "Name" = format("%s-db-subnet-%d", var.project_name, count.index + 1) })
    }
    
    resource "aws_route_table" "public" {
      vpc_id = aws_vpc.this.id
      tags   = merge(var.tags, { "Name" = format("%s-public-rt", var.project_name) })
    }
    
    resource "aws_route" "igw" {
      route_table_id         = aws_route_table.public.id
      destination_cidr_block = "0.0.0.0/0"
      gateway_id             = aws_internet_gateway.this.id
    }
    
    resource "aws_route_table_association" "public" {
      count          = length(var.azs)
      subnet_id      = aws_subnet.public[count.index].id
      route_table_id = aws_route_table.public.id
    }
    
    

variables.tf

  1. variables.tfを作成します
    variable "vpc_cidr" {
      description = "The CIDR block for the VPC"
      type        = string
    }
    
    variable "azs" {
      description = "List of availability zones"
      type        = list(string)
    }
    
    variable "tags" {
      description = "A map of tags to assign to the resources"
      type        = map(string)
      default     = {}
    }
    
    variable "project_name" {
      description = "The name of the project"
      type        = string
    }
    

outputs.tf

  1. outputs.tf を作成します
    output "vpc_id" {
      description = "The ID of the VPC"
      value       = aws_vpc.this.id
    }
    
    output "public_subnets" {
      description = "The IDs of the public subnets"
      value       = aws_subnet.public[*].id
    }
    
    output "private_subnets" {
      description = "The IDs of the private subnets"
      value       = aws_subnet.private[*].id
    }
    
    output "db_subnets" {
      description = "The IDs of the DB subnets"
      value       = aws_subnet.db[*].id
    }
    

ルートモジュールの作成

  1. ルートモジュールの配下のファイルを修正します

main.tfの修正

  1. main.tfを作成します
    • vpc モジュールを呼び出す箇所を追加
    • outputを追加
    data "aws_caller_identity" "this" {}
    
    module "s3" {
      source      = "./terraform-modules/s3"
      bucket_name = format("%s-%s", var.bucket_name, "${data.aws_caller_identity.this.account_id}")
      tags        = var.s3_tags
    }
    
    module "vpc" {
      source       = "./terraform-modules/vpc"
      vpc_cidr     = var.vpc_cidr
      azs          = var.azs
      tags         = var.vpc_tags
      project_name = var.project_name
    }
    
    output "bucket_id" {
      value = module.s3.bucket_id
    }
    
    output "bucket_arn" {
      value = module.s3.bucket_arn
    }
    
    output "bucket_region" {
      value = module.s3.bucket_region
    }
    
    output "vpc_id" {
      value = module.vpc.vpc_id
    }
    
    output "public_subnets" {
      value = module.vpc.public_subnets
    }
    
    output "private_subnets" {
      value = module.vpc.private_subnets
    }
    
    output "db_subnets" {
      value = module.vpc.db_subnets
    }
    
    

variables.tfの修正

  1. variables.tf を修正します
    variable "bucket_name" {
      description = "The name of the S3 bucket"
      type        = string
    }
    
    variable "s3_tags" {
      description = "A map of tags to assign to the resource"
      type        = map(string)
      default     = {}
    }
    
    variable "vpc_cidr" {
      description = "The CIDR block for the VPC"
      type        = string
    }
    
    variable "azs" {
      description = "List of availability zones"
      type        = list(string)
    }
    
    variable "vpc_tags" {
      description = "A map of tags to assign to the resources"
      type        = map(string)
      default     = {}
    }
    
    variable "project_name" {
      description = "The name of the project"
      type        = string
    }
    

terraform.tfvarsの修正

  1. terraform.tfvars を修正します
    • VPC関連の変数を定義します
    bucket_name = "terraform-demo"
    s3_tags = {
      "Environment" = "prod"
      "Project"     = "TerraformExample"
    }
    
    vpc_cidr = "10.0.0.0/16"
    azs      = ["ap-northeast-1a", "ap-northeast-1c"]
    vpc_tags = {
      "Environment" = "prod"
      "Project"     = "TerraformExample"
    }
    project_name = "my-vpc-project"
    

確認

  1. Commit & Pushします。成功しました
    image.png
    image.png
  2. VPCもできていました
    image.png

考察

今回、VPC等をTerraformで作成しました。
次回は、コンテナアプリケーションを動かすためのインフラを構築したいと思います。

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1