使用Terraform(Fargate)部署Nginx
首先
这是一个关于学习Terraform的备忘录。
请点击这里查看目录。
terraform配置
文件结构
.
├── Dockerfile
├── nginx
│ └── index.html
└── terraform
├── main.tf
├── modules
│ ├── bash
│ │ └── null_resource.tf
│ ├── ecr
│ │ └── ecr.tf
│ ├── ecs
│ │ ├── ecs.tf
│ │ ├── ecs_service.tf
│ │ └── ecs_task_definition.tf
│ ├── iam
│ │ ├── aws_iam_policy.tf
│ │ ├── aws_iam_policy_attachment.tf
│ │ ├── aws_iam_role.tf
│ │ └── outputs.tf
│ └── network
│ ├── aws_vpc.tf
│ ├── igw.tf
│ ├── outputs.tf
│ ├── route_table.tf
│ ├── security_group.tf
│ ├── security_group_rule.tf
│ └── subnet.tf
├── terraform.tfstate
├── terraform.tfstate.backup
└── variables.tf
网络配置
我们采用从本地推送到ECR的dockerimage,在fargate上拉取并部署的方法。
Dockerfile和HTML文件
我设定了一个简单的构成,以在画面上输出”Hello world!!!!!!!!!!!”。
FROM nginx:latest
COPY ./nginx /usr/share/nginx/html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div style=" line-height: 200px;height: 200px;text-align: center;">
<p style=" line-height: 1.5;display: inline-block;vertical-align: middle;">
Hello world!!!!!!!!!!!
</p>
</div>
</body>
</html>
主要的.tf文件
每个output.tf是为了通过main.tf将数据传输给其他模块而存在的,不过这里省略了解释。
provider "aws" {
region = var.region
}
# IAM
module "iam" {
source = "./modules/iam"
}
# ECR
module "ecr" {
source = "./modules/ecr"
image_name = var.image_name
}
# Null Resource
module "after_ecr" {
source = "./modules/bash"
region = var.region
image_name = var.image_name
}
# network
module "network" {
source = "./modules/network"
app_name = var.app_name
}
# ECS
module "ecs" {
source = "./modules/ecs"
app_name = var.app_name
vpc_id = module.network.security-group-id
subnet_id = module.network.subnet-public-1a-id
aws_iam_role = module.iam.aws_iam_role
}
我组成
resource "aws_iam_role" "newworld_role" {
name = "newworld_role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid: ""
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
},
]
})
}
“ecr:*”的描述使得Fargate能够进行拉取。
如果没有这个描述,将会出现400错误。
resource "aws_iam_policy" "newworld_policy" {
name = "test_policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ecr:*",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
resource "aws_iam_policy_attachment" "attach" {
name = "iam-attach"
roles = ["${aws_iam_role.newworld_role.name}"]
policy_arn = "${aws_iam_policy.newworld_policy.arn}"
}
ECR建立
variable "image_name" {}
resource "aws_ecr_repository" "repository" {
name = var.image_name
image_tag_mutability = "IMMUTABLE"
force_delete = true
image_scanning_configuration {
scan_on_push = true
}
}
空缺资源的构成
完成ECR构建后,将docker镜像自动推送至ECR。我们正在使用terraform执行以下描述的操作。
aws ecr get-login-password –region ap-northeast-1 | docker login –username AWS –password-stdin AWS的账号ID.dkr.ecr.ap-northeast-1.amazonaws.com
docker tag hello-world-from-ecs:latest AWS的账号ID.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world-from-ecs:latest
docker push AWS的账号ID.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world-from-ecs:latest
aws_caller_identity调用了AWS的账户ID。
data "aws_caller_identity" "self" { }
variable "image_name" {}
variable "region" {}
resource "null_resource" "default" {
provisioner "local-exec" {
command = "aws ecr get-login-password --region ${var.region} | docker login --username AWS --password-stdin ${data.aws_caller_identity.self.account_id}.dkr.ecr.ap-northeast-1.amazonaws.com"
}
provisioner "local-exec" {
command = "docker tag ${var.image_name}:latest ${data.aws_caller_identity.self.account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/${var.image_name}:latest"
}
provisioner "local-exec" {
command = "docker push ${data.aws_caller_identity.self.account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/${var.image_name}:latest"
}
}
网络构建
因为太长,我会简略地说。
云计算系统架构
variable "app_name" {}
resource "aws_ecs_cluster" "newworld-cluster" {
name = "${var.app_name}-cluster"
}
resource "aws_ecs_cluster_capacity_providers" "newworld_capacity_providers" {
cluster_name = "${var.app_name}-cluster"
capacity_providers = ["FARGATE"]
default_capacity_provider_strategy {
base = 1
weight = 100
capacity_provider = "FARGATE"
}
}
variable "vpc_id" {}
variable "subnet_id" {}
resource "aws_ecs_service" "newworld-service" {
name = "nginx-service"
cluster = aws_ecs_cluster.newworld-cluster.id
task_definition = aws_ecs_task_definition.newworld-definition.arn
desired_count = 1
network_configuration {
security_groups = [var.vpc_id]
subnets = ["${var.subnet_id}"]
assign_public_ip = true
}
lifecycle {
ignore_changes = [desired_count]
}
}
variable "vpc_id" {}
variable "subnet_id" {}
resource "aws_ecs_service" "newworld-service" {
name = "nginx-service"
cluster = aws_ecs_cluster.newworld-cluster.id
task_definition = aws_ecs_task_definition.newworld-definition.arn
desired_count = 1
network_configuration {
security_groups = [var.vpc_id]
subnets = ["${var.subnet_id}"]
assign_public_ip = true
}
lifecycle {
ignore_changes = [desired_count]
}
}