Skip to content

Commit

Permalink
Merge pull request #43 from abikouo/apigateway_lambda_v1
Browse files Browse the repository at this point in the history
awsconfig_apigateway_with_lambda_integration - new role
  • Loading branch information
abikouo authored Aug 14, 2023
2 parents 6ef187a + 6fbd416 commit 99bac88
Show file tree
Hide file tree
Showing 14 changed files with 391 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Name | Description
[cloud.aws_ops.enable_cloudtrail_encryption_with_kms](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/enable_cloudtrail_encryption_with_kms/README.md)|A role to encrypt an AWS CloudTrail trail using the AWS Key Management Service (AWS KMS) customer managed key you specify.
[cloud.aws_ops.manage_vpc_peering](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/manage_vpc_peering/README.md)|A role to create, delete and accept existing VPC peering connections.
[cloud.aws_ops.moving_objects_between_buckets](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/moving_objects_between_buckets/README.md)|A role to move objects from one bucket to another bucket.
[cloud.aws_ops.awsconfig_apigateway_with_lambda_integration](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/awsconfig_apigateway_with_lambda_integration/README.md)|A role to create/delete an API gateway with lambda function integration.


### Playbooks
Expand Down
3 changes: 3 additions & 0 deletions changelogs/fragments/awsconfig_apigateway.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- awsconfig_apigateway_with_lambda_integration - new role to create API gateway with Lambda integration
49 changes: 49 additions & 0 deletions roles/awsconfig_apigateway_with_lambda_integration/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# awsconfig_apigateway_with_lambda_integration

A role to create/delete an API gateway with lambda function integration.
the role produces variables **awsconfig_apigateway_with_lambda_integration\_\_invoke_url** that contains the URL to invoke API gateway and **awsconfig_apigateway_with_lambda_integration\_\_id** that contains the id of the API gateway created.

## Requirements

AWS User Account with permission to create API gateway, lambda function and IAM role.

## Role Variables

- **awsconfig_apigateway_with_lambda_integration_operation**: Whether to create or delete the API gateway. Choices: 'create', 'delete'. Default: 'create'.
- **awsconfig_apigateway_with_lambda_integration_api_name**: The name of the API gateway to create/delete.
- **awsconfig_apigateway_with_lambda_integration_id**: string identifier of the API gateway to update/delete.
- **awsconfig_apigateway_with_lambda_integration_tags**: collection of tags associated to the API gateway, this is used to ensure unique API gateway is created/deleted while running multiple times. Provided as dictionnary.
- **awsconfig_apigateway_with_lambda_integration_lambda_runtime**: The lambda function runtime. e.g: 'python3.8'
- **awsconfig_apigateway_with_lambda_integration_lambda_function_file**: The path to a valid file containing the code of the lambda function.
- **awsconfig_apigateway_with_lambda_integration_lambda_handler**: The lambda function handler. e.g: 'hello.lambda_handler'
- **awsconfig_apigateway_with_lambda_integration_stage_name**: The name for the Stage resource. Stage names can only contain alphanumeric characters, hyphens, and underscores. Maximum length is 128 characters.

## Dependencies

- role: [aws_setup_credentials](../aws_setup_credentials/README.md)

## Example Playbook

- hosts: localhost
roles:
- role: cloud.aws_ops.awsconfig_apigateway_with_lambda_integration
aws_access_key: xxxxxxxxxxx
aws_secret_key: xxxxxxxxxxx
aws_region: xxxxxxxx
awsconfig_apigateway_with_lambda_integration_operation: create
awsconfig_apigateway_with_lambda_integration_api_name: hello
awsconfig_apigateway_with_lambda_integration_tags:
automation: ansible
awsconfig_apigateway_with_lambda_integration_lambda_runtime: 'python3.8'
awsconfig_apigateway_with_lambda_integration_lambda_handler: 'hello.lambda_handler'
awsconfig_apigateway_with_lambda_integration_lambda_function_file: hello.py

## License

GNU General Public License v3.0 or later

