terraform: Begin AWS configuration

The `terraform` directory contains the resource descriptions for all AWS
services that need to be configured in order for the dynamic K8s
provisioner to work.  Specifically, it defines the EventBridge rule and
SNS topic/subscriptions that instruct AWS to send EC2 instance state
change notifications to the *dynk8s-provisioner*'s HTTP interface.
master
Dustin 2022-09-27 12:39:01 -05:00
parent c721571043
commit 8e1165eb95
10 changed files with 477 additions and 0 deletions

2
terraform/.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
.terraform.lock.hcl -diff
terraform.tfstate -diff

2
terraform/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.terraform/
terraform.tfstate.backup

View File

@ -0,0 +1,22 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/aws" {
version = "4.30.0"
constraints = "~> 4.16"
hashes = [
"h1:BFfhRf8my/aa0+YOSJv0xfjLQkToF475TJTMhTZfYec=",
"zh:08213f3ba960621448754211f148730edb59194919ee476b0231b769a5355028",
"zh:29c90d6f8bdae0e1469417ade28fa79c74c2af49593c1e2f24f07bacbca9e2c9",
"zh:5c6e9fab64ad68de6cd4ec6cbb20b0f75ba1e51a8efaeda3fe65419f096a06cb",
"zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
"zh:9bf42718580e8c5097227df34e1bfa0a10a23eac9f527d97c2819c163087b402",
"zh:9f87e42e0f3d145fb0ad4aaff7ddded5720a64f9303956b33bd274c6dd05c05b",
"zh:bf0519ed9615bc408b72a0aebe1cc075d4c2042325590ba13dd264cd264907ea",
"zh:c3ac9e1cbd0935614f5a3c9cdb4cf9c6a1045937fe38e61da7c5c0fb7a069870",
"zh:d0c184476ada38c50acc068214ed1252b4fcf80b6be900fc1aed32cbb49f8ff6",
"zh:d4987dc7b7a69ea58f2b3ff0ea4ffc1b61a97881dbb8583c9fcf9444b753a6c2",
"zh:e8037376c81aeb98d8286dc19fba7f8eb053444d4b9484ea6a922382cffc1a85",
"zh:ecdabb44b48addc8483bca7bd683614a347367ae950ca8b6a6880679f5c12abd",
]
}

20
terraform/README.md Normal file
View File

@ -0,0 +1,20 @@
# Configuring AWS Using Terraform
## Prerequisites
The IAM user or role that runs Terraform must have the appropriate permissions.
The `iam-policy.json` file defines a policy that will allow the Terraform to
manage all of the necessary resources. Before running Terraform, create an IAM
policy and assign it to a user, group, or role. Be sure to replace the AWS
account ID in the various target resource names.
To use an IAM role, set the `iam_role` Terraform variable when executing
`terraform plan`/`terraform apply`.
## Create Resources
Terraform will create all resources automatically:
```sh
terraform apply
```

16
terraform/eventbridge.tf Normal file
View File

@ -0,0 +1,16 @@
resource "aws_cloudwatch_event_rule" "instance_state" {
name = "instance-state-events"
event_pattern = <<EOF
{
"source": ["aws.ec2"],
"detail-type": ["EC2 Instance State-change Notification"]
}
EOF
}
resource "aws_cloudwatch_event_target" "sns" {
rule = aws_cloudwatch_event_rule.instance_state.name
target_id = "SendToSNS"
arn = aws_sns_topic.ec2_events.arn
}

49
terraform/iam-policy.json Normal file
View File

@ -0,0 +1,49 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"sns:ListTagsForResource",
"events:DescribeRule",
"sns:GetTopicAttributes",
"events:EnableRule",
"sns:DeleteTopic",
"events:PutRule",
"sns:CreateTopic",
"sns:SetTopicAttributes",
"events:DeleteRule",
"events:PutTargets",
"events:ListTagsForResource",
"sns:Subscribe",
"events:RemoveTargets",
"events:ListTargetsByRule",
"events:DisableRule"
],
"Resource": [
"arn:aws:sns:*:566967686773:*",
"arn:aws:events:*:566967686773:rule/*"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"events:DescribeEventBus",
"events:CreateEventBus",
"events:DeleteEventBus"
],
"Resource": "arn:aws:events:*:566967686773:event-bus/*"
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": [
"sns:Unsubscribe",
"sns:GetSubscriptionAttributes"
],
"Resource": "*"
}
]
}

