├── .gitignore
├── CODE_OF_CONDUCT.md
├── README.md
├── main.tf
├── outputs.tf
└── variables.tf
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled files
2 | *.tfstate
3 | *.tfstate.backup
4 |
5 | # Module directory
6 | .terraform/
7 | .idea/
8 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at ainestal@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # terraform-lambda-fixed-ip
2 | Provide a fixed IP (ElasticIP) to your AWS Lambdas.
3 |
4 | This is extremely useful when you need to connect to a service that filters IPs. Typical services use firewalls that can whitelist some IPs, by allowing your ElasticIP in the firewall rules you will be able to connect to the service from your Lambda.
5 |
6 |
7 | ## How it works
8 | - This terraform module creates a VPC in the eu-west-1 region (you can use a different region)
9 | - Creates a public and a private networks
10 | - Routes all the traffic from the private network to the public network
11 | - Routes all the traffic from the public network to internet
12 | - Assigns an elastic IP to the traffic coming from the public network, so it has a fixed IP
13 |
14 |
15 | ## How to use it
16 | - Include this module in your code:
17 | ```
18 | module "lambdas_vpc" {
19 | source = "github.com/ainestal/terraform-lambda-fixed-ip?ref=0.2"
20 | }
21 | ```
22 | - Plan terraform to see what is going to do:
23 | ```
24 | terraform plan
25 | ```
26 | - If you like what you see, apply the changes:
27 | ```
28 | terraform apply
29 | ```
30 | - Create your Lambdas inside the private subnet.
31 | - You can reference the vpc_id and the elastic ip id. If you are terraforming your lambda, the [lambda_function example](https://www.terraform.io/docs/providers/aws/r/lambda_function.html) would look like:
32 | ```
33 | resource "aws_lambda_function" "test_lambda" {
34 | filename = "lambda_function_payload.zip"
35 | function_name = "lambda_function_name"
36 | role = "${aws_iam_role.iam_for_lambda.arn}"
37 | handler = "exports.test"
38 | source_code_hash = "${base64sha256(file("lambda_function_payload.zip"))}"
39 | runtime = "nodejs4.3"
40 |
41 | environment {
42 | variables = {
43 | foo = "bar"
44 | }
45 | }
46 |
47 | // Include this Lambda in the VPC that provides a Elastic IP
48 | vpc_config {
49 | subnet_ids = [ ${module.lambdas_vpc.private_subnet_id} ]
50 |
51 | security_group_ids = [ ]
52 | }
53 | }
54 | ```
55 | - When your Lambdas run they will use your ElasticIP (and it will always be the same if you don't change it).
56 |
57 |
58 | ## Dependencies
59 | - Terraform >= 0.14.x , you can download it from [terraform downloads](https://www.terraform.io/downloads.html)
60 | - AWS account
61 |
--------------------------------------------------------------------------------
/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = var.region
3 | }
4 |
5 |
6 | //// VPC
7 | resource "aws_vpc" "lambdas" {
8 | cidr_block = var.vpc_cidr
9 | tags = merge(
10 | {
11 | Name = var.vpc_name
12 | },
13 | var.custom_tags
14 | )
15 | }
16 |
17 |
18 | //// Networks
19 | resource "aws_subnet" "lambdas-private" {
20 | cidr_block = var.private_subnet_cidr
21 | vpc_id = aws_vpc.lambdas.id
22 | tags = {
23 | Name = var.private_subnet_name
24 | }
25 | }
26 |
27 | resource "aws_subnet" "lambdas-public" {
28 | cidr_block = var.public_subnet_cidr
29 | vpc_id = aws_vpc.lambdas.id
30 | tags = {
31 | Name = var.public_subnet_name
32 | }
33 | }
34 |
35 |
36 | //// Gateways
37 | resource "aws_internet_gateway" "lambdas" {
38 | vpc_id = aws_vpc.lambdas.id
39 | }
40 |
41 | resource "aws_nat_gateway" "lambdas" {
42 | allocation_id = aws_eip.lambdas.id
43 | subnet_id = aws_subnet.lambdas-public.id
44 | tags = merge(
45 | {
46 | Name = var.nat_gateway_name
47 | },
48 | var.custom_tags
49 | )
50 | }
51 |
52 |
53 | //// Route tables Private
54 | resource "aws_route_table" "lambdas-private" {
55 | vpc_id = aws_vpc.lambdas.id
56 |
57 | route {
58 | cidr_block = "0.0.0.0/0"
59 | nat_gateway_id = aws_nat_gateway.lambdas.id
60 | }
61 | }
62 |
63 | resource "aws_route_table_association" "lambdas-private" {
64 | route_table_id = aws_route_table.lambdas-private.id
65 | subnet_id = aws_subnet.lambdas-private.id
66 | }
67 |
68 |
69 | //// Route tables Public
70 | resource "aws_route_table" "lambdas-public" {
71 | vpc_id = aws_vpc.lambdas.id
72 |
73 | route {
74 | cidr_block = "0.0.0.0/0"
75 | gateway_id = aws_internet_gateway.lambdas.id
76 | }
77 | }
78 |
79 | resource "aws_route_table_association" "lambdas-public" {
80 | route_table_id = aws_route_table.lambdas-public.id
81 | subnet_id = aws_subnet.lambdas-public.id
82 | }
83 |
84 |
85 | //// ElasticIp
86 | resource "aws_eip" "lambdas" {
87 | domain = "vpc"
88 | tags = merge(
89 | {
90 | Name = var.eip_name
91 | },
92 | var.custom_tags
93 | )
94 | }
95 |
96 | resource "aws_security_group" "allow_tls" {
97 | depends_on = [
98 | aws_vpc.lambdas
99 | ]
100 | name = "allow_tls"
101 | description = "Allow TLS inbound traffic"
102 | vpc_id = aws_vpc.lambdas.id
103 |
104 | ingress {
105 | description = "TLS from VPC"
106 | from_port = 443
107 | to_port = 443
108 | protocol = "tcp"
109 | cidr_blocks = [var.vpc_cidr]
110 | ipv6_cidr_blocks = ["::/0"]
111 | }
112 |
113 | egress {
114 | from_port = 0
115 | to_port = 0
116 | protocol = "-1"
117 | cidr_blocks = ["0.0.0.0/0"]
118 | ipv6_cidr_blocks = ["::/0"]
119 | }
120 |
121 | tags = {
122 | Name = "allow_tls"
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/outputs.tf:
--------------------------------------------------------------------------------
1 | output "vpc_id" {
2 | value = aws_vpc.lambdas.id
3 | }
4 |
5 | output "private_subnet_id" {
6 | value = aws_subnet.lambdas-private.id
7 | }
8 |
9 | output "eip_id" {
10 | value = aws_eip.lambdas.id
11 | }
12 |
13 | output "aws_security_group" {
14 | value = aws_security_group.allow_tls
15 | }
16 |
--------------------------------------------------------------------------------
/variables.tf:
--------------------------------------------------------------------------------
1 | variable "region" { default = "eu-west-2" }
2 | variable "vpc_cidr" { default = "10.0.0.0/16" }
3 | variable "vpc_name" { default = "lambdas-vpc" }
4 | variable "private_subnet_cidr" { default = "10.0.0.0/24" }
5 | variable "private_subnet_name" { default = "lambdas-private" }
6 | variable "public_subnet_cidr" { default = "10.0.1.0/24" }
7 | variable "public_subnet_name" { default = "lambdas-public" }
8 | variable "eip_name" {
9 | default ="Elastic IP for Lambdas VPC"
10 | }
11 | variable "nat_gateway_name" {
12 | default = "NAT Gateway for Lambdas VPC"
13 | }
14 | variable "custom_tags" {
15 | description = "A map of custom tags to apply to resources"
16 | type = map(string)
17 | default = {}
18 | }
--------------------------------------------------------------------------------