See [LICENCE](https://github.com/ansible-collections/cloud.aws_ops/blob/main/LICENSE) to see the full text.

## Author Information

- Ansible Cloud Content Team
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
awsconfig_apigateway_with_lambda_integration_operation: create
awsconfig_apigateway_with_lambda_integration_default_api_name: "ansible-api"
awsconfig_apigateway_with_lambda_integration__iam_role_name: "{{ awsconfig_apigateway_with_lambda_integration_api_name | default(awsconfig_apigateway_with_lambda_integration_default_api_name) }}-role"
awsconfig_apigateway_with_lambda_integration__lambda_name: "{{ awsconfig_apigateway_with_lambda_integration_api_name | default(awsconfig_apigateway_with_lambda_integration_default_api_name) }}-lambda"
awsconfig_apigateway_with_lambda_integration__awsregion: "{{ aws_setup_credentials__output.aws_region }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Sid": "",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
dependencies:
- role: cloud.aws_ops.aws_setup_credentials
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
- name: Create API gateway
when: awsconfig_apigateway_with_lambda_integration_operation == 'create'
block:
- name: Get AWS caller info
amazon.aws.aws_caller_info:
register: awsconfig_apigateway_with_lambda_integration__caller_info

- name: Create temporary file
ansible.builtin.tempfile:
suffix: .json
register: awsconfig_apigateway_with_lambda_integration__swagger_file

- name: Generate swagger content
ansible.builtin.template:
src: 'swagger.json.j2'
dest: "{{ awsconfig_apigateway_with_lambda_integration__swagger_file.path }}"
mode: 0755

- name: Create API gateway
community.aws.api_gateway:
state: present
api_file: "{{ awsconfig_apigateway_with_lambda_integration__swagger_file.path }}"
stage: "{{ awsconfig_apigateway_with_lambda_integration_stage_name }}"
endpoint_type: REGIONAL
api_id: "{{ awsconfig_apigateway_with_lambda_integration_id | default(omit) }}"
name: "{{ awsconfig_apigateway_with_lambda_integration_api_name | default(awsconfig_apigateway_with_lambda_integration_default_api_name) }}"
tags: "{{ awsconfig_apigateway_with_lambda_integration_tags | default(omit) }}"
lookup: "{{ awsconfig_apigateway_with_lambda_integration_id is defined | ternary('id', 'tag') }}"
register: awsconfig_apigateway_with_lambda_integration__create_apigateway

- name: Define API gateway id as variable
ansible.builtin.set_fact:
awsconfig_apigateway_with_lambda_integration__id: "{{ awsconfig_apigateway_with_lambda_integration__create_apigateway.api_id }}"

- name: Give API gateway permission to invoke lambda function
amazon.aws.lambda_policy:
state: present
function_name: "{{ awsconfig_apigateway_with_lambda_integration__lambda_name }}"
statement_id: "AllowExecutionFromAPIGateway"
action: "lambda:InvokeFunction"
principal: "apigateway.amazonaws.com"
source_arn: "arn:aws:execute-api:{{ awsconfig_apigateway_with_lambda_integration__awsregion }}:{{ awsconfig_apigateway_with_lambda_integration__caller_info.account }}:{{ awsconfig_apigateway_with_lambda_integration__id }}/*/*"

- name: Define API gateway invoke url and API gateway identifier
ansible.builtin.set_fact:
awsconfig_apigateway_with_lambda_integration__invoke_url: "https://{{ awsconfig_apigateway_with_lambda_integration__id }}.execute-api.{{ awsconfig_apigateway_with_lambda_integration__awsregion }}.amazonaws.com/{{ awsconfig_apigateway_with_lambda_integration_stage_name }}"

always:
- name: Delete temporary file
ansible.builtin.file:
state: absent
path: "{{ awsconfig_apigateway_with_lambda_integration__swagger_file }}"
ignore_errors: true
when: awsconfig_apigateway_with_lambda_integration__swagger_file is defined

- name: Delete API gateway
when: awsconfig_apigateway_with_lambda_integration_operation == 'delete'
block:
- name: Ensure at least one of API gateway id or tags is provided to delete API gateway
ansible.builtin.fail:
msg: "At least one of API gateway id or tags should be supplied when trying to delete API gateway id"
when:
- awsconfig_apigateway_with_lambda_integration_id is not defined
- awsconfig_apigateway_with_lambda_integration_tags is not defined

- name: Delete API Gateway using identifier
when: awsconfig_apigateway_with_lambda_integration_id is defined
block:
- name: Get API gateway info
community.aws.api_gateway_info:
register: awsconfig_apigateway_with_lambda_integration__rest_apis

- name: Delete API gateway using identifier
community.aws.api_gateway:
state: absent
api_id: "{{ awsconfig_apigateway_with_lambda_integration_id }}"
when: awsconfig_apigateway_with_lambda_integration__rest_apis.rest_apis | selectattr('id', 'equalto', awsconfig_apigateway_with_lambda_integration_id) | list | length > 0

- name: Delete API gateway using tags
community.aws.api_gateway:
state: absent
name: "{{ awsconfig_apigateway_with_lambda_integration_api_name | default(awsconfig_apigateway_with_lambda_integration_default_api_name) }}"
tags: "{{ awsconfig_apigateway_with_lambda_integration_tags }}"
lookup: "tag"
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
- name: Create Lambda resources
when: awsconfig_apigateway_with_lambda_integration_operation == 'create'
block:
- name: Create role for lambda function
community.aws.iam_role:
name: "{{ awsconfig_apigateway_with_lambda_integration__iam_role_name }}"
assume_role_policy_document: '{{ lookup("file", "lambda_trust_policy.json") }}'
create_instance_profile: false
managed_policies:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
register: awsconfig_apigateway_with_lambda_integration__iam_role

- name: Wait for IAM role to be available
ansible.builtin.pause:
seconds: 10
when: awsconfig_apigateway_with_lambda_integration__iam_role is changed

- name: Create Lambda function
block:
- name: Create temporary zip file
ansible.builtin.tempfile:
suffix: .zip
register: awsconfig_apigateway_with_lambda_integration__tmp_file

- name: Create lambda function archive
community.general.archive:
format: zip
path: '{{ awsconfig_apigateway_with_lambda_integration_lambda_function_file }}'
dest: '{{ awsconfig_apigateway_with_lambda_integration__tmp_file.path }}'
mode: 0755

- name: Upload lambda function
amazon.aws.lambda:
name: "{{ awsconfig_apigateway_with_lambda_integration__lambda_name }}"
runtime: "{{ awsconfig_apigateway_with_lambda_integration_lambda_runtime | default(omit) }}"
handler: '{{ awsconfig_apigateway_with_lambda_integration_lambda_handler | default(omit) }}'
role: "{{ awsconfig_apigateway_with_lambda_integration__iam_role_name }}"
zip_file: "{{ awsconfig_apigateway_with_lambda_integration__tmp_file.path }}"
register: awsconfig_apigateway_with_lambda_integration__updload_lambda

- name: Ensure lambda function works
amazon.aws.lambda_execute:
name: "{{ awsconfig_apigateway_with_lambda_integration__lambda_name }}"
payload:
name: simple content to my lambda function

- name: Save lambda function ARN
ansible.builtin.set_fact:
awsconfig_apigateway_with_lambda_integration__lambda_arn: "{{ awsconfig_apigateway_with_lambda_integration__updload_lambda.configuration.function_arn }}"

always:
- name: Delete temporary file
ansible.builtin.file:
state: absent
path: "{{ awsconfig_apigateway_with_lambda_integration__tmp_file.path }}"
ignore_errors: true

- name: Delete Lambda resources
when: awsconfig_apigateway_with_lambda_integration_operation == 'delete'
block:
- name: Delete Lambda function
amazon.aws.lambda:
name: "{{ awsconfig_apigateway_with_lambda_integration__lambda_name }}"
state: absent

- name: Delete IAM role name
community.aws.iam_role:
name: "{{ awsconfig_apigateway_with_lambda_integration__iam_role_name }}"
state: absent
10 changes: 10 additions & 0 deletions roles/awsconfig_apigateway_with_lambda_integration/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
- name: Create/Delete API gateway with lambda integration
module_defaults:
group/aws: "{{ aws_setup_credentials__output }}"
block:
- name: "Include file {{ item }}"
ansible.builtin.include_tasks: '{{ item }}'
with_items:
- lambda.yml
- apigateway.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"openapi": "3.0.0",
"info": {
"version": "v1.0",
"title": "{{ awsconfig_apigateway_with_lambda_integration_api_name | default(awsconfig_apigateway_with_lambda_integration_default_api_name) }}"
},
"paths": {
"/{proxy+}": {
"x-amazon-apigateway-any-method": {
"parameters": [
{
"name": "proxy",
"in": "path",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200"
}
},
"requestTemplates": {
"application/json": "{}"
},
"uri": "arn:aws:apigateway:{{ awsconfig_apigateway_with_lambda_integration__awsregion }}:lambda:path/2015-03-31/functions/arn:aws:lambda:{{ awsconfig_apigateway_with_lambda_integration__awsregion }}:{{ awsconfig_apigateway_with_lambda_integration__caller_info.account }}:function:{{ awsconfig_apigateway_with_lambda_integration__lambda_name }}/invocations",
"passthroughBehavior": "when_no_match",
"httpMethod": "POST",
"type": "aws_proxy"
}
}
}
},
"definitions": {
"Empty": {
"type": "object"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cloud/aws
role/awsconfig_apigateway_with_lambda_integration
time=1m
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
aws_security_token: '{{ security_token | default(omit) }}'
awsconfig_apigateway_with_lambda_integration_api_name: "ansible-test-{{ resource_prefix }}"
awsconfig_apigateway_with_lambda_integration_tags:
resource_prefix: "{{ resource_prefix }}"
awsconfig_apigateway_with_lambda_integration_lambda_runtime: "python3.8"
awsconfig_apigateway_with_lambda_integration_lambda_handler: 'server.lambda_handler'
awsconfig_apigateway_with_lambda_integration_stage_name: test
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env python

import json


def lambda_handler(event, context):
resource_prefix = event.get("queryStringParameters", {}).get("resource_prefix")
path = event.get("pathParameters", {}).get("proxy")

message = ""
if path == "ansible-test":
message = "Running ansible-test with Resource prefix {0}".format(
resource_prefix
)

return {
"statusCode": 200,
"body": json.dumps(message, indent=2),
"headers": {"Content-Type": "application/json"},
}
Loading

0 comments on commit 99bac88

Please sign in to comment.