19
terraform/main.tf Normal file
View File

@ -0,0 +1,19 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = var.ec2_region
assume_role {
role_arn = var.iam_role
}
}
data "aws_caller_identity" "current" {}

61
terraform/sns.tf Normal file
View File

@ -0,0 +1,61 @@
data "aws_iam_policy_document" "ec2_events_access_policy" {
statement {
sid = "__default_statement_ID"
effect = "Allow"
principals {
type = "AWS"
identifiers = ["*"]
}
actions = [
"SNS:Subscribe",
"SNS:SetTopicAttributes",
"SNS:RemovePermission",
"SNS:Receive",
"SNS:Publish",
"SNS:ListSubscriptionsByTopic",
"SNS:GetTopicAttributes",
"SNS:DeleteTopic",
"SNS:AddPermission",
]
resources = [
aws_sns_topic.ec2_events.arn,
]
condition {
test = "StringEquals"
variable = "AWS:SourceOwner"
values = [
data.aws_caller_identity.current.account_id
]
}
}
statement {
sid = "AllowEventBridgePublish"
effect = "Allow"
principals {
type = "Service"
identifiers = ["events.amazonaws.com"]
}
actions = ["sns:Publish"]
resources = [aws_sns_topic.ec2_events.arn]
}
}
resource "aws_sns_topic" "ec2_events" {
name = "ec2-events"
}
resource "aws_sns_topic_policy" "ec2_events_policy" {
arn = aws_sns_topic.ec2_events.arn
policy = data.aws_iam_policy_document.ec2_events_access_policy.json
}
resource "aws_sns_topic_subscription" "dynk8s_provisoner" {
topic_arn = aws_sns_topic.ec2_events.arn
protocol = "https"
endpoint = "https://dynk8s-provisioner.pyrocufflink.net/sns/notify"
}

275
terraform/terraform.tfstate Normal file
View File

@ -0,0 +1,275 @@
{
"version": 4,
"terraform_version": "1.2.9",
"serial": 49,
"lineage": "a100be74-c98e-0769-2d6a-bf6a2c5f3ebf",
"outputs": {},
"resources": [
{
"mode": "data",
"type": "aws_caller_identity",
"name": "current",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"account_id": "566967686773",
"arn": "arn:aws:sts::566967686773:assumed-role/dynk8s-terraform/aws-go-sdk-1664301518318294107",
"id": "566967686773",
"user_id": "AROAYIAPIKZ25DFDOYZHT:aws-go-sdk-1664301518318294107"
},
"sensitive_attributes": []
}
]
},
{
"mode": "data",
"type": "aws_iam_policy_document",
"name": "ec2_events_access_policy",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "2883441170",
"json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"__default_statement_ID\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"SNS:Subscribe\",\n \"SNS:SetTopicAttributes\",\n \"SNS:RemovePermission\",\n \"SNS:Receive\",\n \"SNS:Publish\",\n \"SNS:ListSubscriptionsByTopic\",\n \"SNS:GetTopicAttributes\",\n \"SNS:DeleteTopic\",\n \"SNS:AddPermission\"\n ],\n \"Resource\": \"arn:aws:sns:us-east-2:566967686773:ec2-events\",\n \"Principal\": {\n \"AWS\": \"*\"\n },\n \"Condition\": {\n \"StringEquals\": {\n \"AWS:SourceOwner\": \"566967686773\"\n }\n }\n },\n {\n \"Sid\": \"AllowEventBridgePublish\",\n \"Effect\": \"Allow\",\n \"Action\": \"sns:Publish\",\n \"Resource\": \"arn:aws:sns:us-east-2:566967686773:ec2-events\",\n \"Principal\": {\n \"Service\": \"events.amazonaws.com\"\n }\n }\n ]\n}",
"override_json": null,
"override_policy_documents": null,
"policy_id": null,
"source_json": null,
"source_policy_documents": null,
"statement": [
{
"actions": [
"SNS:AddPermission",
"SNS:DeleteTopic",
"SNS:GetTopicAttributes",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive",
"SNS:RemovePermission",
"SNS:SetTopicAttributes",
"SNS:Subscribe"
],
"condition": [
{
"test": "StringEquals",
"values": [
"566967686773"
],
"variable": "AWS:SourceOwner"
}
],
"effect": "Allow",
"not_actions": [],
"not_principals": [],
"not_resources": [],
"principals": [
{
"identifiers": [
"*"
],
"type": "AWS"
}
],
"resources": [
"arn:aws:sns:us-east-2:566967686773:ec2-events"
],
"sid": "__default_statement_ID"
},
{
"actions": [
"sns:Publish"
],
"condition": [],
"effect": "Allow",
"not_actions": [],
"not_principals": [],
"not_resources": [],
"principals": [
{
"identifiers": [
"events.amazonaws.com"
],
"type": "Service"
}
],
"resources": [
"arn:aws:sns:us-east-2:566967686773:ec2-events"
],
"sid": "AllowEventBridgePublish"
}
],
"version": "2012-10-17"
},
"sensitive_attributes": []
}
]
},
{
"mode": "managed",
"type": "aws_cloudwatch_event_rule",
"name": "instance_state",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"arn": "arn:aws:events:us-east-2:566967686773:rule/instance-state-events",
"description": "",
"event_bus_name": "default",
"event_pattern": "{\"detail-type\":[\"EC2 Instance State-change Notification\"],\"source\":[\"aws.ec2\"]}",
"id": "instance-state-events",
"is_enabled": true,
"name": "instance-state-events",
"name_prefix": "",
"role_arn": "",
"schedule_expression": "",
"tags": {},
"tags_all": {}
},
"sensitive_attributes": [],
"private": "bnVsbA=="
}
]
},
{
"mode": "managed",
"type": "aws_cloudwatch_event_target",
"name": "sns",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"arn": "arn:aws:sns:us-east-2:566967686773:ec2-events",
"batch_target": [],
"dead_letter_config": [],
"ecs_target": [],
"event_bus_name": "default",
"http_target": [],
"id": "instance-state-events-SendToSNS",
"input": "",
"input_path": "",
"input_transformer": [],
"kinesis_target": [],
"redshift_target": [],
"retry_policy": [],
"role_arn": "",
"rule": "instance-state-events",
"run_command_targets": [],
"sqs_target": [],
"target_id": "SendToSNS"
},
"sensitive_attributes": [],
"private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ==",
"dependencies": [
"aws_cloudwatch_event_rule.instance_state",
"aws_sns_topic.ec2_events"
]
}
]
},
{
"mode": "managed",
"type": "aws_sns_topic",
"name": "ec2_events",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"application_failure_feedback_role_arn": "",
"application_success_feedback_role_arn": "",
"application_success_feedback_sample_rate": 0,
"arn": "arn:aws:sns:us-east-2:566967686773:ec2-events",
"content_based_deduplication": false,
"delivery_policy": "",
"display_name": "",
"fifo_topic": false,
"firehose_failure_feedback_role_arn": "",
"firehose_success_feedback_role_arn": "",
"firehose_success_feedback_sample_rate": 0,
"http_failure_feedback_role_arn": "",
"http_success_feedback_role_arn": "",
"http_success_feedback_sample_rate": 0,
"id": "arn:aws:sns:us-east-2:566967686773:ec2-events",
"kms_master_key_id": "",
"lambda_failure_feedback_role_arn": "",
"lambda_success_feedback_role_arn": "",
"lambda_success_feedback_sample_rate": 0,
"name": "ec2-events",
"name_prefix": "",
"owner": "566967686773",
"policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"__default_statement_ID\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":[\"SNS:Subscribe\",\"SNS:SetTopicAttributes\",\"SNS:RemovePermission\",\"SNS:Receive\",\"SNS:Publish\",\"SNS:ListSubscriptionsByTopic\",\"SNS:GetTopicAttributes\",\"SNS:DeleteTopic\",\"SNS:AddPermission\"],\"Resource\":\"arn:aws:sns:us-east-2:566967686773:ec2-events\",\"Condition\":{\"StringEquals\":{\"AWS:SourceOwner\":\"566967686773\"}}},{\"Sid\":\"AllowEventBridgePublish\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"events.amazonaws.com\"},\"Action\":\"sns:Publish\",\"Resource\":\"arn:aws:sns:us-east-2:566967686773:ec2-events\"}]}",
"sqs_failure_feedback_role_arn": "",
"sqs_success_feedback_role_arn": "",
"sqs_success_feedback_sample_rate": 0,
"tags": {},
"tags_all": {}
},
"sensitive_attributes": [],
"private": "bnVsbA=="
}
]
},
{
"mode": "managed",
"type": "aws_sns_topic_policy",
"name": "ec2_events_policy",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"arn": "arn:aws:sns:us-east-2:566967686773:ec2-events",
"id": "arn:aws:sns:us-east-2:566967686773:ec2-events",
"owner": "566967686773",
"policy": "{\"Statement\":[{\"Action\":[\"SNS:Subscribe\",\"SNS:SetTopicAttributes\",\"SNS:RemovePermission\",\"SNS:Receive\",\"SNS:Publish\",\"SNS:ListSubscriptionsByTopic\",\"SNS:GetTopicAttributes\",\"SNS:DeleteTopic\",\"SNS:AddPermission\"],\"Condition\":{\"StringEquals\":{\"AWS:SourceOwner\":\"566967686773\"}},\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Resource\":\"arn:aws:sns:us-east-2:566967686773:ec2-events\",\"Sid\":\"__default_statement_ID\"},{\"Action\":\"sns:Publish\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"events.amazonaws.com\"},\"Resource\":\"arn:aws:sns:us-east-2:566967686773:ec2-events\",\"Sid\":\"AllowEventBridgePublish\"}],\"Version\":\"2012-10-17\"}"
},
"sensitive_attributes": [],
"private": "bnVsbA==",
"dependencies": [
"aws_sns_topic.ec2_events",
"data.aws_caller_identity.current",
"data.aws_iam_policy_document.ec2_events_access_policy"
]
}
]
},
{
"mode": "managed",
"type": "aws_sns_topic_subscription",
"name": "dynk8s_provisoner",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"arn": "arn:aws:sns:us-east-2:566967686773:ec2-events:3be7a77b-4b89-4925-bad3-dab7223d07f3",
"confirmation_timeout_in_minutes": 1,
"confirmation_was_authenticated": false,
"delivery_policy": "",
"endpoint": "https://dynk8s-provisioner.pyrocufflink.net/sns/notify",
"endpoint_auto_confirms": false,
"filter_policy": "",
"id": "arn:aws:sns:us-east-2:566967686773:ec2-events:3be7a77b-4b89-4925-bad3-dab7223d07f3",
"owner_id": "566967686773",
"pending_confirmation": false,
"protocol": "https",
"raw_message_delivery": false,
"redrive_policy": "",
"subscription_role_arn": "",
"topic_arn": "arn:aws:sns:us-east-2:566967686773:ec2-events"
},
"sensitive_attributes": [],
"private": "bnVsbA==",
"dependencies": [
"aws_sns_topic.ec2_events"
]
}
]
}
]
}

11
terraform/variables.tf Normal file
View File

@ -0,0 +1,11 @@
variable "ec2_region" {
description = "AWS region where all resources will be created"
type = string
default = "us-east-2"
}
variable "iam_role" {
description = "(Optional) IAM role ARN to assume when managing resources"
type = string
default = null
}