├── sca ├── jumphosts │ ├── output.tf │ ├── provider.tf │ ├── README.md │ ├── variables.tf │ └── jumphost_main.tf ├── container_stack │ ├── output.tf │ ├── inspec │ │ └── container-stack-ready │ │ │ ├── files │ │ │ └── .gitkeep │ │ │ ├── README.md │ │ │ ├── controls │ │ │ └── containerstack.rb │ │ │ └── inspec.yml │ ├── provider.tf │ ├── runtests.sh │ ├── README.md │ ├── variables.tf │ └── main.tf ├── inspec │ └── sca-ready │ │ ├── files │ │ └── .gitkeep │ │ ├── README.md │ │ ├── inspec.yml │ │ └── controls │ │ └── sca.rb ├── core │ ├── inspec │ │ └── core-ready │ │ │ ├── files │ │ │ └── .gitkeep │ │ │ ├── README.md │ │ │ ├── inspec.yml │ │ │ └── controls │ │ │ └── core.rb │ ├── provider.tf │ ├── README.md │ ├── runtests.sh │ ├── main.tf │ ├── variables.tf │ ├── security.tf │ ├── iam.tf │ └── output.tf ├── security_stack │ ├── inspec │ │ ├── aws-instance-ready │ │ │ ├── libraries │ │ │ │ └── .gitkeep │ │ │ ├── README.md │ │ │ ├── controls │ │ │ │ └── ready.rb │ │ │ └── inspec.yml │ │ ├── bigip-atc-ready │ │ │ ├── libraries │ │ │ │ └── .gitkeep │ │ │ ├── README.md │ │ │ ├── inspec.yml │ │ │ └── controls │ │ │ │ └── atc.rb │ │ └── security-stack-ready │ │ │ ├── files │ │ │ └── .gitkeep │ │ │ ├── README.md │ │ │ ├── controls │ │ │ └── security.rb │ │ │ └── inspec.yml │ ├── provider.tf │ ├── alien_ranges.tf │ ├── README.md │ ├── cfe_bucket.tf │ ├── variables.tf │ ├── runtests.sh │ ├── output.tf │ ├── ips.tf │ ├── internal.tf │ ├── external.tf │ └── templates │ │ ├── bigip_onboard_base.tmpl │ │ └── bigip_onboard.tmpl ├── application_stack │ ├── inspec │ │ └── application-stack-ready │ │ │ ├── files │ │ │ └── .gitkeep │ │ │ ├── README.md │ │ │ ├── controls │ │ │ └── appstack.rb │ │ │ └── inspec.yml │ ├── runtests.sh │ └── README.md ├── runtests.sh ├── README.md └── configuration_stack │ ├── templates │ ├── cloudFailoverExtension │ │ └── cfe.json │ ├── as3 │ │ └── as3.tmpl │ └── declarativeOnboarding │ │ ├── externalClusterPayg.json │ │ ├── ipsClusterPayg.json │ │ └── internalClusterPayg.json │ ├── variables.tf │ ├── README.md │ ├── as3declaration.tf │ ├── provider.tf │ ├── cloudFailoverExtension.tf │ └── declarativeOnboarding.tf ├── modules ├── appStack │ ├── README.md │ ├── json │ │ └── README.md │ ├── iRules │ │ └── README.md │ ├── scripts │ │ └── README.md │ └── templates │ │ └── README.md ├── awsInfrastructure │ ├── README.md │ ├── variables.tf │ ├── app_main.tf │ ├── k8s_main.tf │ └── tgw_main.tf ├── k8sStack │ ├── json │ │ └── README.md │ ├── iRules │ │ └── README.md │ ├── scripts │ │ └── README.md │ └── templates │ │ └── README.md ├── README.md └── securityStack │ ├── json │ └── README.md │ ├── README.md │ ├── iRules │ └── README.md │ ├── scripts │ └── README.md │ └── templates │ └── README.md ├── images ├── Concept_Arch.png ├── F5_SCA_V2_SECURITY_VPC_Fault_Domain_AZ.png └── F5_SCA_V2_SECURITY_VPC_Fault_Domain_Device.png ├── SUPPORT.txt ├── .gitignore ├── TERMS_OF_USE.txt └── LICENSE /sca/jumphosts/output.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sca/container_stack/output.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules/appStack/README.md: -------------------------------------------------------------------------------- 1 | # appStack -------------------------------------------------------------------------------- /modules/appStack/json/README.md: -------------------------------------------------------------------------------- 1 | # json -------------------------------------------------------------------------------- /modules/awsInfrastructure/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules/k8sStack/json/README.md: -------------------------------------------------------------------------------- 1 | # json -------------------------------------------------------------------------------- /sca/inspec/sca-ready/files/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules/README.md: -------------------------------------------------------------------------------- 1 | # f5-terraform-aws-sca -------------------------------------------------------------------------------- /modules/appStack/iRules/README.md: -------------------------------------------------------------------------------- 1 | # iRules -------------------------------------------------------------------------------- /modules/appStack/scripts/README.md: -------------------------------------------------------------------------------- 1 | # scripts -------------------------------------------------------------------------------- /modules/k8sStack/iRules/README.md: -------------------------------------------------------------------------------- 1 | # iRules -------------------------------------------------------------------------------- /modules/k8sStack/scripts/README.md: -------------------------------------------------------------------------------- 1 | # scripts -------------------------------------------------------------------------------- /modules/securityStack/json/README.md: -------------------------------------------------------------------------------- 1 | # json -------------------------------------------------------------------------------- /sca/core/inspec/core-ready/files/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules/appStack/templates/README.md: -------------------------------------------------------------------------------- 1 | # templates -------------------------------------------------------------------------------- /modules/k8sStack/templates/README.md: -------------------------------------------------------------------------------- 1 | # templates -------------------------------------------------------------------------------- /modules/securityStack/README.md: -------------------------------------------------------------------------------- 1 | # securityStack -------------------------------------------------------------------------------- /modules/securityStack/iRules/README.md: -------------------------------------------------------------------------------- 1 | # iRules -------------------------------------------------------------------------------- /modules/securityStack/scripts/README.md: -------------------------------------------------------------------------------- 1 | # scripts -------------------------------------------------------------------------------- /modules/securityStack/templates/README.md: -------------------------------------------------------------------------------- 1 | # templates -------------------------------------------------------------------------------- /sca/container_stack/inspec/container-stack-ready/files/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sca/security_stack/inspec/aws-instance-ready/libraries/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sca/security_stack/inspec/bigip-atc-ready/libraries/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sca/security_stack/inspec/security-stack-ready/files/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sca/application_stack/inspec/application-stack-ready/files/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sca/jumphosts/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.aws_region.value 3 | } -------------------------------------------------------------------------------- /sca/container_stack/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.aws_region.value 3 | } -------------------------------------------------------------------------------- /images/Concept_Arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f5devcentral/terraform-aws-f5-sca/HEAD/images/Concept_Arch.png -------------------------------------------------------------------------------- /sca/security_stack/inspec/aws-instance-ready/README.md: -------------------------------------------------------------------------------- 1 | # Example InSpec Profile 2 | 3 | This example shows the implementation of an InSpec profile. 4 | -------------------------------------------------------------------------------- /sca/security_stack/inspec/bigip-atc-ready/README.md: -------------------------------------------------------------------------------- 1 | # Example InSpec Profile 2 | 3 | This example shows the implementation of an InSpec profile. 4 | -------------------------------------------------------------------------------- /images/F5_SCA_V2_SECURITY_VPC_Fault_Domain_AZ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f5devcentral/terraform-aws-f5-sca/HEAD/images/F5_SCA_V2_SECURITY_VPC_Fault_Domain_AZ.png -------------------------------------------------------------------------------- /images/F5_SCA_V2_SECURITY_VPC_Fault_Domain_Device.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f5devcentral/terraform-aws-f5-sca/HEAD/images/F5_SCA_V2_SECURITY_VPC_Fault_Domain_Device.png -------------------------------------------------------------------------------- /sca/core/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.aws_region 3 | } 4 | 5 | terraform { 6 | required_providers { 7 | aws = "~> 2.59" 8 | random = "~> 2.2" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sca/inspec/sca-ready/README.md: -------------------------------------------------------------------------------- 1 | # SCA Readiness InSpec Profile 2 | 3 | This InSpec profile validates that the SCA deployment is valid and ready for use. 4 | 5 | TODO: What does the sentence above mean? 6 | -------------------------------------------------------------------------------- /sca/security_stack/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.aws_region.value 3 | } 4 | 5 | terraform { 6 | required_providers { 7 | aws = "~> 2.59" 8 | template = "~> 2.1" 9 | } 10 | } -------------------------------------------------------------------------------- /sca/core/inspec/core-ready/README.md: -------------------------------------------------------------------------------- 1 | # SCA Core Readiness InSpec Profile 2 | 3 | This InSpec profile validates that the SCA Core deployment is valid and ready for use. 4 | 5 | TODO: What does the sentence above mean? -------------------------------------------------------------------------------- /sca/container_stack/inspec/container-stack-ready/README.md: -------------------------------------------------------------------------------- 1 | # SCA Container Stack Readiness InSpec Profile 2 | 3 | This InSpec profile validates that the SCA Container deployment is valid and ready for use. 4 | 5 | TODO: What does the sentence above mean? -------------------------------------------------------------------------------- /sca/security_stack/inspec/security-stack-ready/README.md: -------------------------------------------------------------------------------- 1 | # SCA Security Stack Readiness InSpec Profile 2 | 3 | This InSpec profile validates that the SCA Security Stack deployment is valid and ready for use. 4 | 5 | TODO: What does the sentence above mean? -------------------------------------------------------------------------------- /sca/security_stack/alien_ranges.tf: -------------------------------------------------------------------------------- 1 | resource "aws_route" "internet_alien_range" { 2 | route_table_id = var.route_tables.value.internet 3 | destination_cidr_block = "192.168.100.0/24" 4 | network_interface_id = module.external_az1.public_nic_ids[0] 5 | } 6 | -------------------------------------------------------------------------------- /sca/security_stack/inspec/security-stack-ready/controls/security.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2020, F5 Networks 2 | 3 | title "Security Stack" 4 | 5 | include_controls 'aws-instance-ready' do 6 | 7 | end 8 | 9 | include_controls 'bigip-atc-ready' do 10 | 11 | end -------------------------------------------------------------------------------- /sca/application_stack/inspec/application-stack-ready/README.md: -------------------------------------------------------------------------------- 1 | # SCA Application Stack Readiness InSpec Profile 2 | 3 | This InSpec profile validates that the SCA Appliation Stack deployment is valid and ready for use. 4 | 5 | TODO: What does the sentence above mean? -------------------------------------------------------------------------------- /sca/core/README.md: -------------------------------------------------------------------------------- 1 | # Core Deployment 2 | This will deploy the core AWS services needed by the Secure Cloud Architecture 3 | 4 | ## Deployment Steps 5 | ### Initialize Terraform 6 | ```bash 7 | terraform init 8 | ``` 9 | ### Validate and Apply 10 | ```bash 11 | terraform validate && terraform apply 12 | ``` -------------------------------------------------------------------------------- /sca/inspec/sca-ready/inspec.yml: -------------------------------------------------------------------------------- 1 | name: sca-ready 2 | title: Secure Cloud Architecture InSpec Profile 3 | maintainer: heath.parrott@f5.com 4 | copyright: F5 Networks 5 | copyright_email: f5devcentral@f5.com 6 | license: Apache-2.0 7 | summary: An InSpec Compliance Profile validating the Secure Cloud Architecture environment is ready for use 8 | version: 0.1.0 9 | supports: 10 | platform: aws -------------------------------------------------------------------------------- /sca/security_stack/inspec/aws-instance-ready/controls/ready.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2020, F5 Networks 2 | 3 | title "AWS Instance Ready" 4 | 5 | control "Running in AWS" do 6 | impact 1.0 7 | title "AWS shows BIG-IP EC2 instance is running" 8 | describe aws_ec2_instance(input('instance_id')) do 9 | it { should exist } 10 | it { should be_running } 11 | end 12 | end -------------------------------------------------------------------------------- /sca/inspec/sca-ready/controls/sca.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2020, F5 Networks 2 | 3 | title "SCA Environment" 4 | 5 | # load data from Terraform output 6 | # created by terraform output --json > inspec/bigip-ready/files/terraform.json 7 | content = inspec.profile.file("terraform.json") 8 | params = JSON.parse(content) 9 | 10 | 11 | # 12 | # TODO: what tests validate that the sca environment is ready? 13 | # 14 | -------------------------------------------------------------------------------- /sca/core/inspec/core-ready/inspec.yml: -------------------------------------------------------------------------------- 1 | name: core-ready 2 | title: Secure Cloud Architecture Core InSpec Profile 3 | maintainer: heath.parrott@f5.com 4 | copyright: F5 Networks 5 | copyright_email: f5devcentral@f5.com 6 | license: Apache-2.0 7 | summary: An InSpec Compliance Profile validating the core of the Secure Cloud Architecture environment is ready for use 8 | version: 0.1.0 9 | supports: 10 | platform: aws -------------------------------------------------------------------------------- /sca/runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | tf_output_file='inspec/sca-ready/files/terraform.json' 3 | 4 | # Save the Terraform data into a JSON file for InSpec to read 5 | terraform output --json > $tf_output_file 6 | 7 | # Set the jumphost IP address 8 | jumphost=`cat $tf_output_file| jq '.jumphost_ip.value[0]' -r` 9 | 10 | # Run InSpec tests from the Jumphost 11 | inspec exec inspec/sca-ready -t ssh://azureuser@$jumphost -i tftest -------------------------------------------------------------------------------- /sca/core/runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | tf_output_file='inspec/core-ready/files/terraform.json' 3 | 4 | # Save the Terraform data into a JSON file for InSpec to read 5 | terraform output --json > $tf_output_file 6 | 7 | # Set the jumphost IP address 8 | jumphost=`cat $tf_output_file| jq '.jumphost_ip.value[0]' -r` 9 | 10 | # Run InSpec tests from the Jumphost 11 | inspec exec inspec/core-ready -t ssh://azureuser@$jumphost -i tftest -------------------------------------------------------------------------------- /sca/application_stack/inspec/application-stack-ready/controls/appstack.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2020, F5 Networks 2 | 3 | title "Application Stack" 4 | 5 | # load data from Terraform output 6 | # created by terraform output --json > inspec/bigip-ready/files/terraform.json 7 | content = inspec.profile.file("terraform.json") 8 | params = JSON.parse(content) 9 | 10 | 11 | # 12 | # TODO: what tests validate that the app stack is ready? 13 | # 14 | -------------------------------------------------------------------------------- /sca/container_stack/inspec/container-stack-ready/controls/containerstack.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2020, F5 Networks 2 | 3 | title "Container Stack" 4 | 5 | # load data from Terraform output 6 | # created by terraform output --json > inspec/bigip-ready/files/terraform.json 7 | content = inspec.profile.file("terraform.json") 8 | params = JSON.parse(content) 9 | 10 | 11 | # 12 | # TODO: what tests validate that the container stack is ready? 13 | # 14 | -------------------------------------------------------------------------------- /sca/container_stack/inspec/container-stack-ready/inspec.yml: -------------------------------------------------------------------------------- 1 | name: container-stack-ready 2 | title: Secure Cloud Architecture Container Environment InSpec Profile 3 | maintainer: heath.parrott@f5.com 4 | copyright: F5 Networks 5 | copyright_email: f5devcentral@f5.com 6 | license: Apache-2.0 7 | summary: An InSpec Compliance Profile validating the Secure Cloud Architecture Container environment is ready for use 8 | version: 0.1.0 9 | supports: 10 | platform: aws -------------------------------------------------------------------------------- /sca/container_stack/runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | tf_output_file='inspec/container-stack-ready/files/terraform.json' 3 | 4 | # Save the Terraform data into a JSON file for InSpec to read 5 | terraform output --json > $tf_output_file 6 | 7 | # Set the jumphost IP address 8 | jumphost=`cat $tf_output_file| jq '.jumphost_ip.value[0]' -r` 9 | 10 | # Run InSpec tests from the Jumphost 11 | inspec exec inspec/container-stack-ready -t ssh://azureuser@$jumphost -i tftest -------------------------------------------------------------------------------- /sca/application_stack/runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | tf_output_file='inspec/application-stack-ready/files/terraform.json' 3 | 4 | # Save the Terraform data into a JSON file for InSpec to read 5 | terraform output --json > $tf_output_file 6 | 7 | # Set the jumphost IP address 8 | jumphost=`cat $tf_output_file| jq '.jumphost_ip.value[0]' -r` 9 | 10 | # Run InSpec tests from the Jumphost 11 | inspec exec inspec/application-stack-ready -t ssh://azureuser@$jumphost -i tftest -------------------------------------------------------------------------------- /sca/application_stack/inspec/application-stack-ready/inspec.yml: -------------------------------------------------------------------------------- 1 | name: application-stack-ready 2 | title: Secure Cloud Architecture Application Environment InSpec Profile 3 | maintainer: heath.parrott@f5.com 4 | copyright: F5 Networks 5 | copyright_email: f5devcentral@f5.com 6 | license: Apache-2.0 7 | summary: An InSpec Compliance Profile validating the Secure Cloud Architecture Application environment is ready for use 8 | version: 0.1.0 9 | supports: 10 | platform: aws -------------------------------------------------------------------------------- /sca/core/main.tf: -------------------------------------------------------------------------------- 1 | # 2 | # Create a random id 3 | # 4 | resource "random_id" "id" { 5 | byte_length = 2 6 | } 7 | 8 | # 9 | # Deploy the base AWS infrastructure 10 | # 11 | module core { 12 | source = "../../modules/awsInfrastructure" 13 | 14 | aws_region = var.aws_region 15 | project = var.project 16 | region-az-1 = var.region-az-1 17 | region-az-2 = var.region-az-2 18 | cidr-1 = var.cidr-1 19 | cidr-2 = var.cidr-2 20 | cidr-3 = var.cidr-3 21 | } 22 | -------------------------------------------------------------------------------- /sca/security_stack/inspec/aws-instance-ready/inspec.yml: -------------------------------------------------------------------------------- 1 | name: aws-instance-ready 2 | title: AWS Instance Ready 3 | maintainer: Cody Green, Mark Menger 4 | copyright: F5 Networks 5 | copyright_email: c.green@f5.com, m.menger@f5.com 6 | license: Apache-2.0 7 | summary: An InSpec Compliance Profile to test that an AWS instance is in a ready state 8 | version: 0.1.0 9 | supports: 10 | platform: aws 11 | inputs: 12 | - name: instance_id 13 | description: AWS EC2 Instance ID 14 | type: String 15 | -------------------------------------------------------------------------------- /sca/security_stack/inspec/bigip-atc-ready/inspec.yml: -------------------------------------------------------------------------------- 1 | name: bigip-atc-ready 2 | title: Automation Toolchain Ready 3 | maintainer: Cody Green, Mark Menger 4 | copyright: F5 Networks 5 | copyright_email: c.green@f5.com, m.menger@f5.com 6 | license: Apache-2.0 7 | summary: An InSpec Compliance Profile to test that the F5 Automation Toolchain is ready and the right versions are installed 8 | version: 0.1.0 9 | supports: 10 | platform: os 11 | inputs: 12 | - name: instance_id 13 | description: AWS EC2 Instance ID 14 | type: String 15 | -------------------------------------------------------------------------------- /sca/application_stack/README.md: -------------------------------------------------------------------------------- 1 | # Application Stack Deployment 2 | This stack deploys the EC2 based applications. 3 | 4 | ## Deployment Steps 5 | ### Obtain state from 0-core and security stack 6 | ```bash 7 | terraform output -state=../core/terraform.tfstate --json > core.auto.tfvars.json 8 | terraform output -state=../core/terraform.tfstate --json > security.auto.tfvars.json 9 | ``` 10 | ### Initialize Terraform 11 | ```bash 12 | terraform init 13 | ``` 14 | ### Validate and Apply 15 | ```bash 16 | terraform validate && terraform apply 17 | ``` -------------------------------------------------------------------------------- /SUPPORT.txt: -------------------------------------------------------------------------------- 1 | Maintenance and F5 Technical Support of the F5 code is provided only if the software (i) is unmodified; and (ii) has been marked as F5 Supported in SOL80012344, (https://support.f5.com/csp/article/K80012344). Support will only be provided to customers who have an existing support contract, purchased separately, subject to F5’s support policies available at http://www.f5.com/about/guidelines-policies/ and http://askf5.com. 2 | 3 | The information required when opening a support case is available at https://support.f5.com/csp/article/K60974137 4 | -------------------------------------------------------------------------------- /sca/README.md: -------------------------------------------------------------------------------- 1 | # Deployment of the Secure Cloud Architecture Demo 2 | This directory contains the various Terraform modules to create the Secure Cloud Architecture (SCA) components: 3 | - Core: deployed the required AWS base infrastructure 4 | - Security Stack: deploys the Internet Ingress/Egress security stack and the various BIG-IPs 5 | - Application Stack: deploys the EC2 based application stack 6 | - Container Stack: deploys the container based application stack 7 | 8 | ## Deploy 9 | To deploy the full SCA stack you'll need to progress through the sub folders in the following order: 10 | 1. core 11 | 2. security_stack 12 | 3. application_stack 13 | 4. container_stack -------------------------------------------------------------------------------- /sca/security_stack/inspec/security-stack-ready/inspec.yml: -------------------------------------------------------------------------------- 1 | name: security-stack-ready 2 | title: Secure Cloud Architecture Security Stack InSpec Profile 3 | maintainer: heath.parrott@f5.com 4 | copyright: F5 Networks 5 | copyright_email: f5devcentral@f5.com 6 | license: Apache-2.0 7 | summary: An InSpec Compliance Profile validating the Secure Cloud Architecture security stack is ready for use 8 | version: 0.1.0 9 | supports: 10 | - platform: aws 11 | - platform: os 12 | depends: 13 | - name: aws-instance-ready 14 | path: ../aws-instance-ready 15 | - name: bigip-atc-ready 16 | path: ../bigip-atc-ready 17 | inputs: 18 | - name: instance_id 19 | description: AWS EC2 Instance ID 20 | type: String 21 | -------------------------------------------------------------------------------- /sca/security_stack/README.md: -------------------------------------------------------------------------------- 1 | # Security Stack Deployment 2 | This stack deploys the Security stack that protects the various application stacks. 3 | For demo purposes it will deploy three pairs of F5 BIG-IP appliances: 4 | - External BIG-IPs at the Internet Edge of the Security Stack 5 | - IPS BIG-IPs for network inspection and intrusion prevention services 6 | - Internal BIG-IPs at the Inside Edge of the Security Stach for application security 7 | 8 | ## Deployment Steps 9 | ### Obtain state from 0-core 10 | ```bash 11 | terraform output -state=../core/terraform.tfstate --json > core.auto.tfvars.json 12 | ``` 13 | ### Initialize Terraform 14 | ```bash 15 | terraform init 16 | ``` 17 | ### Validate and Apply 18 | ```bash 19 | terraform validate && terraform apply 20 | ``` -------------------------------------------------------------------------------- /sca/core/inspec/core-ready/controls/core.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2020, F5 Networks 2 | 3 | title "SCA Core" 4 | 5 | # load data from Terraform output 6 | # created by terraform output --json > inspec/bigip-ready/files/terraform.json 7 | content = inspec.profile.file("terraform.json") 8 | params = JSON.parse(content) 9 | 10 | begin 11 | SECURITY_GROUPS = params['security_groups']['value'] 12 | VPCS = params['vpcs']['value'] 13 | SUBNETS = params['subnets']['value'] 14 | ROUTE_TABLES = params['route_tables']['value'] 15 | TRANSIT_GATEWAYS = params['transit_gateways']['value'] 16 | rescue 17 | SECURITY_GROUPS = [] 18 | VPCS = [] 19 | SUBNETS = [] 20 | ROUTE_TABLES = [] 21 | TRANSIT_GATEWAYS = [] 22 | end 23 | 24 | # 25 | # TODO: what tests validate that the sca core is ready? 26 | # 27 | -------------------------------------------------------------------------------- /sca/container_stack/README.md: -------------------------------------------------------------------------------- 1 | # Container_Stack 2 | 3 | ## Deployment Steps 4 | ### Obtain state from 0-core and security stack 5 | ```bash 6 | terraform output -state=../core/terraform.tfstate --json > core.auto.tfvars.json 7 | ``` 8 | ### Initialize Terraform 9 | ```bash 10 | terraform init 11 | ``` 12 | ### Validate and Apply 13 | ```bash 14 | terraform validate && terraform apply 15 | ``` 16 | 17 | __Overview__ 18 | 19 | This module deploys a known vulnerable web application named juicebox in a Fargate Contiainer using AWSVPC network mode. DO NOT USE IT IN A PRODUCTION ENVIRONMENT. DO NOT CONNECT THIS VPC TO A PRODUCTION ENVIRONMENT OR ANY ENVIRONMENT WHERE A BREACH WILL CAUSE HARM. F5 MAKES NO WARRANTIES OR SUPPORT FOR THIS APPLICATION OR ANY BREACH, LOSS, OR OTHER EVENT DUE TO USING THIS APPLICATION. IT IS FOR SECURITY TESTING AND EXAMPLE ONLY. 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /sca/security_stack/cfe_bucket.tf: -------------------------------------------------------------------------------- 1 | resource "aws_s3_bucket" "cfe_external_bucket" { 2 | #Error: expected length of bucket_prefix to be in the range (0 - 37), got mydeployment-sca-tf--cfe-external-bucket-4bf0 3 | bucket_prefix = format( 4 | "%s-cfe-external-bucket-%s", 5 | var.project.value, 6 | var.random_id.value 7 | ) 8 | tags = { 9 | f5_cloud_failover_label = format( "%s-external-%s", var.project.value, var.random_id.value ) 10 | } 11 | } 12 | 13 | resource "aws_s3_bucket" "cfe_internal_bucket" { 14 | #Error: expected length of bucket_prefix to be in the range (0 - 37), got mydeployment-sca-tf--cfe-external-bucket-4bf0 15 | bucket_prefix = format( 16 | "%s-cfe-internal-bucket-%s", 17 | var.project.value, 18 | var.random_id.value 19 | ) 20 | tags = { 21 | f5_cloud_failover_label = format( "%s-internal-%s", var.project.value, var.random_id.value ) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | 11 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 12 | # .tfvars files are managed as part of configuration and so should be included in 13 | # version control. 14 | # 15 | *.tfvars 16 | *.tfvars.json 17 | 18 | # Ignore override files as they are usually used to override resources locally and so 19 | # are not checked in 20 | override.tf 21 | override.tf.json 22 | *_override.tf 23 | *_override.tf.json 24 | 25 | # Include override files you do wish to add to version control using negated pattern 26 | # 27 | # !example_override.tf 28 | 29 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 30 | # example: *tfplan* 31 | 32 | #.DS_store 33 | .DS_Store 34 | 35 | # InSpec files 36 | sca/*/inspec/*/files/*.json 37 | sca/*/inspec/*/inspec.lock 38 | -------------------------------------------------------------------------------- /sca/configuration_stack/templates/cloudFailoverExtension/cfe.json: -------------------------------------------------------------------------------- 1 | { 2 | "class":"Cloud_Failover", 3 | "controls":{ 4 | "class":"Controls", 5 | "logLevel":"silly" 6 | }, 7 | "environment":"aws", 8 | "externalStorage":{ 9 | "scopingTags":{ 10 | "f5_cloud_failover_label":"${label}" 11 | } 12 | }, 13 | "failoverAddresses":{ 14 | "scopingTags":{ 15 | "f5_cloud_failover_label":"${label}" 16 | } 17 | }, 18 | "failoverRoutes":{ 19 | "enabled": true, 20 | "scopingTags":{ 21 | "f5_cloud_failover_label":"${labelRouteTable}" 22 | }, 23 | "scopingAddressRanges":[ 24 | { 25 | "range":"${range}" 26 | } 27 | ], 28 | "defaultNextHopAddresses":{ 29 | "discoveryType":"static", 30 | "items": [ 31 | "${local_selfip}", 32 | "${remote_selfip}" 33 | ] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sca/security_stack/variables.tf: -------------------------------------------------------------------------------- 1 | variable "ec2_key_name" { 2 | description = "AWS EC2 Key name for SSH access" 3 | type = string 4 | } 5 | 6 | variable "ec2_instance_type" { 7 | description = "AWS EC2 instance type" 8 | type = string 9 | default = "m4.xlarge" 10 | } 11 | 12 | variable "atc_versions" { 13 | description = "F5 Automation Toolchain Version used in this project" 14 | type = map(string) 15 | default = { 16 | doVersion = "1.12.0" 17 | as3Version = "3.20.0" 18 | tsVersion = "1.11.0" 19 | cfVersion = "1.3.0" 20 | fastVersion = "0.2.0" 21 | } 22 | } 23 | 24 | variable aws_region {} 25 | variable project {} 26 | variable random_id {} 27 | variable secrets_manager_name {} 28 | variable iam_instance_profile_name {} 29 | variable security_groups {} 30 | variable vpcs {} 31 | variable subnets {} 32 | variable route_tables {} 33 | variable transit_gateways {} 34 | variable aws_cidr_ips {} 35 | variable subnet_cidrs {} 36 | -------------------------------------------------------------------------------- /sca/configuration_stack/variables.tf: -------------------------------------------------------------------------------- 1 | variable bigip_mgmt_ips {} 2 | variable project {} 3 | variable random_id {} 4 | 5 | variable "aws_region" {} 6 | 7 | # DO variables for each BIG-IP tier 8 | ## Ext tier 9 | variable "bigip_map" {} 10 | variable "ext0_gateway" { 11 | default = "10.100.0.1" 12 | } 13 | variable "ext1_gateway" { 14 | default = "10.100.10.1" 15 | } 16 | variable "ips0_gateway" { 17 | default = "10.100.6.1" 18 | } 19 | variable "ips1_gateway" { 20 | default = "10.100.16.1" 21 | } 22 | variable "int0_gateway" { 23 | default = "10.0.7.1" 24 | } 25 | variable "int1_gateway" { 26 | default = "10.0.17.1" 27 | } 28 | 29 | 30 | 31 | # DO variables common across all tiers 32 | variable ntp_server { 33 | default = "0.us.pool.ntp.org" 34 | } 35 | variable dns_server { 36 | default = "8.8.8.8" 37 | } 38 | variable timezone { 39 | default = "UTC" 40 | } 41 | variable uname { 42 | default = "admin" 43 | } 44 | variable secrets_manager_name {} 45 | 46 | variable cfe_bucket_external {} 47 | variable cfe_bucket_internal {} 48 | variable CFE_route_tables {} 49 | -------------------------------------------------------------------------------- /sca/configuration_stack/README.md: -------------------------------------------------------------------------------- 1 | # Configuration Stack Deployment 2 | This stack deploys the configuration to the infrastructure from the Security stack stacks. 3 | It will use the F5 Automation Toolchain for programmatic, declarative deployment of this configuration, using: 4 | - Declarative Onboarding (DO) for device-level configuration (selfIP's, DNS servers, cluster config, etc) 5 | - Cloud Failover Extension (CFE) for configuration of HA failover 6 | 7 | ## Deployment Steps 8 | ### Obtain state from 0-core 9 | ```bash 10 | terraform output -state=../core/terraform.tfstate --json > core.auto.tfvars.json 11 | ``` 12 | ### Obtain state from 1-security stack 13 | ```bash 14 | terraform output -state=../security_stack/terraform.tfstate --json > security.auto.tfvars.json 15 | ``` 16 | ### Initialize Terraform 17 | ```bash 18 | terraform init 19 | ``` 20 | ### Validate and Apply 21 | ```bash 22 | terraform validate && terraform apply 23 | ``` 24 | 25 | ### Known Issues 26 | - https://github.com/F5Networks/terraform-provider-bigip/issues/61 27 | - https://github.com/F5Networks/f5-declarative-onboarding/issues/129 28 | 29 | -------------------------------------------------------------------------------- /sca/jumphosts/README.md: -------------------------------------------------------------------------------- 1 | # JumpHost Stack 2 | 3 | ## Deployment Steps 4 | ### Obtain state from 0-core and security stack 5 | ```bash 6 | terraform output -state=../core/terraform.tfstate --json > core.auto.tfvars.json 7 | ``` 8 | ### Initialize Terraform 9 | ```bash 10 | terraform init 11 | ``` 12 | ### Validate and Apply 13 | ```bash 14 | terraform validate && terraform apply 15 | ``` 16 | 17 | __Overview__ 18 | 19 | This module deploys a two Ubuntu 18.x Server jump hosts. These systems run an SSH and RDP service allowing remote access into the environment. It is critical that you do the following 20 | 21 | 1. Lock down the incoming Security Group to your public IPs noted in /CIDR format via the variable. 22 | 2. SSH in with your __predefined__ [AWS key](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-ec2-keypairs.html) to setup a User/Pass for RDP access. Your key must be in the same region that you are deploying to. 23 | 3. It is recomended that you run an update once deployed to apply the latest security patches. 24 | 25 | ### Dependenices 26 | 27 | This stack depends on the core stack being deployed first. No other stacks are dependent on it. -------------------------------------------------------------------------------- /sca/configuration_stack/templates/as3/as3.tmpl: -------------------------------------------------------------------------------- 1 | { 2 | "class": "AS3", 3 | "action": "deploy", 4 | "persist": true, 5 | "logLevel": "info", 6 | "declaration": { 7 | "class": "ADC", 8 | "schemaVersion": "3.5.0", 9 | "id": "urn:uuid:b92236ad-a677-4574-8bce-7d1487aeb62f", 10 | "label": "baseline", 11 | "remark": "baseline VIPs", 12 | "baseline": { 13 | "class": "Tenant", 14 | "forward_outbound": { 15 | "class": "Application", 16 | "template": "generic", 17 | "forward_outbound": { 18 | "class": "Service_L4", 19 | "layer4": "any", 20 | "translateServerAddress": false, 21 | "translateServerPort": false, 22 | "virtualAddresses": [ 23 | "${virtualAddress}" 24 | ], 25 | "virtualPort": 0, 26 | "snat": "auto", 27 | "allowVlans": 28 | [ 29 | "${allowedVlan}" 30 | ] 31 | } 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /sca/configuration_stack/as3declaration.tf: -------------------------------------------------------------------------------- 1 | data "template_file" "as3_declaration_baseline" { 2 | template = file("${path.module}/templates/as3/as3.tmpl") 3 | 4 | vars = { 5 | virtualAddress = "0.0.0.0/0" 6 | allowedVlan = "internal" 7 | } 8 | } 9 | 10 | resource "bigip_as3" "external_bigip_az1" { 11 | depends_on = [ 12 | bigip_do.external_bigip_az1, 13 | bigip_do.external_bigip_az2, 14 | null_resource.cfe-internal-az1, 15 | null_resource.cfe-internal-az2 16 | ] 17 | provider = bigip.external_bigip_az1 18 | as3_json = templatefile("${path.module}/templates/as3/as3.tmpl", { 19 | virtualAddress = "0.0.0.0/0", 20 | allowedVlan = "internal" 21 | }) 22 | } 23 | 24 | resource "bigip_as3" "internal_bigip_az1" { 25 | depends_on = [ 26 | bigip_do.internal_bigip_az1, 27 | bigip_do.internal_bigip_az2, 28 | null_resource.cfe-internal-az1, 29 | null_resource.cfe-internal-az2 30 | ] 31 | provider = bigip.internal_bigip_az1 32 | as3_json = templatefile("${path.module}/templates/as3/as3.tmpl", { 33 | virtualAddress = "0.0.0.0/0", 34 | allowedVlan = "internal" 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /sca/core/variables.tf: -------------------------------------------------------------------------------- 1 | variable "aws_region" { 2 | description = "AWS Region to deploy SCA in" 3 | type = string 4 | } 5 | 6 | variable "project" { 7 | description = "Project name for the SCA deployment" 8 | type = string 9 | } 10 | 11 | variable "region-az-1" { 12 | description = "AWS Region availability zone to deploy 1 of the 2 SCA stacks" 13 | type = string 14 | } 15 | 16 | variable "region-az-2" { 17 | description = "AWS Region availability zone to deploy 1 of the 2 SCA stacks" 18 | type = string 19 | } 20 | variable "allowed_mgmt_cidr" { 21 | description = "CIDR of allowed IPs for the BIG-IP management interface" 22 | type = string 23 | default = "0.0.0.0/0" 24 | } 25 | 26 | variable "allowed_app_cidr" { 27 | description = "CIDR of allowed IPs for the BIG-IP Virtual Servers" 28 | type = string 29 | default = "0.0.0.0/0" 30 | } 31 | 32 | variable "cidr-1" { 33 | description = "CIDR block for the Security VPC" 34 | default = "10.100.0.0/16" 35 | } 36 | 37 | variable "cidr-2" { 38 | description = "CIDR block for the Applicaiton VPC" 39 | default = "10.200.0.0/16" 40 | } 41 | 42 | variable "cidr-3" { 43 | description = "CIDR block for the Container VPC" 44 | default = "10.240.0.0/16" 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /sca/security_stack/runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | tf_output_file='inspec/security-stack-ready/files/terraform.json' 3 | 4 | # Save the Terraform data into a JSON file for InSpec to read 5 | terraform output --json > $tf_output_file 6 | 7 | # internal management interfaces - uncommented when jumphost is ready 8 | bigips=$(jq '.bigip_mgmt_dns.value[][]' $tf_output_file -r) 9 | bigip_mgmt_port=443 10 | bigip_instance_ids=$(terraform show --json | jq '.values.root_module.child_modules[].resources[] | select(.address=="aws_instance.f5_bigip") | .values.id' -r) 11 | 12 | for bigip_instance_id in $bigip_instance_ids 13 | do 14 | echo $bigip_instance_id 15 | inspec exec inspec/security-stack-ready --input instance_id=$bigip_instance_id -t aws:// || break 16 | done || exit 1 17 | 18 | # get the BIG-IP password 19 | secrets_manager_name=$(jq '.secrets_manager_name.value' core.auto.tfvars.json) 20 | secrets_manager_id=$(terraform show -json | jq '.values.root_module.child_modules[].resources[] | select(.address=="data.aws_secretsmanager_secret.password") | .values.id ' -r | head -n 1) 21 | bigip_password=$(aws secretsmanager get-secret-value --secret-id "$secrets_manager_id" | jq '.SecretString' -r) 22 | for bigip in $bigips 23 | do 24 | echo $bigip 25 | inspec exec inspec/security-stack-ready --input bigip_mgmt_ip=$bigip bigip_password=$bigip_password || break 26 | done || exit 1 -------------------------------------------------------------------------------- /sca/core/security.tf: -------------------------------------------------------------------------------- 1 | # 2 | # Create a security group for BIG-IP 3 | # 4 | module "bigip_sg" { 5 | source = "terraform-aws-modules/security-group/aws" 6 | 7 | name = format("%s-bigip-%s", var.project, random_id.id.hex) 8 | description = "Security group for BIG-IP " 9 | vpc_id = module.core.security-vpc 10 | 11 | ingress_cidr_blocks = [var.allowed_app_cidr] 12 | ingress_rules = ["http-80-tcp", "https-443-tcp"] 13 | 14 | ingress_with_source_security_group_id = [ 15 | { 16 | rule = "all-all" 17 | source_security_group_id = module.bigip_sg.this_security_group_id 18 | } 19 | ] 20 | 21 | # Allow ec2 instances outbound Internet connectivity 22 | egress_cidr_blocks = ["0.0.0.0/0"] 23 | egress_rules = ["all-all"] 24 | } 25 | 26 | # 27 | # Create a security group for BIG-IP Management 28 | # 29 | module "bigip_mgmt_sg" { 30 | source = "terraform-aws-modules/security-group/aws" 31 | 32 | name = format("%s-bigip-mgmt-%s", var.project, random_id.id.hex) 33 | description = "Security group for BIG-IP Management" 34 | vpc_id = module.core.security-vpc 35 | 36 | ingress_cidr_blocks = [var.allowed_mgmt_cidr] 37 | ingress_rules = ["https-443-tcp", "https-8443-tcp", "ssh-tcp"] 38 | 39 | ingress_with_source_security_group_id = [ 40 | { 41 | rule = "all-all" 42 | source_security_group_id = module.bigip_mgmt_sg.this_security_group_id 43 | } 44 | ] 45 | 46 | # Allow ec2 instances outbound Internet connectivity 47 | egress_cidr_blocks = ["0.0.0.0/0"] 48 | egress_rules = ["all-all"] 49 | } 50 | -------------------------------------------------------------------------------- /sca/configuration_stack/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.aws_region.value 3 | } 4 | 5 | provider "bigip" { 6 | version = "~> 1.2" 7 | alias = "external_bigip_az1" 8 | address = "https://${var.bigip_mgmt_ips.value.external_az1[0]}" 9 | username = "admin" 10 | password = data.aws_secretsmanager_secret_version.secret.secret_string 11 | } 12 | 13 | provider "bigip" { 14 | version = "~> 1.2" 15 | alias = "external_bigip_az2" 16 | address = "https://${var.bigip_mgmt_ips.value.external_az2[0]}" 17 | username = "admin" 18 | password = data.aws_secretsmanager_secret_version.secret.secret_string 19 | } 20 | 21 | provider "bigip" { 22 | version = "~> 1.2" 23 | alias = "ips_bigip_az1" 24 | address = "https://${var.bigip_mgmt_ips.value.ips_az1[0]}" 25 | username = "admin" 26 | password = data.aws_secretsmanager_secret_version.secret.secret_string 27 | } 28 | 29 | provider "bigip" { 30 | version = "~> 1.2" 31 | alias = "ips_bigip_az2" 32 | address = "https://${var.bigip_mgmt_ips.value.ips_az2[0]}" 33 | username = "admin" 34 | password = data.aws_secretsmanager_secret_version.secret.secret_string 35 | } 36 | 37 | provider "bigip" { 38 | version = "~> 1.2" 39 | alias = "internal_bigip_az1" 40 | address = "https://${var.bigip_mgmt_ips.value.internal_az1[0]}" 41 | username = "admin" 42 | password = data.aws_secretsmanager_secret_version.secret.secret_string 43 | } 44 | 45 | provider "bigip" { 46 | version = "~> 1.2" 47 | alias = "internal_bigip_az2" 48 | address = "https://${var.bigip_mgmt_ips.value.internal_az2[0]}" 49 | username = "admin" 50 | password = data.aws_secretsmanager_secret_version.secret.secret_string 51 | } 52 | -------------------------------------------------------------------------------- /sca/configuration_stack/templates/declarativeOnboarding/externalClusterPayg.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/master/src/schema/latest/base.schema.json", 3 | "schemaVersion": "1.11.1", 4 | "class": "Device", 5 | "async": true, 6 | "label": "External Cluster PAYG", 7 | "Common": { 8 | "class": "Tenant", 9 | "hostname": "${local_host}", 10 | "dbvars": { 11 | "class": "DbVariables", 12 | "ui.advisory.enabled": true, 13 | "ui.advisory.color": "green", 14 | "ui.advisory.text": "/Common/hostname" 15 | }, 16 | "myDns": { 17 | "class": "DNS", 18 | "nameServers": [ 19 | "169.254.169.254", 20 | "${dns_server}" 21 | ], 22 | "search": [ 23 | "f5.com", 24 | "ec2.internal", 25 | "compute-1.internal" 26 | ] 27 | }, 28 | "myNtp": { 29 | "class": "NTP", 30 | "servers": [ 31 | "${ntp_server}", 32 | "0.pool.ntp.org", 33 | "1.pool.ntp.org" 34 | ], 35 | "timezone": "${timezone}" 36 | }, 37 | "myProvisioning": { 38 | "class": "Provision", 39 | "ltm": "nominal", 40 | "afm": "nominal" 41 | }, 42 | "configsync": { 43 | "class": "ConfigSync", 44 | "configsyncIp": "${local_selfip2}" 45 | }, 46 | "failoverAddress": { 47 | "class": "FailoverUnicast", 48 | "address": "${local_selfip2}" 49 | }, 50 | "failoverGroup": { 51 | "class": "DeviceGroup", 52 | "type": "sync-failover", 53 | "members": [ 54 | "${host1}", 55 | "${host2}" 56 | ], 57 | "owner": "/Common/failoverGroup/members/0", 58 | "autoSync": true, 59 | "saveOnAutoSync": false, 60 | "networkFailover": true, 61 | "fullLoadOnSync": false 62 | }, 63 | "trust": { 64 | "class": "DeviceTrust", 65 | "localUsername": "${admin_user}", 66 | "localPassword": "${admin_password}", 67 | "remoteHost": "${remote_selfip}", 68 | "remoteUsername": "${admin_user}", 69 | "remotePassword": "${admin_password}" 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /sca/core/iam.tf: -------------------------------------------------------------------------------- 1 | # 2 | # Get current AWS region 3 | # 4 | data "aws_region" "current" {} 5 | 6 | # 7 | # Get caller identity 8 | # 9 | data "aws_caller_identity" "current" {} 10 | 11 | # 12 | # Create IAM Role 13 | # 14 | data "aws_iam_policy_document" "bigip_role" { 15 | version = "2012-10-17" 16 | statement { 17 | actions = [ 18 | "sts:AssumeRole" 19 | ] 20 | principals { 21 | type = "Service" 22 | identifiers = ["ec2.amazonaws.com"] 23 | } 24 | } 25 | } 26 | 27 | resource "aws_iam_role" "bigip_role" { 28 | name = format("%s-bigip-role-%s", var.project, random_id.id.hex) 29 | assume_role_policy = data.aws_iam_policy_document.bigip_role.json 30 | 31 | tags = { 32 | tag-key = "tag-value" 33 | } 34 | } 35 | 36 | resource "aws_iam_instance_profile" "bigip_profile" { 37 | name = format("%s-bigip-profile-%s", var.project, random_id.id.hex) 38 | role = aws_iam_role.bigip_role.name 39 | } 40 | 41 | data "aws_iam_policy_document" "bigip_policy" { 42 | version = "2012-10-17" 43 | statement { 44 | actions = [ 45 | "secretsmanager:GetSecretValue" 46 | ] 47 | 48 | resources = [ 49 | module.core.secrets_manager_id 50 | ] 51 | } 52 | statement { 53 | actions = [ 54 | "ec2:DescribeInstances", 55 | "ec2:DescribeInstanceStatus", 56 | "ec2:DescribeAddresses", 57 | "ec2:DescribeNetworkInterfaces", 58 | "ec2:DescribeNetworkInterfaceAttribute", 59 | "ec2:DescribeRouteTables", 60 | "s3:ListAllMyBuckets", 61 | "ec2:AssociateAddress", 62 | "ec2:DisassociateAddress", 63 | "ec2:AssignPrivateIpAddresses", 64 | "ec2:UnassignPrivateIpAddresses", 65 | ] 66 | resources = ["*"] 67 | } 68 | statement { 69 | actions = [ 70 | "ec2:CreateRoute", 71 | "ec2:ReplaceRoute" 72 | ] 73 | # resources = [format("arn:aws:ec2:%s:%s:route-table/%s", 74 | # data.aws_region.current.name, 75 | # data.aws_caller_identity.current.account_id, 76 | # var.cfe_route_table_id 77 | # )] 78 | resources = ["*"] 79 | # condition { 80 | # test = "StringEquals" 81 | # variable = "ec2:ResourceTag/Name" 82 | # values = [var.cfe_ec2_resource_tag] 83 | # } 84 | } 85 | statement { 86 | actions = [ 87 | "s3:ListBucket", 88 | "s3:GetBucketTagging" 89 | ] 90 | # resources = [format("arn:aws:s3:::%s", var.cfe_route_table_id)] 91 | resources = ["*"] 92 | } 93 | statement { 94 | actions = [ 95 | "s3:PutObject", 96 | "s3:GetObject", 97 | "s3:DeleteObject" 98 | ] 99 | # resources = [format("arn:aws:s3:::%s/*", var.cfe_route_table_id)] 100 | resources = ["*"] 101 | } 102 | statement { 103 | actions = ["logs:*"] 104 | resources = ["*"] 105 | } 106 | } 107 | 108 | resource "aws_iam_role_policy" "bigip_policy" { 109 | name = format("%s-bigip-policy-%s", var.project, random_id.id.hex) 110 | role = aws_iam_role.bigip_role.id 111 | policy = data.aws_iam_policy_document.bigip_policy.json 112 | } 113 | -------------------------------------------------------------------------------- /sca/jumphosts/variables.tf: -------------------------------------------------------------------------------- 1 | /* ## F5 Networks Secure Cloud Migration and Securty Zone Template for AWS #################################################################################################################################################################################### 2 | Version 1.4 3 | March 2020 4 | 5 | 6 | This Template is provided as is and without warranty or support. It is intended for demonstration or reference purposes. While all attempts are made to ensure it functions as desired it is not a supported by F5 Networks. This template can be used 7 | to quickly deploy a Security VPC - aka DMZ, in-front of the your application VPC(S). Additional VPCs can be added to the template by adding CIDR variables, VPC resource blocks, VPC specific route tables 8 | and TransitGateway edits. Limits to VPCs that can be added are =to the limits of transit gateway. 9 | 10 | It is built to run in a region with three zones to use and will place services in 1a and 1c. Modifications to other zones can be done. 11 | 12 | F5 Application Services will be deployed into the security VPC but if one wished they could also be deployed inside of the Application VPCs. 13 | 14 | */ 15 | 16 | ############################################################################################################################################################################################################################################################### 17 | 18 | #### Deploy Fargate Containers and Service Discovery Service ################################################################################################################################################################################################### 19 | # 20 | # This stack is for EXAMPLE only and deploys a KNOWN VULNERABLE APPLICATION. DO NOT USE IN ENVIRONMENTS WHERE SECURITY IS A CONCERN!!!!!! 21 | # F5 can control ingress to Faregate services and leverage the DNS Name service to locate the items. Note you will have to decrease the default time on the NODE (not pool) for DNS discovery to work efficiently. You will need to use the DNS name 22 | # juiceshop.my-project.local for your node. 23 | # 24 | # 25 | ################################################################################################################################################################################################################################################################ 26 | 27 | ### Stack Default Variables 28 | 29 | variable aws_region {} 30 | variable project {} 31 | variable random_id {} 32 | variable secrets_manager_name {} 33 | variable iam_instance_profile_name {} 34 | variable security_groups {} 35 | variable vpcs {} 36 | variable subnets {} 37 | variable route_tables {} 38 | variable transit_gateways {} 39 | variable cidrs {} 40 | variable subnet_cidrs {} 41 | variable aws_cidr_ips {} 42 | 43 | 44 | ### JumpHost Variables 45 | 46 | variable jump_ssh_key { 47 | description = "Predefined AWS SSH key used to access the sytem and create a user/password combination for RDP Access. The key must be in the same region that you are deploying to" 48 | } 49 | 50 | variable my_public_ip { 51 | description = "The Subnet or Source IP that you will connect from since RDP and SSH are open to external access. Use CIDR notation" 52 | type = string 53 | } 54 | 55 | -------------------------------------------------------------------------------- /sca/container_stack/variables.tf: -------------------------------------------------------------------------------- 1 | /* ## F5 Networks Secure Cloud Migration and Securty Zone Template for AWS #################################################################################################################################################################################### 2 | Version 1.4 3 | March 2020 4 | 5 | 6 | This Template is provided as is and without warranty or support. It is intended for demonstration or reference purposes. While all attempts are made to ensure it functions as desired it is not a supported by F5 Networks. This template can be used 7 | to quickly deploy a Security VPC - aka DMZ, in-front of the your application VPC(S). Additional VPCs can be added to the template by adding CIDR variables, VPC resource blocks, VPC specific route tables 8 | and TransitGateway edits. Limits to VPCs that can be added are =to the limits of transit gateway. 9 | 10 | It is built to run in a region with three zones to use and will place services in 1a and 1c. Modifications to other zones can be done. 11 | 12 | F5 Application Services will be deployed into the security VPC but if one wished they could also be deployed inside of the Application VPCs. 13 | 14 | */ 15 | 16 | ############################################################################################################################################################################################################################################################### 17 | 18 | #### Deploy Fargate Containers and Service Discovery Service ################################################################################################################################################################################################### 19 | # This stack is for EXAMPLE only and deploys a KNOWN VULNERABLE APPLICATION. DO NOT USE IN ENVIRONMENTS WHERE SECURITY IS A CONCERN!!!!!! 20 | # F5 can control ingress to Faregate services and leverage the DNS Name service to locate the items. Note you will have to decrease the default time on the NODE (not pool) for DNS discovery to work efficiently. You will need to use the DNS name 21 | # juiceshop.my-project.local for your node. 22 | # 23 | # 24 | ################################################################################################################################################################################################################################################################ 25 | 26 | ### Stack Default Variables 27 | 28 | variable aws_region {} 29 | variable project {} 30 | variable random_id {} 31 | variable secrets_manager_name {} 32 | variable iam_instance_profile_name {} 33 | variable security_groups {} 34 | variable vpcs {} 35 | variable subnets {} 36 | variable route_tables {} 37 | variable transit_gateways {} 38 | variable cidrs {} 39 | variable subnet_cidrs {} 40 | variable aws_cidr_ips {} 41 | 42 | ### Fargate Variables 43 | 44 | variable "app_image" { 45 | description = "Docker image to run in the ECS cluster" 46 | 47 | default = "bkimminich/juice-shop" 48 | } 49 | 50 | variable "app_port" { 51 | description = "Port exposed by the docker image to redirect traffic to" 52 | default = 3000 53 | } 54 | 55 | variable "app_count" { 56 | description = "Number of docker containers to run" 57 | default = 3 58 | } 59 | 60 | variable "fargate_cpu" { 61 | description = "Fargate instance CPU units to provision (1 vCPU = 1024 CPU units)" 62 | default = 256 63 | } 64 | 65 | variable "fargate_memory" { 66 | description = "Fargate instance memory to provision (in MiB)" 67 | default = "512" 68 | } 69 | -------------------------------------------------------------------------------- /TERMS_OF_USE.txt: -------------------------------------------------------------------------------- 1 | THIS LICENSE AGREEMENT IS ENTERED INTO BETWEEN THE SUBMITTING PARTY AND F5 NETWORKS, INC. AND THE SUBMITTING PARTY AGREES TO BE BOUND BY THE TERMS OF THIS AGREEMENT BY SUBMITTING, POSTING, DOWNLOADING, COPYING, MODIFYING, INPUTTING, INSTALLATION, UPLOAD OR OTHER USE OF F5 MATERIALS AND THE SUBMISSIONS. IF YOU DO NOT AGREE TO THE FOREGOING, DO NOT POST THE SUBISSIONS OR USE THE F5 MATERIALS. 2 | (1) F5 does not claim ownership of the materials you provide to F5 (including feedback and suggestions) or post, upload, input or submit to any F5 GitHub repository (collectively "Submissions"). However, by posting, uploading, inputting, providing or submitting your Submission you grant F5, its affiliated companies and necessary sub-licensees a full, complete, irrevocable copyright license to use your Submission including, without limitation, the rights to: copy, distribute, transmit, publicly display, publicly perform, reproduce, edit, translate and reformat your Submission; and to publish your name in connection with your Submission. In addition, you agree that your submission will be subject to the terms of the MIT License (https://github.com/f5devcentral/f5-postman-collections/LICENSE.txt). 3 | (2) By posting, uploading, inputting, providing or submitting your Submission you warrant and represent that you own, are approved by your employer, or otherwise control all of the rights to your Submission as described including, without limitation, all the rights necessary for you to provide, post, upload, input or submit the Submissions. 4 | (3) Infringement Indemnification. Submitting party will defend and indemnify F5 against a claim that any information, design, specification, instruction, software, data, or material furnished by the submitting party under this license infringes a trademark, copyright, or patent. F5 will notify the submitting party promptly of such claim and will give sole control of defense and all related settlement negotiations to submitting party. F5 will provide reasonable assistance, information, and authority necessary to perform these obligations. Reasonable out-of-pocket expenses incurred by F5 for providing such assistance will be reimbursed by the submitting party. 5 | (4) THE MATERIALS AND SERVICES MADE AVAILABLE AT AND THROUGH THIS SITE ARE PROVIDED BY F5 ON AN "AS IS" BASIS. F5 MAKES NO REPRESENTATIONS, WARRANTIES OR GUARANTIES OF ANY KIND, EXPRESS OR IMPLIED, AS TO THE OPERATION OF THIS SITE, ITS CONTENT, OR ANY PRODUCTS OR SERVICES DESCRIBED OR OFFERED BY THIS SITE. TO THE FULL EXTENT PERMISSIBLE BY APPLICABLE LAW, F5 DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY, INCLUDING MERCHANTABILITY OF COMPUTER PROGRAMS AND INFORMATIONAL CONTENT, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, TITLE, OR THAT THE SITE CONTENT IS RELIABLE, ACCURATE, OR TIMELY. F5 WILL NOT BE LIABLE FOR ANY DAMAGES OF ANY KIND ARISING FROM THE USE OF THIS SITE, INCLUDING, BUT NOT LIMITED TO DIRECT, INDIRECT, INCIDENTAL, PUNITIVE, SPECIAL, CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF USE, DATA OR PROFITS, ARISING OUT OF OR IN ANY WAY CONNECTED WITH THE USE OR PERFORMANCE OF THE WEB SITE, WITH THE DELAY OR INABILITY TO USE THE WEB SITE OR RELATED SERVICES, THE PROVISION OF OR FAILURE TO PROVIDE SERVICES, OR FOR ANY INFORMATION, SOFTWARE, PRODUCTS, SERVICES AND RELATED GRAPHICS OBTAINED THROUGH THE WEB SITE, OR OTHERWISE ARISING OUT OF THE USE OF THE WEB SITE, WHETHER BASED ON CONTRACT, TORT, NEGLIGENCE, STRICT LIABILITY OR OTHERWISE, EVEN IF F5 OR ANY OF ITS SUPPLIERS HAS BEEN ADVISED OF THE POSSIBILITY OF DAMAGES. BECAUSE SOME STATES/JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU. WHILE THIS SITE MAY PROVIDE LINKS TO THIRD PARTY SITES, F5 DOES NOT CONTROL OR ENDORSE ANY THIRD PARTY SITE AND DISCLAIMS ANY RESPONSIBILITY FOR ITS FUNCTIONALITY OR CONTENT. THESE DISCLAIMERS AND LIMITATIONS ARE MADE IN ADDITION TO THOSE MADE IN AND APPLICABLE TO VARIOUS PAGES OR SECTIONS OF THIS SITE. 6 | -------------------------------------------------------------------------------- /sca/security_stack/output.tf: -------------------------------------------------------------------------------- 1 | # BIG-IP Management Public IP Addresses 2 | output "bigip_mgmt_ips" { 3 | value = { 4 | external_az1 = module.external_az1.mgmt_public_ips 5 | external_az2 = module.external_az2.mgmt_public_ips 6 | ips_az1 = module.ips_az1.mgmt_public_ips 7 | ips_az2 = module.ips_az2.mgmt_public_ips 8 | internal_az1 = module.internal_az1.mgmt_public_ips 9 | internal_az2 = module.internal_az2.mgmt_public_ips 10 | } 11 | } 12 | 13 | # BIG-IP Management Public DNS Address 14 | output "bigip_mgmt_dns" { 15 | value = { 16 | external_az1 = module.external_az1.mgmt_public_dns 17 | external_az2 = module.external_az2.mgmt_public_dns 18 | ips_az1 = module.ips_az1.mgmt_public_dns 19 | ips_az2 = module.ips_az2.mgmt_public_dns 20 | internal_az1 = module.internal_az1.mgmt_public_dns 21 | internal_az2 = module.internal_az2.mgmt_public_dns 22 | } 23 | } 24 | 25 | # BIG-IP Management Port 26 | output "bigip_mgmt_port" { 27 | value = { 28 | external_az1 = module.external_az1.mgmt_port 29 | external_az2 = module.external_az2.mgmt_port 30 | ips_az1 = module.ips_az1.mgmt_port 31 | ips_az2 = module.ips_az2.mgmt_port 32 | internal_az1 = module.internal_az1.mgmt_port 33 | internal_az2 = module.internal_az2.mgmt_port 34 | } 35 | } 36 | 37 | output "mgmt_addresses" { 38 | description = "List of BIG-IP management addresses" 39 | value = { 40 | external_az1 = module.external_az1.mgmt_addresses 41 | external_az2 = module.external_az2.mgmt_addresses 42 | ips_az1 = module.ips_az1.mgmt_addresses 43 | ips_az2 = module.ips_az2.mgmt_addresses 44 | internal_az1 = module.internal_az1.mgmt_addresses 45 | internal_az2 = module.internal_az2.mgmt_addresses 46 | } 47 | } 48 | 49 | output "public_addresses" { 50 | description = "List of BIG-IP public addresses" 51 | value = { 52 | external_az1 = module.external_az1.public_addresses 53 | external_az2 = module.external_az2.public_addresses 54 | ips_az1 = module.ips_az1.public_addresses 55 | ips_az2 = module.ips_az2.public_addresses 56 | internal_az1 = module.internal_az1.public_addresses 57 | internal_az2 = module.internal_az2.public_addresses 58 | } 59 | } 60 | 61 | output "private_addresses" { 62 | description = "List of BIG-IP private addresses" 63 | value = { 64 | external_az1 = module.external_az1.private_addresses 65 | external_az2 = module.external_az2.private_addresses 66 | ips_az1 = module.ips_az1.private_addresses 67 | ips_az2 = module.ips_az2.private_addresses 68 | internal_az1 = module.internal_az1.private_addresses 69 | internal_az2 = module.internal_az2.private_addresses 70 | } 71 | } 72 | 73 | # Public Network Interface 74 | output "public_nic_ids" { 75 | description = "List of BIG-IP public network interface ids" 76 | value = { 77 | external_az1 = module.external_az1.public_nic_ids 78 | external_az2 = module.external_az2.public_nic_ids 79 | ips_az1 = module.ips_az1.public_nic_ids 80 | ips_az2 = module.ips_az2.public_nic_ids 81 | internal_az1 = module.internal_az1.public_nic_ids 82 | internal_az2 = module.internal_az2.public_nic_ids 83 | } 84 | } 85 | 86 | # BIG-IP map 87 | output "bigip_map" { 88 | description = "Map of the deployed BIG-IPs and their network information" 89 | value = { 90 | external_az1 = module.external_az1.bigip_map 91 | external_az2 = module.external_az2.bigip_map 92 | ips_az1 = module.ips_az1.bigip_map 93 | ips_az2 = module.ips_az2.bigip_map 94 | internal_az1 = module.internal_az1.bigip_map 95 | internal_az2 = module.internal_az2.bigip_map 96 | } 97 | } 98 | 99 | # CFE bucket details 100 | output "cfe_bucket_external" { 101 | description = "Details of CFE bucket for external tier" 102 | value = aws_s3_bucket.cfe_external_bucket 103 | } 104 | output "cfe_bucket_internal" { 105 | description = "Details of CFE bucket for internal tier" 106 | value = aws_s3_bucket.cfe_internal_bucket 107 | } -------------------------------------------------------------------------------- /sca/jumphosts/jumphost_main.tf: -------------------------------------------------------------------------------- 1 | /* ## F5 Networks Secure Cloud Migration and Securty Zone Template for AWS #################################################################################################################################################################################### 2 | Version 1.4 3 | March 2020 4 | 5 | 6 | This Template is provided as is and without warranty or support. It is intended for demonstration or reference purposes. While all attempts are made to ensure it functions as desired it is not a supported by F5 Networks. This template can be used 7 | to quickly deploy a Security VPC - aka DMZ, in-front of the your application VPC(S). Additional VPCs can be added to the template by adding CIDR variables, VPC resource blocks, VPC specific route tables 8 | and TransitGateway edits. Limits to VPCs that can be added are =to the limits of transit gateway. 9 | 10 | It is built to run in a region with three zones to use and will place services in 1a and 1c. Modifications to other zones can be done. 11 | 12 | F5 Application Services will be deployed into the security VPC but if one wished they could also be deployed inside of the Application VPCs. 13 | 14 | */ 15 | ############################################################################################################################################################################################################################################################### 16 | 17 | resource "aws_security_group" "allow_incoming_jump_host" { 18 | name = "allow_incoming_jump_host" 19 | description = "Allow Jumphost inbound traffic" 20 | vpc_id = var.vpcs.value.security 21 | 22 | ingress { 23 | # TLS (change to whatever ports you need) 24 | from_port = 22 25 | to_port = 22 26 | protocol = "tcp" 27 | # Please restrict your ingress to only necessary IPs and ports. 28 | # Opening to 0.0.0.0/0 can lead to security vulnerabilities. 29 | cidr_blocks = ["${var.my_public_ip}"] 30 | } 31 | ingress { 32 | # RDP (change to whatever ports you need) 33 | from_port = 3389 34 | to_port = 3389 35 | protocol = "tcp" 36 | # Please restrict your ingress to only necessary IPs and ports. 37 | # Opening to 0.0.0.0/0 can lead to security vulnerabilities. 38 | cidr_blocks = ["${var.my_public_ip}"] 39 | } 40 | 41 | egress { 42 | from_port = 0 43 | to_port = 0 44 | protocol = "-1" 45 | cidr_blocks = ["0.0.0.0/0"] 46 | } 47 | } 48 | 49 | # Create a new instance of the latest Ubuntu 14.04 on an 50 | # t2.micro node with an AWS Tag naming it "HelloWorld" 51 | 52 | data "aws_ami" "ubuntu" { 53 | most_recent = true 54 | 55 | filter { 56 | name = "name" 57 | values = ["ubuntu/images/hvm-ssd/ubuntu-*-18.04-amd64-server-*"] 58 | } 59 | 60 | filter { 61 | name = "virtualization-type" 62 | values = ["hvm"] 63 | } 64 | 65 | owners = ["099720109477"] # Canonical 66 | } 67 | 68 | resource "aws_instance" "Jumphost" { 69 | count = 2 70 | ami = data.aws_ami.ubuntu.id 71 | instance_type = "t2.micro" 72 | key_name = var.jump_ssh_key 73 | associate_public_ip_address = true 74 | # subnets should be consolidated into a single variable 75 | subnet_id = element([var.subnets.value.az1.security.mgmt,var.subnets.value.az2.security.mgmt],count.index) 76 | vpc_security_group_ids = [aws_security_group.allow_incoming_jump_host.id] 77 | user_data = <<-EOF 78 | #!/bin/bash 79 | apt update 80 | apt —yes —force-yes install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils 81 | apt —yes —force-yes install xrdp 82 | apt —yes —force-yes install awscli 83 | apt —yes install python 84 | snap install postman 85 | wget https://packages.chef.io/files/stable/inspec/4.18.111/ubuntu/18.04/inspec_4.18.111-1_amd64.deb 86 | sudo dpkg -i ./inspec_4.18.111-1_amd64.deb 87 | rm inspec_4.18.111-1_amd64.deb 88 | EOF 89 | 90 | 91 | tags = { 92 | Name = "${var.project.value}_Jumphost_${count.index}" 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /sca/configuration_stack/templates/declarativeOnboarding/ipsClusterPayg.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/master/src/schema/latest/base.schema.json", 3 | "schemaVersion": "1.11.1", 4 | "class": "Device", 5 | "async": true, 6 | "label": "Ips Cluster PAYG", 7 | "Common": { 8 | "class": "Tenant", 9 | "hostname": "${local_host}.example.com", 10 | "dbvars": { 11 | "class": "DbVariables", 12 | "ui.advisory.enabled": true, 13 | "ui.advisory.color": "green", 14 | "ui.advisory.text": "/Common/hostname" 15 | }, 16 | "myDns": { 17 | "class": "DNS", 18 | "nameServers": [ 19 | "169.254.169.254", 20 | "${dns_server}", 21 | "2001:4860:4860::8844" 22 | ], 23 | "search": [ 24 | "f5.com", 25 | "ec2.internal", 26 | "compute-1.internal" 27 | ] 28 | }, 29 | "myNtp": { 30 | "class": "NTP", 31 | "servers": [ 32 | "${ntp_server}", 33 | "0.pool.ntp.org", 34 | "1.pool.ntp.org" 35 | ], 36 | "timezone": "${timezone}" 37 | }, 38 | "myProvisioning": { 39 | "class": "Provision", 40 | "ltm": "nominal", 41 | "afm": "nominal", 42 | "avr": "nominal" 43 | }, 44 | "dmz-outside": { 45 | "class": "VLAN", 46 | "tag": 4094, 47 | "mtu": 1500, 48 | "interfaces": [ 49 | { 50 | "name": "1.1", 51 | "tagged": false 52 | } 53 | ] 54 | }, 55 | "application-region": { 56 | "class": "VLAN", 57 | "tag": 4093, 58 | "mtu": 1500, 59 | "interfaces": [ 60 | { 61 | "name": "1.2", 62 | "tagged": false 63 | } 64 | ] 65 | }, 66 | "dmz-inside": { 67 | "class": "VLAN", 68 | "tag": 4092, 69 | "mtu": 1500, 70 | "interfaces": [ 71 | { 72 | "name": "1.3", 73 | "tagged": false 74 | } 75 | ] 76 | }, 77 | "dmz-outside-self": { 78 | "class": "SelfIp", 79 | "address": "${local_selfip}/24", 80 | "vlan": "dmz-outside", 81 | "allowService": "none", 82 | "trafficGroup": "traffic-group-local-only" 83 | }, 84 | "application-region-self": { 85 | "class": "SelfIp", 86 | "address": "${local_selfip2}/24", 87 | "vlan": "application-region", 88 | "allowService": "none", 89 | "trafficGroup": "traffic-group-local-only" 90 | }, 91 | "dmz-inside-self": { 92 | "class": "SelfIp", 93 | "address": "${local_selfip3}/24", 94 | "vlan": "dmz-inside", 95 | "allowService": "default", 96 | "trafficGroup": "traffic-group-local-only" 97 | }, 98 | "default": { 99 | "class": "Route", 100 | "gw": "${gateway}", 101 | "network": "default", 102 | "mtu": 1500 103 | }, 104 | "configsync": { 105 | "class": "ConfigSync", 106 | "configsyncIp": "/Common/application-region-self/address" 107 | }, 108 | "failoverAddress": { 109 | "class": "FailoverUnicast", 110 | "address": "/Common/application-region-self/address" 111 | }, 112 | "failoverGroup": { 113 | "class": "DeviceGroup", 114 | "type": "sync-failover", 115 | "members": [ 116 | "${host1}.example.com", 117 | "${host2}.example.com" 118 | ], 119 | "owner": "/Common/failoverGroup/members/0", 120 | "autoSync": true, 121 | "saveOnAutoSync": false, 122 | "networkFailover": true, 123 | "fullLoadOnSync": false 124 | }, 125 | "trust": { 126 | "class": "DeviceTrust", 127 | "localUsername": "${admin_user}", 128 | "localPassword": "${admin_password}", 129 | "remoteHost": "${remote_selfip}", 130 | "remoteUsername": "${admin_user}", 131 | "remotePassword": "${admin_password}" 132 | } 133 | } 134 | } -------------------------------------------------------------------------------- /sca/configuration_stack/templates/declarativeOnboarding/internalClusterPayg.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/master/src/schema/latest/base.schema.json", 3 | "schemaVersion": "1.11.1", 4 | "class": "Device", 5 | "async": true, 6 | "label": "Internal Cluster PAYG", 7 | "Common": { 8 | "class": "Tenant", 9 | "hostname": "${local_host}.example.com", 10 | "dbvars": { 11 | "class": "DbVariables", 12 | "ui.advisory.enabled": true, 13 | "ui.advisory.color": "green", 14 | "ui.advisory.text": "/Common/hostname" 15 | }, 16 | "myDns": { 17 | "class": "DNS", 18 | "nameServers": [ 19 | "169.254.169.254", 20 | "${dns_server}", 21 | "2001:4860:4860::8844" 22 | ], 23 | "search": [ 24 | "f5.com", 25 | "ec2.internal", 26 | "compute-1.internal" 27 | ] 28 | }, 29 | "myNtp": { 30 | "class": "NTP", 31 | "servers": [ 32 | "${ntp_server}", 33 | "0.pool.ntp.org", 34 | "1.pool.ntp.org" 35 | ], 36 | "timezone": "${timezone}" 37 | }, 38 | "myProvisioning": { 39 | "class": "Provision", 40 | "ltm": "nominal", 41 | "asm": "nominal", 42 | "avr": "nominal" 43 | }, 44 | "dmz-outside": { 45 | "class": "VLAN", 46 | "tag": 4094, 47 | "mtu": 1500, 48 | "interfaces": [ 49 | { 50 | "name": "1.1", 51 | "tagged": false 52 | } 53 | ] 54 | }, 55 | "application-region": { 56 | "class": "VLAN", 57 | "tag": 4093, 58 | "mtu": 1500, 59 | "interfaces": [ 60 | { 61 | "name": "1.2", 62 | "tagged": false 63 | } 64 | ] 65 | }, 66 | "peering": { 67 | "class": "VLAN", 68 | "tag": 4092, 69 | "mtu": 1500, 70 | "interfaces": [ 71 | { 72 | "name": "1.3", 73 | "tagged": false 74 | } 75 | ] 76 | }, 77 | "dmz-outside-self": { 78 | "class": "SelfIp", 79 | "address": "${local_selfip}/24", 80 | "vlan": "dmz-outside", 81 | "allowService": "none", 82 | "trafficGroup": "traffic-group-local-only" 83 | }, 84 | "application-region-self": { 85 | "class": "SelfIp", 86 | "address": "${local_selfip2}/24", 87 | "vlan": "application-region", 88 | "allowService": "none", 89 | "trafficGroup": "traffic-group-local-only" 90 | }, 91 | "peering-self": { 92 | "class": "SelfIp", 93 | "address": "${local_selfip3}/24", 94 | "vlan": "peering", 95 | "allowService": "default", 96 | "trafficGroup": "traffic-group-local-only" 97 | }, 98 | "default": { 99 | "class": "Route", 100 | "gw": "${gateway}", 101 | "network": "default", 102 | "mtu": 1500 103 | }, 104 | "configsync": { 105 | "class": "ConfigSync", 106 | "configsyncIp": "/Common/peering-self/address" 107 | }, 108 | "failoverAddress": { 109 | "class": "FailoverUnicast", 110 | "address": "/Common/peering-self/address" 111 | }, 112 | "failoverGroup": { 113 | "class": "DeviceGroup", 114 | "type": "sync-failover", 115 | "members": [ 116 | "${host1}.example.com", 117 | "${host2}.example.com" 118 | ], 119 | "owner": "/Common/failoverGroup/members/0", 120 | "autoSync": true, 121 | "saveOnAutoSync": false, 122 | "networkFailover": true, 123 | "fullLoadOnSync": false, 124 | "asmSync": true 125 | }, 126 | "trust": { 127 | "class": "DeviceTrust", 128 | "localUsername": "${admin_user}", 129 | "localPassword": "${admin_password}", 130 | "remoteHost": "${remote_selfip}", 131 | "remoteUsername": "${admin_user}", 132 | "remotePassword": "${admin_password}" 133 | } 134 | } 135 | } -------------------------------------------------------------------------------- /sca/security_stack/inspec/bigip-atc-ready/controls/atc.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2020, F5 Networks 2 | 3 | title "Automation Toolchain Ready" 4 | 5 | bigip_host = input('bigip_mgmt_ip') 6 | bigip_mgmt_port = input('bigip_mgmt_port', value: 443) 7 | bigip_password = input('bigip_password') 8 | 9 | # 10 | # Test that DO is available and the correct version 11 | # 12 | control "Declarative Onboarding Available" do 13 | impact 1.0 14 | title "BIGIP has DO" 15 | # is the declarative onboarding end point available? 16 | describe http("https://#{bigip_host}:#{bigip_mgmt_port}/mgmt/shared/declarative-onboarding/info", 17 | auth: {user: 'admin', pass: bigip_password}, 18 | params: {format: 'html'}, 19 | method: 'GET', 20 | ssl_verify: false) do 21 | its('status') { should cmp 200 } 22 | its('headers.Content-Type') { should match 'application/json' } 23 | end 24 | describe json(content: http("https://#{bigip_host}:#{bigip_mgmt_port}/mgmt/shared/declarative-onboarding/info", 25 | auth: {user: 'admin', pass: bigip_password}, 26 | params: {format: 'html'}, 27 | method: 'GET', 28 | ssl_verify: false).body) do 29 | its([0,'version']) { should eq '1.12.0' } 30 | its([0,'release']) { should eq '1' } # this should be replaced with a test using the json resource 31 | end 32 | end 33 | 34 | # 35 | # Test that AS3 is available and the correct version 36 | # 37 | control "Application Service Extension Available" do 38 | impact 1.0 39 | title "BIGIP has AS3" 40 | # is the application services end point available? 41 | describe http("https://#{bigip_host}:#{bigip_mgmt_port}/mgmt/shared/appsvcs/info", 42 | auth: {user: 'admin', pass: bigip_password}, 43 | params: {format: 'html'}, 44 | method: 'GET', 45 | ssl_verify: false) do 46 | its('status') { should cmp 200 } 47 | its('headers.Content-Type') { should match 'application/json' } 48 | end 49 | describe json(content: http("https://#{bigip_host}:#{bigip_mgmt_port}/mgmt/shared/appsvcs/info", 50 | auth: {user: 'admin', pass: bigip_password}, 51 | params: {format: 'html'}, 52 | method: 'GET', 53 | ssl_verify: false).body) do 54 | its('version') { should eq '3.13.2' } 55 | its('release') { should eq '1' } # this should be replaced with a test using the json resource 56 | end 57 | end 58 | 59 | # 60 | # Test that CFE is available and the correct version 61 | # 62 | control "Cloud Failover Extension Available" do 63 | impact 1.0 64 | title "BIGIP has CFE" 65 | # is the application services end point available? 66 | describe http("https://#{bigip_host}:#{bigip_mgmt_port}/mgmt/shared/cloud-failover/info", 67 | auth: {user: 'admin', pass: bigip_password}, 68 | params: {format: 'html'}, 69 | method: 'GET', 70 | ssl_verify: false) do 71 | its('status') { should cmp 200 } 72 | its('headers.Content-Type') { should match 'application/json' } 73 | end 74 | describe json(content: http("https://#{bigip_host}:#{bigip_mgmt_port}/mgmt/shared/cloud-failover/info", 75 | auth: {user: 'admin', pass: bigip_password}, 76 | params: {format: 'html'}, 77 | method: 'GET', 78 | ssl_verify: false).body) do 79 | its('version') { should eq '1.2.0' } 80 | its('release') { should eq '0' } # this should be replaced with a test using the json resource 81 | end 82 | end 83 | 84 | # 85 | # Test that TS is available and the correct version 86 | # 87 | control "Telemetry Streaming Available" do 88 | impact 1.0 89 | title "BIGIP has TS" 90 | # is the application services end point available? 91 | describe http("https://#{bigip_host}:#{bigip_mgmt_port}/mgmt/shared/telemetry/info", 92 | auth: {user: 'admin', pass: bigip_password}, 93 | params: {format: 'html'}, 94 | method: 'GET', 95 | ssl_verify: false) do 96 | its('status') { should cmp 200 } 97 | its('headers.Content-Type') { should match 'application/json' } 98 | end 99 | describe json(content: http("https://#{bigip_host}:#{bigip_mgmt_port}/mgmt/shared/telemetry/info", 100 | auth: {user: 'admin', pass: bigip_password}, 101 | params: {format: 'html'}, 102 | method: 'GET', 103 | ssl_verify: false).body) do 104 | its('version') { should eq '1.11.0' } 105 | its('release') { should eq '1' } # this should be replaced with a test using the json resource 106 | end 107 | end -------------------------------------------------------------------------------- /modules/awsInfrastructure/variables.tf: -------------------------------------------------------------------------------- 1 | /* ## F5 Networks Secure Cloud Migration and Securty Zone Template for AWS #################################################################################################################################################################################### 2 | Version 1.4 3 | March 2020 4 | 5 | 6 | This Template is provided as is and without warranty or support. It is intended for demonstration or reference purposes. While all attempts are made to ensure it functions as desired it is not a supported by F5 Networks. This template can be used 7 | to quickly deploy a Security VPC - aka DMZ, in-front of the your application VPC(S). Additional VPCs can be added to the template by adding CIDR variables, VPC resource blocks, VPC specific route tables 8 | and TransitGateway edits. Limits to VPCs that can be added are =to the limits of transit gateway. 9 | 10 | It is built to run in a region with three zones to use and will place services in 1a and 1c. Modifications to other zones can be done. 11 | 12 | F5 Application Services will be deployed into the security VPC but if one wished they could also be deployed inside of the Application VPCs. 13 | 14 | */ 15 | ############################################################################################################################################################################################################################################################### 16 | 17 | ##### AWS Region Variables ################################################################################################################################################################################################################################### 18 | # 19 | # The variables below deine the AWS retion that you will deploy to. The template is desinged for a region with 3 zones, and relies upon the user credentials already in their profile. 20 | # 21 | ############################################################################################################################################################################################################################################################# 22 | 23 | variable "aws_region" { 24 | description = "aws region " 25 | default = "us-west-2" 26 | } 27 | 28 | ##### Tag Variable ####################################################################################################################################################################################################################################### 29 | # 30 | # The field below is used to create the naming for tags for created resrouces. This helps identify the objects that are created by the template. 31 | # 32 | ############################################################################################################################################################################################################################################################ 33 | 34 | variable "project" { 35 | description = "project name to use for tags" 36 | default = "f5-sca-v2" 37 | } 38 | 39 | ##### CIDR Variables ####################################################################################################################################################################################################################################### 40 | # 41 | # The CIDR blocks are used in the VPCs (cidr-number) and are used to restrict access to the environment (cidr-cusotomer-source) 42 | # 43 | ############################################################################################################################################################################################################################################################ 44 | 45 | variable "cidr-1" { 46 | description = "CIDR block for the Security VPC" 47 | } 48 | 49 | variable "cidr-2" { 50 | description = "CIDR block for the Applicaiton VPC" 51 | } 52 | 53 | variable "cidr-3" { 54 | description = "CIDR block for the Container VPC" 55 | } 56 | 57 | variable "cidr-customer-source" { 58 | description = "Allow Access to services from Customer CIDR Range" 59 | default = "0.0.0.0/0" 60 | } 61 | 62 | ##### Region Variables ####################################################################################################################################################################################################################################### 63 | # 64 | # Set the Avaibility Zones that we will use to create our deployment. 65 | # 66 | ############################################################################################################################################################################################################################################################### 67 | 68 | variable "region-az-1" { 69 | description = "This becomes AZ_1" 70 | } 71 | 72 | variable "region-az-2" { 73 | description = "This becomes AZ_2" 74 | } 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /sca/container_stack/main.tf: -------------------------------------------------------------------------------- 1 | /* ## F5 Networks Secure Cloud Migration and Securty Zone Template for AWS #################################################################################################################################################################################### 2 | Version 1.4 3 | March 2020 4 | 5 | 6 | This Template is provided as is and without warranty or support. It is intended for demonstration or reference purposes. While all attempts are made to ensure it functions as desired it is not a supported by F5 Networks. This template can be used 7 | to quickly deploy a Security VPC - aka DMZ, in-front of the your application VPC(S). Additional VPCs can be added to the template by adding CIDR variables, VPC resource blocks, VPC specific route tables 8 | and TransitGateway edits. Limits to VPCs that can be added are =to the limits of transit gateway. 9 | 10 | It is built to run in a region with three zones to use and will place services in 1a and 1c. Modifications to other zones can be done. 11 | 12 | F5 Application Services will be deployed into the security VPC but if one wished they could also be deployed inside of the Application VPCs. 13 | 14 | */ 15 | ############################################################################################################################################################################################################################################################### 16 | #### Deploy Fargate Containers and Service Discovery Service ################################################################################################################################################################################################### 17 | # This stack is for EXAMPLE only and deploys a KNOWN VULNERABLE APPLICATION. DO NOT USE IN ENVIRONMENTS WHERE SECURITY IS A CONCERN!!!!!! 18 | # F5 can control ingress to Faregate services and leverage the DNS Name service to locate the items. Note you will have to decrease the default time on the NODE (not pool) for DNS discovery to work efficiently. You will need to use the DNS name 19 | # juiceshop.my-project.local for your node. 20 | # 21 | # 22 | ################################################################################################################################################################################################################################################################ 23 | 24 | #### Deploy the Service Discovery Security Group ############################################################################################################################################################################################################### 25 | # 26 | # The Security Group permits all Traffic in the event that ingress traffic is not processed by a SNAT 27 | # 28 | ################################################################################################################################################################################################################################################################ 29 | 30 | 31 | resource "aws_security_group" "demo_tasks" { 32 | name = "demo-ecs-tasks" 33 | description = "allow inbound access to Fargate Instances" 34 | vpc_id = var.vpcs.value.container 35 | 36 | ingress { 37 | protocol = "tcp" 38 | from_port = var.app_port 39 | to_port = var.app_port 40 | cidr_blocks = ["0.0.0.0/0"] 41 | } 42 | 43 | egress { 44 | protocol = "-1" 45 | from_port = 0 46 | to_port = 0 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | } 50 | 51 | #### Deploy the Service Discovery Service ###################################################################################################################################################################################################################### 52 | # 53 | # The Service Discvoery Service is placed in the Secuirty VPC to allow the BIG-IP systems to find the IP Endpoints 54 | # 55 | ################################################################################################################################################################################################################################################################ 56 | 57 | 58 | resource "aws_service_discovery_private_dns_namespace" "example" { 59 | name = "my-project.local" 60 | description = "example" 61 | vpc = var.vpcs.value.security 62 | } 63 | 64 | resource "aws_service_discovery_service" "example" { 65 | name = "juiceshop" 66 | 67 | dns_config { 68 | namespace_id = aws_service_discovery_private_dns_namespace.example.id 69 | 70 | dns_records { 71 | ttl = 10 72 | type = "A" 73 | } 74 | 75 | routing_policy = "MULTIVALUE" 76 | } 77 | 78 | health_check_custom_config { 79 | failure_threshold = 1 80 | } 81 | } 82 | 83 | 84 | 85 | resource "aws_ecs_cluster" "example-ecs-cluster" { 86 | name = "example-ecs-cluster" 87 | } 88 | 89 | resource "aws_ecs_task_definition" "app" { 90 | family = "example" 91 | network_mode = "awsvpc" 92 | requires_compatibilities = ["FARGATE"] 93 | cpu = 256 94 | memory = 512 95 | container_definitions = jsonencode([{ 96 | name = "TEST" 97 | image = var.app_image 98 | portMappings = [{ 99 | protocol = "tcp" 100 | containerPort = var.app_port 101 | hostPort = var.app_port 102 | }], 103 | }]) 104 | } 105 | 106 | resource "aws_ecs_service" "main" { 107 | name = "example-ecs-service" 108 | cluster = aws_ecs_cluster.example-ecs-cluster.id 109 | task_definition = aws_ecs_task_definition.app.arn 110 | desired_count = var.app_count 111 | launch_type = "FARGATE" 112 | 113 | network_configuration { 114 | security_groups = ["${aws_security_group.demo_tasks.id}"] 115 | subnets = [var.subnets.value.az1.container.dmz_1, var.subnets.value.az2.container.dmz_1] 116 | } 117 | 118 | service_registries { 119 | registry_arn = aws_service_discovery_service.example.arn 120 | } 121 | } 122 | 123 | -------------------------------------------------------------------------------- /sca/configuration_stack/cloudFailoverExtension.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | ext_self_ip_extNic_az1 = flatten([ 3 | for environment, bigips in var.bigip_map.value : [ 4 | for key, bigip in bigips : { 5 | id : key 6 | subnets : { 7 | for subnet, data in bigip : data.attachment[0].device_index => { 8 | private_ip : data.private_ip 9 | } 10 | } 11 | } 12 | ] if(environment == "external_az1") 13 | ]) 14 | ext_self_ip_extNic_az2 = flatten([ 15 | for environment, bigips in var.bigip_map.value : [ 16 | for key, bigip in bigips : { 17 | id : key 18 | subnets : { 19 | for subnet, data in bigip : data.attachment[0].device_index => { 20 | private_ip : data.private_ip 21 | } 22 | } 23 | } 24 | ] if(environment == "external_az2") 25 | ]) 26 | int_self_ip_intNic_az1 = flatten([ 27 | for environment, bigips in var.bigip_map.value : [ 28 | for key, bigip in bigips : { 29 | id : key 30 | subnets : { 31 | for subnet, data in bigip : data.attachment[0].device_index => { 32 | private_ip : data.private_ip 33 | } 34 | } 35 | } 36 | ] if(environment == "internal_az1") 37 | ]) 38 | int_self_ip_intNic_az2 = flatten([ 39 | for environment, bigips in var.bigip_map.value : [ 40 | for key, bigip in bigips : { 41 | id : key 42 | subnets : { 43 | for subnet, data in bigip : data.attachment[0].device_index => { 44 | private_ip : data.private_ip 45 | } 46 | } 47 | } 48 | ] if(environment == "internal_az2") 49 | ]) 50 | } 51 | 52 | # Template files for CFE declarations 53 | data "template_file" "cfe_declaration_ext_tier" { 54 | template = file("${path.module}/templates/cloudFailoverExtension/cfe.json") 55 | 56 | vars = { 57 | label = var.cfe_bucket_external.value.tags.f5_cloud_failover_label 58 | labelRouteTable = var.CFE_route_tables.value.internet 59 | range = "192.168.100.0/24" 60 | local_selfip = local.ext_self_ip_extNic_az1[0].subnets[1].private_ip 61 | remote_selfip = local.ext_self_ip_extNic_az2[0].subnets[1].private_ip 62 | } 63 | } 64 | data "template_file" "cfe_declaration_int_tier" { 65 | template = file("${path.module}/templates/cloudFailoverExtension/cfe.json") 66 | 67 | vars = { 68 | label = var.cfe_bucket_internal.value.tags.f5_cloud_failover_label 69 | labelRouteTable = var.CFE_route_tables.value.internal 70 | range = "0.0.0.0/0" 71 | local_selfip = local.int_self_ip_intNic_az1[0].subnets[3].private_ip 72 | remote_selfip = local.int_self_ip_intNic_az2[0].subnets[3].private_ip 73 | } 74 | } 75 | 76 | resource "local_file" "ext_cfe_json" { 77 | content = data.template_file.cfe_declaration_ext_tier.rendered 78 | filename = "${path.module}/ext_cfe_json.json" 79 | } 80 | resource "local_file" "int_cfe_json" { 81 | content = data.template_file.cfe_declaration_int_tier.rendered 82 | filename = "${path.module}/int_cfe_json.json" 83 | } 84 | 85 | resource "null_resource" "cfe-external-az1" { 86 | depends_on = [ 87 | bigip_do.external_bigip_az1, 88 | bigip_do.external_bigip_az2 89 | ] 90 | # Running CFE REST API 91 | provisioner "local-exec" { 92 | command = <<-EOF 93 | #!/bin/bash 94 | sleep 15 95 | curl -k -X GET https://${var.bigip_mgmt_ips.value.external_az1[0]}/mgmt/shared/cloud-failover/info -u admin:${data.aws_secretsmanager_secret_version.secret.secret_string} 96 | sleep 10 97 | curl -k -X POST https://${var.bigip_mgmt_ips.value.external_az1[0]}/mgmt/shared/cloud-failover/declare -u admin:${data.aws_secretsmanager_secret_version.secret.secret_string} -d @${path.module}/ext_cfe_json.json 98 | EOF 99 | } 100 | } 101 | 102 | resource "null_resource" "cfe-external-az2" { 103 | depends_on = [ 104 | bigip_do.external_bigip_az1, 105 | bigip_do.external_bigip_az2 106 | ] 107 | # Running CFE REST API 108 | provisioner "local-exec" { 109 | command = <<-EOF 110 | #!/bin/bash 111 | sleep 15 112 | curl -k -X GET https://${var.bigip_mgmt_ips.value.external_az2[0]}/mgmt/shared/cloud-failover/info -u admin:${data.aws_secretsmanager_secret_version.secret.secret_string} 113 | sleep 10 114 | curl -k -X POST https://${var.bigip_mgmt_ips.value.external_az2[0]}/mgmt/shared/cloud-failover/declare -u admin:${data.aws_secretsmanager_secret_version.secret.secret_string} -d @${path.module}/ext_cfe_json.json 115 | EOF 116 | } 117 | } 118 | 119 | resource "null_resource" "cfe-internal-az1" { 120 | depends_on = [ 121 | bigip_do.internal_bigip_az1, 122 | bigip_do.internal_bigip_az2 123 | ] 124 | # Running CFE REST API 125 | provisioner "local-exec" { 126 | command = <<-EOF 127 | #!/bin/bash 128 | sleep 15 129 | curl -k -X GET https://${var.bigip_mgmt_ips.value.internal_az1[0]}/mgmt/shared/cloud-failover/info -u admin:${data.aws_secretsmanager_secret_version.secret.secret_string} 130 | sleep 10 131 | curl -k -X POST https://${var.bigip_mgmt_ips.value.internal_az1[0]}/mgmt/shared/cloud-failover/declare -u admin:${data.aws_secretsmanager_secret_version.secret.secret_string} -d @${path.module}/int_cfe_json.json 132 | sleep 25 133 | EOF 134 | } 135 | } 136 | 137 | resource "null_resource" "cfe-internal-az2" { 138 | depends_on = [ 139 | bigip_do.internal_bigip_az1, 140 | bigip_do.internal_bigip_az2 141 | ] 142 | # Running CFE REST API 143 | provisioner "local-exec" { 144 | command = <<-EOF 145 | #!/bin/bash 146 | sleep 15 147 | curl -k -X GET https://${var.bigip_mgmt_ips.value.internal_az2[0]}/mgmt/shared/cloud-failover/info -u admin:${data.aws_secretsmanager_secret_version.secret.secret_string} 148 | sleep 10 149 | curl -k -X POST https://${var.bigip_mgmt_ips.value.internal_az2[0]}/mgmt/shared/cloud-failover/declare -u admin:${data.aws_secretsmanager_secret_version.secret.secret_string} -d @${path.module}/int_cfe_json.json 150 | sleep 25 151 | EOF 152 | } 153 | } -------------------------------------------------------------------------------- /sca/security_stack/ips.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | ips_bigip_map_az1 = { 3 | "0" = { 4 | "network_interfaces" = { 5 | "us-west-1a:management:0" = { 6 | "device_index" = "0" 7 | "interface_type" = "management" 8 | "private_ips_count" = 0 9 | "public_ip" = true 10 | "subnet_id" = var.subnets.value.az1.security.mgmt 11 | "subnet_security_group_ids" = [ 12 | var.security_groups.value.management 13 | ] 14 | } 15 | "us-west-1a:public:0" = { 16 | "device_index" = "1" 17 | "interface_type" = "private" 18 | "private_ips_count" = 0 19 | "public_ip" = false 20 | "subnet_id" = var.subnets.value.az1.security.dmz_outside 21 | "subnet_security_group_ids" = [ 22 | var.security_groups.value.public 23 | ] 24 | } 25 | "us-west-1a:private:0" = { 26 | "device_index" = "2" 27 | "interface_type" = "private" 28 | "private_ips_count" = 0 29 | "public_ip" = false 30 | "subnet_id" = var.subnets.value.az1.security.application_region 31 | "subnet_security_group_ids" = [ 32 | var.security_groups.value.private 33 | ] 34 | } 35 | "us-west-1a:private:1" = { 36 | "device_index" = "3" 37 | "interface_type" = "private" 38 | "private_ips_count" = 0 39 | "public_ip" = false 40 | "subnet_id" = var.subnets.value.az1.security.dmz_inside 41 | "subnet_security_group_ids" = [ 42 | var.security_groups.value.private 43 | ] 44 | } 45 | } 46 | } 47 | } 48 | } 49 | locals { 50 | ips_bigip_map_az2 = { 51 | "0" = { 52 | "network_interfaces" = { 53 | "us-west-1b:management:0" = { 54 | "device_index" = "0" 55 | "interface_type" = "management" 56 | "private_ips_count" = 0 57 | "public_ip" = true 58 | "subnet_id" = var.subnets.value.az2.security.mgmt 59 | "subnet_security_group_ids" = [ 60 | var.security_groups.value.management 61 | ] 62 | } 63 | "us-west-1b:public:0" = { 64 | "device_index" = "1" 65 | "interface_type" = "private" 66 | "private_ips_count" = 0 67 | "public_ip" = false 68 | "subnet_id" = var.subnets.value.az2.security.dmz_outside 69 | "subnet_security_group_ids" = [ 70 | var.security_groups.value.public 71 | ] 72 | } 73 | "us-west-1b:private:0" = { 74 | "device_index" = "2" 75 | "interface_type" = "private" 76 | "private_ips_count" = 0 77 | "public_ip" = false 78 | "subnet_id" = var.subnets.value.az2.security.application_region 79 | "subnet_security_group_ids" = [ 80 | var.security_groups.value.private 81 | ] 82 | } 83 | "us-west-1b:private:1" = { 84 | "device_index" = "3" 85 | "interface_type" = "private" 86 | "private_ips_count" = 0 87 | "public_ip" = false 88 | "subnet_id" = var.subnets.value.az2.security.dmz_inside 89 | "subnet_security_group_ids" = [ 90 | var.security_groups.value.private 91 | ] 92 | } 93 | } 94 | } 95 | } 96 | } 97 | # Setup Onboarding scripts 98 | data "template_file" "ips_onboard_az1" { 99 | template = "${file("${path.root}/templates/bigip_onboard.tmpl")}" 100 | 101 | vars = { 102 | #uname = var.adminAccountName 103 | # atc versions 104 | #example version: 105 | #as3Version = "3.16.0" 106 | doVersion = var.atc_versions.doVersion 107 | as3Version = var.atc_versions.as3Version 108 | tsVersion = var.atc_versions.tsVersion 109 | cfVersion = var.atc_versions.cfVersion 110 | fastVersion = var.atc_versions.fastVersion 111 | onboard_log = "/var/log/startup-script.log" 112 | secret_id = var.secrets_manager_name.value 113 | # gateways 114 | applicationGateway = var.aws_cidr_ips.value.az1.security.application_region 115 | #dmzInsideGateway = var.aws_cidr_ips.value.az1.security.dmz_inside 116 | dmzOutsideGateway = var.aws_cidr_ips.value.az1.security.dmz_inside 117 | #egressCh1Gateway = var.aws_cidr_ips.value.az1.security.egress_to_ch1 118 | #egressCh2Gateway = var.aws_cidr_ips.value.az1.security.egress_to_ch2 119 | #internalGateway = var.aws_cidr_ips.value.az1.security.internal 120 | externalGateway = var.aws_cidr_ips.value.az1.security.application_region 121 | #mgmtGateway = var.aws_cidr_ips.value.az1.security.mgmt 122 | #peeringGateway = var.aws_cidr_ips.value.az1.security.peering 123 | # networks 124 | applicationNetwork = var.subnet_cidrs.value.az1.security.application_region 125 | #dmzInsideNetwork = var.subnet_cidrs.value.az1.security.dmz_inside 126 | dmzOutsideNetwork = var.subnet_cidrs.value.az1.security.dmz_inside 127 | #egressCh1Network = var.subnet_cidrs.value.az1.security.egress_to_ch1 128 | #egressCh2Network = var.subnet_cidrs.value.az1.security.egress_to_ch2 129 | #internalNetwork = var.subnet_cidrs.value.az1.security.internal 130 | externalNetwork = var.subnet_cidrs.value.az1.security.dmz_outside 131 | #mgmtNetwork = var.subnet_cidrs.value.az1.security.mgmt 132 | #peeringNetwork = var.subnet_cidrs.value.az1.security.peering 133 | # sync must be other az 134 | syncNetwork = var.subnet_cidrs.value.az2.security.application_region 135 | } 136 | } 137 | data "template_file" "ips_onboard_az2" { 138 | template = "${file("${path.root}/templates/bigip_onboard.tmpl")}" 139 | 140 | vars = { 141 | #uname = var.adminAccountName 142 | # atc versions 143 | #example version: 144 | #as3Version = "3.16.0" 145 | doVersion = var.atc_versions.doVersion 146 | as3Version = var.atc_versions.as3Version 147 | tsVersion = var.atc_versions.tsVersion 148 | cfVersion = var.atc_versions.cfVersion 149 | fastVersion = var.atc_versions.fastVersion 150 | onboard_log = "/var/log/startup-script.log" 151 | secret_id = var.secrets_manager_name.value 152 | # gateways 153 | applicationGateway = var.aws_cidr_ips.value.az2.security.application_region 154 | #dmzInsideGateway = var.aws_cidr_ips.value.az2.security.dmz_inside 155 | dmzOutsideGateway = var.aws_cidr_ips.value.az2.security.dmz_inside 156 | #egressCh1Gateway = var.aws_cidr_ips.value.az2.security.egress_to_ch1 157 | #egressCh2Gateway = var.aws_cidr_ips.value.az2.security.egress_to_ch2 158 | #internalGateway = var.aws_cidr_ips.value.az2.security.internal 159 | externalGateway = var.aws_cidr_ips.value.az2.security.application_region 160 | #mgmtGateway = var.aws_cidr_ips.value.az2.security.mgmt 161 | #peeringGateway = var.aws_cidr_ips.value.az2.security.peering 162 | # networks 163 | applicationNetwork = var.subnet_cidrs.value.az2.security.application_region 164 | #dmzInsideNetwork = var.subnet_cidrs.value.az2.security.dmz_inside 165 | dmzOutsideNetwork = var.subnet_cidrs.value.az2.security.dmz_inside 166 | #egressCh1Network = var.subnet_cidrs.value.az2.security.egress_to_ch1 167 | #egressCh2Network = var.subnet_cidrs.value.az2.security.egress_to_ch2 168 | #internalNetwork = var.subnet_cidrs.value.az2.security.internal 169 | externalNetwork = var.subnet_cidrs.value.az2.security.dmz_outside 170 | #mgmtNetwork = var.subnet_cidrs.value.az2.security.mgmt 171 | #peeringNetwork = var.subnet_cidrs.value.az2.security.peering 172 | # sync must be other az 173 | syncNetwork = var.subnet_cidrs.value.az1.security.application_region 174 | } 175 | } 176 | # 177 | # Create BIG-IP 178 | # 179 | module ips_az1 { 180 | source = "github.com/f5devcentral/terraform-aws-bigip?ref=develop" 181 | 182 | prefix = format( 183 | "%s-bigip_with_new_vpc_ips-%s", 184 | var.project.value, 185 | var.random_id.value 186 | ) 187 | ec2_instance_type = var.ec2_instance_type 188 | ec2_key_name = var.ec2_key_name 189 | aws_secretmanager_secret_id = var.secrets_manager_name.value 190 | bigip_map = local.ips_bigip_map_az1 191 | iam_instance_profile = var.iam_instance_profile_name.value 192 | custom_user_data = data.template_file.ips_onboard_az1.rendered 193 | } 194 | module ips_az2 { 195 | source = "github.com/f5devcentral/terraform-aws-bigip?ref=develop" 196 | 197 | prefix = format( 198 | "%s-bigip_with_new_vpc_ips-%s", 199 | var.project.value, 200 | var.random_id.value 201 | ) 202 | ec2_instance_type = var.ec2_instance_type 203 | ec2_key_name = var.ec2_key_name 204 | aws_secretmanager_secret_id = var.secrets_manager_name.value 205 | bigip_map = local.ips_bigip_map_az2 206 | iam_instance_profile = var.iam_instance_profile_name.value 207 | custom_user_data = data.template_file.ips_onboard_az2.rendered 208 | } 209 | -------------------------------------------------------------------------------- /sca/security_stack/internal.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | internal_bigip_map_az1 = { 3 | "0" = { 4 | "network_interfaces" = { 5 | "us-west-1a:management:0" = { 6 | "device_index" = "0" 7 | "interface_type" = "management" 8 | "private_ips_count" = 0 9 | "public_ip" = true 10 | "subnet_id" = var.subnets.value.az1.security.mgmt 11 | "subnet_security_group_ids" = [ 12 | var.security_groups.value.management 13 | ] 14 | } 15 | "us-west-1a:public:0" = { 16 | "device_index" = "1" 17 | "interface_type" = "private" 18 | "private_ips_count" = 0 19 | "public_ip" = false 20 | "subnet_id" = var.subnets.value.az1.security.dmz_inside 21 | "subnet_security_group_ids" = [ 22 | var.security_groups.value.public 23 | ] 24 | } 25 | "us-west-1a:private:0" = { 26 | "device_index" = "2" 27 | "interface_type" = "private" 28 | "private_ips_count" = 0 29 | "public_ip" = false 30 | "subnet_id" = var.subnets.value.az1.security.application_region 31 | "subnet_security_group_ids" = [ 32 | var.security_groups.value.private 33 | ] 34 | } 35 | "us-west-1a:private:1" = { 36 | "device_index" = "3" 37 | "interface_type" = "private" 38 | "private_ips_count" = 0 39 | "public_ip" = false 40 | "subnet_id" = var.subnets.value.az1.security.internal 41 | "subnet_security_group_ids" = [ 42 | var.security_groups.value.private 43 | ] 44 | } 45 | } 46 | } 47 | } 48 | } 49 | locals { 50 | internal_bigip_map_az2 = { 51 | "0" = { 52 | "network_interfaces" = { 53 | "us-west-1b:management:0" = { 54 | "device_index" = "0" 55 | "interface_type" = "management" 56 | "private_ips_count" = 0 57 | "public_ip" = true 58 | "subnet_id" = var.subnets.value.az2.security.mgmt 59 | "subnet_security_group_ids" = [ 60 | var.security_groups.value.management 61 | ] 62 | } 63 | "us-west-1b:public:0" = { 64 | "device_index" = "1" 65 | "interface_type" = "private" 66 | "private_ips_count" = 0 67 | "public_ip" = false 68 | "subnet_id" = var.subnets.value.az2.security.dmz_inside 69 | "subnet_security_group_ids" = [ 70 | var.security_groups.value.public 71 | ] 72 | } 73 | "us-west-1b:private:0" = { 74 | "device_index" = "2" 75 | "interface_type" = "private" 76 | "private_ips_count" = 0 77 | "public_ip" = false 78 | "subnet_id" = var.subnets.value.az2.security.application_region 79 | "subnet_security_group_ids" = [ 80 | var.security_groups.value.private 81 | ] 82 | } 83 | "us-west-1b:private:1" = { 84 | "device_index" = "3" 85 | "interface_type" = "private" 86 | "private_ips_count" = 0 87 | "public_ip" = false 88 | "subnet_id" = var.subnets.value.az2.security.internal 89 | "subnet_security_group_ids" = [ 90 | var.security_groups.value.private 91 | ] 92 | } 93 | } 94 | } 95 | } 96 | } 97 | # Setup Onboarding scripts 98 | data "template_file" "internal_onboard_az1" { 99 | template = "${file("${path.root}/templates/bigip_onboard.tmpl")}" 100 | 101 | vars = { 102 | #uname = var.adminAccountName 103 | # atc versions 104 | #example version: 105 | #as3Version = "3.16.0" 106 | doVersion = var.atc_versions.doVersion 107 | as3Version = var.atc_versions.as3Version 108 | tsVersion = var.atc_versions.tsVersion 109 | cfVersion = var.atc_versions.cfVersion 110 | fastVersion = var.atc_versions.fastVersion 111 | onboard_log = "/var/log/startup-script.log" 112 | secret_id = var.secrets_manager_name.value 113 | # gateways 114 | applicationGateway = var.aws_cidr_ips.value.az1.security.application_region 115 | #dmzInsideGateway = var.aws_cidr_ips.value.az1.security.dmz_inside 116 | dmzOutsideGateway = var.aws_cidr_ips.value.az1.security.internal 117 | #egressCh1Gateway = var.aws_cidr_ips.value.az1.security.egress_to_ch1 118 | #egressCh2Gateway = var.aws_cidr_ips.value.az1.security.egress_to_ch2 119 | #internalGateway = var.aws_cidr_ips.value.az1.security.internal 120 | externalGateway = var.aws_cidr_ips.value.az1.security.application_region 121 | #mgmtGateway = var.aws_cidr_ips.value.az1.security.mgmt 122 | #peeringGateway = var.aws_cidr_ips.value.az1.security.peering 123 | # networks 124 | applicationNetwork = var.subnet_cidrs.value.az1.security.application_region 125 | #dmzInsideNetwork = var.subnet_cidrs.value.az1.security.dmz_inside 126 | dmzOutsideNetwork = var.subnet_cidrs.value.az1.security.internal 127 | #egressCh1Network = var.subnet_cidrs.value.az1.security.egress_to_ch1 128 | #egressCh2Network = var.subnet_cidrs.value.az1.security.egress_to_ch2 129 | #internalNetwork = var.subnet_cidrs.value.az1.security.internal 130 | externalNetwork = var.subnet_cidrs.value.az1.security.dmz_inside 131 | #mgmtNetwork = var.subnet_cidrs.value.az1.security.mgmt 132 | #peeringNetwork = var.subnet_cidrs.value.az1.security.peering 133 | # sync must be other az 134 | syncNetwork = var.subnet_cidrs.value.az2.security.application_region 135 | } 136 | } 137 | data "template_file" "internal_onboard_az2" { 138 | template = "${file("${path.root}/templates/bigip_onboard.tmpl")}" 139 | 140 | vars = { 141 | #uname = var.adminAccountName 142 | # atc versions 143 | #example version: 144 | #as3Version = "3.16.0" 145 | doVersion = var.atc_versions.doVersion 146 | as3Version = var.atc_versions.as3Version 147 | tsVersion = var.atc_versions.tsVersion 148 | cfVersion = var.atc_versions.cfVersion 149 | fastVersion = var.atc_versions.fastVersion 150 | onboard_log = "/var/log/startup-script.log" 151 | secret_id = var.secrets_manager_name.value 152 | # gateways 153 | applicationGateway = var.aws_cidr_ips.value.az2.security.application_region 154 | #dmzInsideGateway = var.aws_cidr_ips.value.az2.security.dmz_inside 155 | dmzOutsideGateway = var.aws_cidr_ips.value.az2.security.internal 156 | #egressCh1Gateway = var.aws_cidr_ips.value.az2.security.egress_to_ch1 157 | #egressCh2Gateway = var.aws_cidr_ips.value.az2.security.egress_to_ch2 158 | #internalGateway = var.aws_cidr_ips.value.az2.security.internal 159 | externalGateway = var.aws_cidr_ips.value.az2.security.application_region 160 | #mgmtGateway = var.aws_cidr_ips.value.az2.security.mgmt 161 | #peeringGateway = var.aws_cidr_ips.value.az2.security.peering 162 | # networks 163 | applicationNetwork = var.subnet_cidrs.value.az2.security.application_region 164 | #dmzInsideNetwork = var.subnet_cidrs.value.az2.security.dmz_inside 165 | dmzOutsideNetwork = var.subnet_cidrs.value.az2.security.internal 166 | #egressCh1Network = var.subnet_cidrs.value.az2.security.egress_to_ch1 167 | #egressCh2Network = var.subnet_cidrs.value.az2.security.egress_to_ch2 168 | #internalNetwork = var.subnet_cidrs.value.az2.security.internal 169 | externalNetwork = var.subnet_cidrs.value.az2.security.dmz_inside 170 | #mgmtNetwork = var.subnet_cidrs.value.az2.security.mgmt 171 | #peeringNetwork = var.subnet_cidrs.value.az2.security.peering 172 | # sync must be other az 173 | syncNetwork = var.subnet_cidrs.value.az1.security.application_region 174 | } 175 | } 176 | # 177 | # Create BIG-IP 178 | # 179 | module internal_az1 { 180 | source = "github.com/f5devcentral/terraform-aws-bigip?ref=develop" 181 | 182 | prefix = format( 183 | "%s-bigip_with_new_vpc_internal-%s", 184 | var.project.value, 185 | var.random_id.value 186 | ) 187 | ec2_instance_type = var.ec2_instance_type 188 | ec2_key_name = var.ec2_key_name 189 | aws_secretmanager_secret_id = var.secrets_manager_name.value 190 | bigip_map = local.internal_bigip_map_az1 191 | iam_instance_profile = var.iam_instance_profile_name.value 192 | custom_user_data = data.template_file.internal_onboard_az1.rendered 193 | } 194 | 195 | module internal_az2 { 196 | source = "github.com/f5devcentral/terraform-aws-bigip?ref=develop" 197 | 198 | prefix = format( 199 | "%s-bigip_with_new_vpc_internal-%s", 200 | var.project.value, 201 | var.random_id.value 202 | ) 203 | ec2_instance_type = var.ec2_instance_type 204 | ec2_key_name = var.ec2_key_name 205 | aws_secretmanager_secret_id = var.secrets_manager_name.value 206 | bigip_map = local.internal_bigip_map_az2 207 | iam_instance_profile = var.iam_instance_profile_name.value 208 | custom_user_data = data.template_file.internal_onboard_az2.rendered 209 | } 210 | -------------------------------------------------------------------------------- /sca/security_stack/external.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | external_bigip_map_az1 = { 3 | "0" = { 4 | "network_interfaces" = { 5 | "us-west-1a:management:0" = { 6 | "device_index" = "0" 7 | "interface_type" = "management" 8 | "private_ips_count" = 0 9 | "public_ip" = true 10 | "subnet_id" = var.subnets.value.az1.security.mgmt 11 | "subnet_security_group_ids" = [ 12 | var.security_groups.value.management 13 | ] 14 | } 15 | "us-west-1a:public:0" = { 16 | "device_index" = "1" 17 | "interface_type" = "public" 18 | "private_ips_count" = 0 19 | "public_ip" = true 20 | "subnet_id" = var.subnets.value.az1.security.internet 21 | "subnet_security_group_ids" = [ 22 | var.security_groups.value.public 23 | ] 24 | } 25 | "us-west-1a:private:0" = { 26 | "device_index" = "2" 27 | "interface_type" = "private" 28 | "private_ips_count" = 0 29 | "public_ip" = false 30 | "subnet_id" = var.subnets.value.az1.security.application_region 31 | "subnet_security_group_ids" = [ 32 | var.security_groups.value.private 33 | ] 34 | } 35 | "us-west-1a:private:1" = { 36 | "device_index" = "3" 37 | "interface_type" = "private" 38 | "private_ips_count" = 0 39 | "public_ip" = false 40 | "subnet_id" = var.subnets.value.az1.security.dmz_outside 41 | "subnet_security_group_ids" = [ 42 | var.security_groups.value.private 43 | ] 44 | } 45 | } 46 | } 47 | } 48 | } 49 | locals { 50 | external_bigip_map_az2 = { 51 | "0" = { 52 | "network_interfaces" = { 53 | "us-west-1b:management:0" = { 54 | "device_index" = "0" 55 | "interface_type" = "management" 56 | "private_ips_count" = 0 57 | "public_ip" = true 58 | "subnet_id" = var.subnets.value.az2.security.mgmt 59 | "subnet_security_group_ids" = [ 60 | var.security_groups.value.management 61 | ] 62 | } 63 | "us-west-1b:public:0" = { 64 | "device_index" = "1" 65 | "interface_type" = "public" 66 | "private_ips_count" = 0 67 | "public_ip" = true 68 | "subnet_id" = var.subnets.value.az2.security.internet 69 | "subnet_security_group_ids" = [ 70 | var.security_groups.value.public 71 | ] 72 | } 73 | "us-west-1b:private:0" = { 74 | "device_index" = "2" 75 | "interface_type" = "private" 76 | "private_ips_count" = 0 77 | "public_ip" = false 78 | "subnet_id" = var.subnets.value.az2.security.application_region 79 | "subnet_security_group_ids" = [ 80 | var.security_groups.value.private 81 | ] 82 | } 83 | "us-west-1b:private:1" = { 84 | "device_index" = "3" 85 | "interface_type" = "private" 86 | "private_ips_count" = 0 87 | "public_ip" = false 88 | "subnet_id" = var.subnets.value.az2.security.dmz_outside 89 | "subnet_security_group_ids" = [ 90 | var.security_groups.value.private 91 | ] 92 | } 93 | } 94 | } 95 | } 96 | } 97 | # Setup Onboarding scripts 98 | data "template_file" "external_onboard_az1" { 99 | template = "${file("${path.root}/templates/bigip_onboard.tmpl")}" 100 | 101 | vars = { 102 | #uname = var.adminAccountName 103 | # atc versions 104 | #example version: 105 | #as3Version = "3.16.0" 106 | doVersion = var.atc_versions.doVersion 107 | as3Version = var.atc_versions.as3Version 108 | tsVersion = var.atc_versions.tsVersion 109 | cfVersion = var.atc_versions.cfVersion 110 | fastVersion = var.atc_versions.fastVersion 111 | onboard_log = "/var/log/startup-script.log" 112 | secret_id = var.secrets_manager_name.value 113 | # gateways 114 | applicationGateway = var.aws_cidr_ips.value.az1.security.application_region 115 | dmzInsideGateway = var.aws_cidr_ips.value.az1.security.dmz_inside 116 | dmzOutsideGateway = var.aws_cidr_ips.value.az1.security.dmz_outside 117 | egressCh1Gateway = var.aws_cidr_ips.value.az1.security.egress_to_ch1 118 | egressCh2Gateway = var.aws_cidr_ips.value.az1.security.egress_to_ch2 119 | internalGateway = var.aws_cidr_ips.value.az1.security.internal 120 | externalGateway = var.aws_cidr_ips.value.az1.security.internet 121 | mgmtGateway = var.aws_cidr_ips.value.az1.security.mgmt 122 | peeringGateway = var.aws_cidr_ips.value.az1.security.peering 123 | # networks 124 | applicationNetwork = var.subnet_cidrs.value.az1.security.application_region 125 | dmzInsideNetwork = var.subnet_cidrs.value.az1.security.dmz_inside 126 | dmzOutsideNetwork = var.subnet_cidrs.value.az1.security.dmz_outside 127 | egressCh1Network = var.subnet_cidrs.value.az1.security.egress_to_ch1 128 | egressCh2Network = var.subnet_cidrs.value.az1.security.egress_to_ch2 129 | internalNetwork = var.subnet_cidrs.value.az1.security.internal 130 | externalNetwork = var.subnet_cidrs.value.az1.security.internet 131 | mgmtNetwork = var.subnet_cidrs.value.az1.security.mgmt 132 | peeringNetwork = var.subnet_cidrs.value.az1.security.peering 133 | # sync must be other az 134 | syncNetwork = var.subnet_cidrs.value.az2.security.application_region 135 | } 136 | } 137 | data "template_file" "external_onboard_az2" { 138 | # Error: expected length of user_data to be in the range (0 - 16384), got #!/bin/bash 139 | template = "${file("${path.root}/templates/bigip_onboard.tmpl")}" 140 | 141 | vars = { 142 | #uname = var.adminAccountName 143 | # atc versions 144 | #example version: 145 | #as3Version = "3.16.0" 146 | doVersion = var.atc_versions.doVersion 147 | as3Version = var.atc_versions.as3Version 148 | tsVersion = var.atc_versions.tsVersion 149 | cfVersion = var.atc_versions.cfVersion 150 | fastVersion = var.atc_versions.fastVersion 151 | onboard_log = "/var/log/startup-script.log" 152 | secret_id = var.secrets_manager_name.value 153 | # gateways 154 | applicationGateway = var.aws_cidr_ips.value.az2.security.application_region 155 | dmzInsideGateway = var.aws_cidr_ips.value.az2.security.dmz_inside 156 | dmzOutsideGateway = var.aws_cidr_ips.value.az2.security.dmz_outside 157 | egressCh1Gateway = var.aws_cidr_ips.value.az2.security.egress_to_ch1 158 | egressCh2Gateway = var.aws_cidr_ips.value.az2.security.egress_to_ch2 159 | internalGateway = var.aws_cidr_ips.value.az2.security.internal 160 | externalGateway = var.aws_cidr_ips.value.az2.security.internet 161 | mgmtGateway = var.aws_cidr_ips.value.az2.security.mgmt 162 | peeringGateway = var.aws_cidr_ips.value.az2.security.peering 163 | # networks 164 | applicationNetwork = var.subnet_cidrs.value.az2.security.application_region 165 | dmzInsideNetwork = var.subnet_cidrs.value.az2.security.dmz_inside 166 | dmzOutsideNetwork = var.subnet_cidrs.value.az2.security.dmz_outside 167 | egressCh1Network = var.subnet_cidrs.value.az2.security.egress_to_ch1 168 | egressCh2Network = var.subnet_cidrs.value.az2.security.egress_to_ch2 169 | internalNetwork = var.subnet_cidrs.value.az2.security.internal 170 | externalNetwork = var.subnet_cidrs.value.az2.security.internet 171 | mgmtNetwork = var.subnet_cidrs.value.az2.security.mgmt 172 | peeringNetwork = var.subnet_cidrs.value.az2.security.peering 173 | # sync must be other az 174 | syncNetwork = var.subnet_cidrs.value.az1.security.application_region 175 | } 176 | } 177 | # 178 | # Create BIG-IP 179 | # 180 | module external_az1 { 181 | source = "github.com/f5devcentral/terraform-aws-bigip?ref=develop" 182 | 183 | prefix = format( 184 | "%s-bigip_with_new_vpc_external-%s", 185 | var.project.value, 186 | var.random_id.value 187 | ) 188 | ec2_instance_type = var.ec2_instance_type 189 | ec2_key_name = var.ec2_key_name 190 | aws_secretmanager_secret_id = var.secrets_manager_name.value 191 | bigip_map = local.external_bigip_map_az1 192 | iam_instance_profile = var.iam_instance_profile_name.value 193 | custom_user_data = data.template_file.external_onboard_az1.rendered 194 | } 195 | module external_az2 { 196 | source = "github.com/f5devcentral/terraform-aws-bigip?ref=develop" 197 | 198 | prefix = format( 199 | "%s-bigip_with_new_vpc_external-%s", 200 | var.project.value, 201 | var.random_id.value 202 | ) 203 | ec2_instance_type = var.ec2_instance_type 204 | ec2_key_name = var.ec2_key_name 205 | aws_secretmanager_secret_id = var.secrets_manager_name.value 206 | bigip_map = local.external_bigip_map_az2 207 | iam_instance_profile = var.iam_instance_profile_name.value 208 | custom_user_data = data.template_file.external_onboard_az2.rendered 209 | } 210 | -------------------------------------------------------------------------------- /modules/awsInfrastructure/app_main.tf: -------------------------------------------------------------------------------- 1 | /* ## F5 Networks Secure Cloud Migration and Securty Zone Template for AWS #################################################################################################################################################################################### 2 | Version 1.4 3 | March 2020 4 | 5 | 6 | This Template is provided as is and without warranty or support. It is intended for demonstration or reference purposes. While all attempts are made to ensure it functions as desired it is not a supported by F5 Networks. This template can be used 7 | to quickly deploy a Security VPC - aka DMZ, in-front of the your application VPC(S). Additional VPCs can be added to the template by adding CIDR variables, VPC resource blocks, VPC specific route tables 8 | and TransitGateway edits. Limits to VPCs that can be added are =to the limits of transit gateway. 9 | 10 | It is built to run in a region with three zones to use and will place services in 1a and 1c. Modifications to other zones can be done. 11 | 12 | F5 Application Services will be deployed into the security VPC but if one wished they could also be deployed inside of the Application VPCs. 13 | 14 | */ 15 | ############################################################################################################################################################################################################################################################### 16 | 17 | ################################################################################################################################################################################################################################################################ 18 | # 19 | # Application VPC Creation 20 | # 21 | ################################################################################################################################################################################################################################################################ 22 | 23 | resource "aws_vpc" "application-test" { 24 | cidr_block = var.cidr-2 25 | enable_dns_hostnames = true 26 | enable_dns_support = true 27 | 28 | tags = { 29 | Name = "${var.project}_Application-VPC" 30 | } 31 | } 32 | 33 | # application-test VPC Subnets AZ 1 34 | 35 | resource "aws_subnet" "app_subnet_internet_region-az-1" { 36 | cidr_block = cidrsubnet(aws_vpc.application-test.cidr_block, 8, 0) 37 | vpc_id = aws_vpc.application-test.id 38 | availability_zone = var.region-az-1 39 | 40 | tags = { 41 | Name = "${var.project}_app_subnet_internet_region-az-1" 42 | } 43 | } 44 | 45 | resource "aws_subnet" "app_subnet_dmz_1_region-az-1" { 46 | cidr_block = cidrsubnet(aws_vpc.application-test.cidr_block, 8, 1) 47 | vpc_id = aws_vpc.application-test.id 48 | availability_zone = var.region-az-1 49 | 50 | tags = { 51 | Name = "${var.project}_app_subnet_dmz_1_region-az-1" 52 | } 53 | } 54 | 55 | resource "aws_subnet" "app_subnet_application_region-az-1" { 56 | cidr_block = cidrsubnet(aws_vpc.application-test.cidr_block, 8, 2) 57 | vpc_id = aws_vpc.application-test.id 58 | availability_zone = var.region-az-1 59 | 60 | tags = { 61 | Name = "${var.project}_app_subnet_application_region-az-1" 62 | } 63 | } 64 | 65 | resource "aws_subnet" "app_subnet_peering_region-az-1" { 66 | cidr_block = cidrsubnet(aws_vpc.application-test.cidr_block, 8, 3) 67 | vpc_id = aws_vpc.application-test.id 68 | availability_zone = var.region-az-1 69 | 70 | tags = { 71 | Name = "${var.project}_app_subnet_peering_region-az-1" 72 | } 73 | } 74 | 75 | resource "aws_subnet" "app_subnet_mgmt_region-az-1" { 76 | cidr_block = cidrsubnet(aws_vpc.application-test.cidr_block, 8, 100) 77 | vpc_id = aws_vpc.application-test.id 78 | availability_zone = var.region-az-1 79 | 80 | tags = { 81 | Name = "${var.project}_app_subnet_mgmt_region-az-1" 82 | } 83 | } 84 | 85 | #Application VPC Subnets AZ 2 86 | 87 | resource "aws_subnet" "app_subnet_internet_region-az-2" { 88 | cidr_block = cidrsubnet(aws_vpc.application-test.cidr_block, 8, 10) 89 | vpc_id = aws_vpc.application-test.id 90 | availability_zone = var.region-az-2 91 | 92 | tags = { 93 | Name = "${var.project}_app_subnet_internet_region-az-2" 94 | } 95 | } 96 | 97 | resource "aws_subnet" "app_subnet_dmz_1_region-az-2" { 98 | cidr_block = cidrsubnet(aws_vpc.application-test.cidr_block, 8, 11) 99 | vpc_id = aws_vpc.application-test.id 100 | availability_zone = var.region-az-2 101 | 102 | tags = { 103 | Name = "${var.project}_app_subnet_dmz_1_region-az-2" 104 | } 105 | } 106 | 107 | resource "aws_subnet" "app_subnet_application_region-az-2" { 108 | cidr_block = cidrsubnet(aws_vpc.application-test.cidr_block, 8, 12) 109 | vpc_id = aws_vpc.application-test.id 110 | availability_zone = var.region-az-2 111 | 112 | tags = { 113 | Name = "${var.project}_app_subnet_application_region-az-2" 114 | } 115 | } 116 | 117 | resource "aws_subnet" "app_subnet_peering_region-az-2" { 118 | cidr_block = cidrsubnet(aws_vpc.application-test.cidr_block, 8, 13) 119 | vpc_id = aws_vpc.application-test.id 120 | availability_zone = var.region-az-2 121 | 122 | tags = { 123 | Name = "${var.project}_app_subnet_peering_region-az-2" 124 | } 125 | } 126 | 127 | resource "aws_subnet" "app_subnet_mgmt_region-az-2" { 128 | cidr_block = cidrsubnet(aws_vpc.application-test.cidr_block, 8, 200) 129 | vpc_id = aws_vpc.application-test.id 130 | availability_zone = var.region-az-2 131 | 132 | tags = { 133 | Name = "${var.project}_app_subnet_mgmt_region-az-2" 134 | } 135 | } 136 | 137 | /* 138 | #CREATE APP-VPC Main RT 139 | */ 140 | 141 | resource "aws_route_table" "app_tgw_main_rt" { 142 | vpc_id = aws_vpc.application-test.id 143 | 144 | tags = { 145 | Name = "${var.project}_application_main_rt" 146 | } 147 | } 148 | 149 | #Associate App Subnets with Main_RT 150 | 151 | resource "aws_route_table_association" "app_subnet_internet_region-az-1" { 152 | route_table_id = aws_route_table.app_tgw_main_rt.id 153 | subnet_id = aws_subnet.app_subnet_internet_region-az-1.id 154 | } 155 | 156 | resource "aws_route_table_association" "app_subnet_dmz_1_region-az-1" { 157 | route_table_id = aws_route_table.app_tgw_main_rt.id 158 | subnet_id = aws_subnet.app_subnet_dmz_1_region-az-1.id 159 | } 160 | 161 | resource "aws_route_table_association" "app_subnet_application_region-az-1" { 162 | route_table_id = aws_route_table.app_tgw_main_rt.id 163 | subnet_id = aws_subnet.app_subnet_application_region-az-1.id 164 | } 165 | 166 | resource "aws_route_table_association" "app_subnet_peering_region-az-1" { 167 | route_table_id = aws_route_table.app_tgw_main_rt.id 168 | subnet_id = aws_subnet.app_subnet_peering_region-az-1.id 169 | } 170 | 171 | resource "aws_route_table_association" "app_subnet_mgmt_region-az-1" { 172 | route_table_id = aws_route_table.app_tgw_main_rt.id 173 | subnet_id = aws_subnet.app_subnet_mgmt_region-az-1.id 174 | } 175 | 176 | resource "aws_route_table_association" "app_subnet_internet_region-az-2" { 177 | route_table_id = aws_route_table.app_tgw_main_rt.id 178 | subnet_id = aws_subnet.app_subnet_internet_region-az-2.id 179 | } 180 | 181 | resource "aws_route_table_association" "app_subnet_dmz_1_region-az-2" { 182 | route_table_id = aws_route_table.app_tgw_main_rt.id 183 | subnet_id = aws_subnet.app_subnet_dmz_1_region-az-2.id 184 | } 185 | 186 | resource "aws_route_table_association" "app_subnet_application_region-az-2" { 187 | route_table_id = aws_route_table.app_tgw_main_rt.id 188 | subnet_id = aws_subnet.app_subnet_application_region-az-2.id 189 | } 190 | 191 | resource "aws_route_table_association" "app_subnet_peering_region-az-2" { 192 | route_table_id = aws_route_table.app_tgw_main_rt.id 193 | subnet_id = aws_subnet.app_subnet_peering_region-az-2.id 194 | } 195 | 196 | resource "aws_route_table_association" "app_subnet_mgmt_region-az-2" { 197 | route_table_id = aws_route_table.app_tgw_main_rt.id 198 | subnet_id = aws_subnet.app_subnet_mgmt_region-az-2.id 199 | } 200 | 201 | #Enpoint Security Group 202 | 203 | resource "aws_security_group" "sg_internal_application_vpc" { 204 | description = "wide open" 205 | ingress { 206 | protocol = -1 207 | from_port = 0 208 | to_port = 0 209 | cidr_blocks = ["${var.cidr-2}"] 210 | } 211 | egress { 212 | protocol = -1 213 | from_port = 0 214 | to_port = 0 215 | cidr_blocks = ["${var.cidr-2}"] 216 | } 217 | vpc_id = aws_vpc.application-test.id 218 | } 219 | 220 | 221 | # Create S3 VPC Endpoint 222 | resource "aws_vpc_endpoint" "s3-application-vpc" { 223 | vpc_id = aws_vpc.application-test.id 224 | service_name = "com.amazonaws.${var.aws_region}.s3" 225 | } 226 | 227 | resource "aws_vpc_endpoint_route_table_association" "private_s3-app-vpc" { 228 | vpc_endpoint_id = aws_vpc_endpoint.s3-application-vpc.id 229 | route_table_id = aws_route_table.app_tgw_main_rt.id 230 | } 231 | 232 | 233 | # Create EC2 VPC Endpoint 234 | resource "aws_vpc_endpoint" "app-ec2-endpoint" { 235 | vpc_id = aws_vpc.application-test.id 236 | service_name = "com.amazonaws.${var.aws_region}.ec2" 237 | vpc_endpoint_type = "Interface" 238 | 239 | security_group_ids = [aws_security_group.sg_internal_application_vpc.id] 240 | 241 | private_dns_enabled = true 242 | subnet_ids = [aws_subnet.app_subnet_peering_region-az-1.id, aws_subnet.app_subnet_peering_region-az-2.id] 243 | } 244 | 245 | # Create Cloudwatch VPC Endpoint 246 | resource "aws_vpc_endpoint" "app-vpc-logs" { 247 | vpc_id = aws_vpc.application-test.id 248 | service_name = "com.amazonaws.${var.aws_region}.logs" 249 | vpc_endpoint_type = "Interface" 250 | 251 | security_group_ids = [aws_security_group.sg_internal_application_vpc.id] 252 | 253 | private_dns_enabled = true 254 | subnet_ids = [aws_subnet.app_subnet_peering_region-az-1.id, aws_subnet.app_subnet_peering_region-az-2.id] 255 | 256 | } 257 | 258 | 259 | -------------------------------------------------------------------------------- /modules/awsInfrastructure/k8s_main.tf: -------------------------------------------------------------------------------- 1 | /* ## F5 Networks Secure Cloud Migration and Securty Zone Template for AWS #################################################################################################################################################################################### 2 | Version 1.4 3 | March 2020 4 | 5 | 6 | This Template is provided as is and without warranty or support. It is intended for demonstration or reference purposes. While all attempts are made to ensure it functions as desired it is not a supported by F5 Networks. This template can be used 7 | to quickly deploy a Security VPC - aka DMZ, in-front of the your application VPC(S). Additional VPCs can be added to the template by adding CIDR variables, VPC resource blocks, VPC specific route tables 8 | and TransitGateway edits. Limits to VPCs that can be added are =to the limits of transit gateway. 9 | 10 | It is built to run in a region with three zones to use and will place services in 1a and 1c. Modifications to other zones can be done. 11 | 12 | F5 Application Services will be deployed into the security VPC but if one wished they could also be deployed inside of the Application VPCs. 13 | 14 | */ 15 | ############################################################################################################################################################################################################################################################### 16 | 17 | ################################################################################################################################################################################################################################################################ 18 | # 19 | # container VPC Creation 20 | # 21 | ################################################################################################################################################################################################################################################################ 22 | resource "aws_vpc" "container-test" { 23 | cidr_block = var.cidr-3 24 | enable_dns_hostnames = true 25 | enable_dns_support = true 26 | 27 | tags = { 28 | Name = "${var.project}_Container-VPC" 29 | } 30 | } 31 | 32 | #Conatiner-test VPC Subnets AZ 1 33 | 34 | resource "aws_subnet" "container_subnet_internet_region-az-1" { 35 | cidr_block = cidrsubnet(aws_vpc.container-test.cidr_block, 8, 0) 36 | vpc_id = aws_vpc.container-test.id 37 | availability_zone = var.region-az-1 38 | 39 | tags = { 40 | Name = "${var.project}_container_subnet_internet_region-az-1" 41 | } 42 | } 43 | 44 | resource "aws_subnet" "container_subnet_dmz_1_region-az-1" { 45 | cidr_block = cidrsubnet(aws_vpc.container-test.cidr_block, 8, 1) 46 | vpc_id = aws_vpc.container-test.id 47 | availability_zone = var.region-az-1 48 | 49 | tags = { 50 | Name = "${var.project}_container_subnet_dmz_1_region-az-1" 51 | } 52 | } 53 | 54 | resource "aws_subnet" "container_subnet_application_region-az-1" { 55 | cidr_block = cidrsubnet(aws_vpc.container-test.cidr_block, 8, 2) 56 | vpc_id = aws_vpc.container-test.id 57 | availability_zone = var.region-az-1 58 | 59 | tags = { 60 | Name = "${var.project}_container_subnet_application_region-az-1" 61 | } 62 | } 63 | 64 | resource "aws_subnet" "container_subnet_peering_region-az-1" { 65 | cidr_block = cidrsubnet(aws_vpc.container-test.cidr_block, 8, 3) 66 | vpc_id = aws_vpc.container-test.id 67 | availability_zone = var.region-az-1 68 | 69 | tags = { 70 | Name = "${var.project}_container_subnet_peering_region-az-1" 71 | } 72 | } 73 | 74 | resource "aws_subnet" "container_subnet_mgmt_region-az-1" { 75 | cidr_block = cidrsubnet(aws_vpc.container-test.cidr_block, 8, 100) 76 | vpc_id = aws_vpc.container-test.id 77 | availability_zone = var.region-az-1 78 | 79 | tags = { 80 | Name = "${var.project}_container_subnet_mgmt_region-az-1" 81 | } 82 | } 83 | 84 | #container-Test Subnets AZ 2 85 | 86 | resource "aws_subnet" "container_subnet_internet_region-az-2" { 87 | cidr_block = cidrsubnet(aws_vpc.container-test.cidr_block, 8, 10) 88 | vpc_id = aws_vpc.container-test.id 89 | availability_zone = var.region-az-2 90 | 91 | tags = { 92 | Name = "${var.project}_container_subnet_internet_region-az-2" 93 | } 94 | } 95 | 96 | resource "aws_subnet" "container_subnet_dmz_1_region-az-2" { 97 | cidr_block = cidrsubnet(aws_vpc.container-test.cidr_block, 8, 11) 98 | vpc_id = aws_vpc.container-test.id 99 | availability_zone = var.region-az-2 100 | 101 | tags = { 102 | Name = "${var.project}_container_subnet_dmz_1_region-az-2" 103 | } 104 | } 105 | 106 | resource "aws_subnet" "container_subnet_application_region-az-2" { 107 | cidr_block = cidrsubnet(aws_vpc.container-test.cidr_block, 8, 12) 108 | vpc_id = aws_vpc.container-test.id 109 | availability_zone = var.region-az-2 110 | 111 | tags = { 112 | Name = "${var.project}_container_subnet_application_region-az-2" 113 | } 114 | } 115 | 116 | resource "aws_subnet" "container_subnet_peering_region-az-2" { 117 | cidr_block = cidrsubnet(aws_vpc.container-test.cidr_block, 8, 13) 118 | vpc_id = aws_vpc.container-test.id 119 | availability_zone = var.region-az-2 120 | 121 | tags = { 122 | Name = "${var.project}_container_subnet_peering_region-az-2" 123 | } 124 | } 125 | 126 | resource "aws_subnet" "container_subnet_mgmt_region-az-2" { 127 | cidr_block = cidrsubnet(aws_vpc.container-test.cidr_block, 8, 200) 128 | vpc_id = aws_vpc.container-test.id 129 | availability_zone = var.region-az-2 130 | 131 | tags = { 132 | Name = "${var.project}_container_subnet_mgmt_region-az-2" 133 | } 134 | } 135 | 136 | /* 137 | CREATE container-Test Main RT 138 | */ 139 | 140 | resource "aws_route_table" "container_tgw_main_rt" { 141 | vpc_id = aws_vpc.container-test.id 142 | 143 | tags = { 144 | Name = "${var.project}_container_main_rt" 145 | } 146 | } 147 | 148 | #Associate Conatiner Subnets with Main_RT 149 | 150 | resource "aws_route_table_association" "container_subnet_internet_region-az-1" { 151 | route_table_id = aws_route_table.container_tgw_main_rt.id 152 | subnet_id = aws_subnet.container_subnet_internet_region-az-1.id 153 | } 154 | 155 | resource "aws_route_table_association" "container_subnet_dmz_1_region-az-1" { 156 | route_table_id = aws_route_table.container_tgw_main_rt.id 157 | subnet_id = aws_subnet.container_subnet_dmz_1_region-az-1.id 158 | } 159 | 160 | resource "aws_route_table_association" "container_subnet_application_region-az-1" { 161 | route_table_id = aws_route_table.container_tgw_main_rt.id 162 | subnet_id = aws_subnet.container_subnet_application_region-az-1.id 163 | } 164 | 165 | resource "aws_route_table_association" "container_subnet_peering_region-az-1" { 166 | route_table_id = aws_route_table.container_tgw_main_rt.id 167 | subnet_id = aws_subnet.container_subnet_peering_region-az-1.id 168 | } 169 | 170 | resource "aws_route_table_association" "container_subnet_mgmt_region-az-1" { 171 | route_table_id = aws_route_table.container_tgw_main_rt.id 172 | subnet_id = aws_subnet.container_subnet_mgmt_region-az-1.id 173 | } 174 | 175 | resource "aws_route_table_association" "container_subnet_internet_region-az-2" { 176 | route_table_id = aws_route_table.container_tgw_main_rt.id 177 | subnet_id = aws_subnet.container_subnet_internet_region-az-2.id 178 | } 179 | 180 | resource "aws_route_table_association" "container_subnet_dmz_1_region-az-2" { 181 | route_table_id = aws_route_table.container_tgw_main_rt.id 182 | subnet_id = aws_subnet.container_subnet_dmz_1_region-az-2.id 183 | } 184 | 185 | resource "aws_route_table_association" "container_subnet_application_region-az-2" { 186 | route_table_id = aws_route_table.container_tgw_main_rt.id 187 | subnet_id = aws_subnet.container_subnet_application_region-az-2.id 188 | } 189 | 190 | resource "aws_route_table_association" "container_subnet_peering_region-az-2" { 191 | route_table_id = aws_route_table.container_tgw_main_rt.id 192 | subnet_id = aws_subnet.container_subnet_peering_region-az-2.id 193 | } 194 | 195 | resource "aws_route_table_association" "container_subnet_mgmt_region-az-2" { 196 | route_table_id = aws_route_table.container_tgw_main_rt.id 197 | subnet_id = aws_subnet.container_subnet_mgmt_region-az-2.id 198 | } 199 | 200 | #Enpoint Security Group 201 | 202 | resource "aws_security_group" "sg_internal_container_vpc" { 203 | description = "wide open" 204 | ingress { 205 | protocol = -1 206 | from_port = 0 207 | to_port = 0 208 | cidr_blocks = ["${var.cidr-3}"] 209 | } 210 | egress { 211 | protocol = -1 212 | from_port = 0 213 | to_port = 0 214 | cidr_blocks = ["${var.cidr-3}"] 215 | } 216 | vpc_id = aws_vpc.container-test.id 217 | } 218 | 219 | 220 | # Create S3 VPC Endpoint 221 | resource "aws_vpc_endpoint" "s3-container-vpc" { 222 | vpc_id = aws_vpc.container-test.id 223 | service_name = "com.amazonaws.${var.aws_region}.s3" 224 | } 225 | 226 | resource "aws_vpc_endpoint_route_table_association" "private_s3-container-vpc" { 227 | vpc_endpoint_id = aws_vpc_endpoint.s3-container-vpc.id 228 | route_table_id = aws_route_table.container_tgw_main_rt.id 229 | } 230 | 231 | 232 | # Create EC2 VPC Endpoint 233 | resource "aws_vpc_endpoint" "conatiner-ec2-endpoint" { 234 | vpc_id = aws_vpc.container-test.id 235 | service_name = "com.amazonaws.${var.aws_region}.ec2" 236 | vpc_endpoint_type = "Interface" 237 | 238 | security_group_ids = [aws_security_group.sg_internal_container_vpc.id] 239 | 240 | private_dns_enabled = true 241 | subnet_ids = [aws_subnet.container_subnet_peering_region-az-1.id, aws_subnet.container_subnet_peering_region-az-2.id] 242 | } 243 | 244 | # Create Cloudwatch VPC Endpoint 245 | resource "aws_vpc_endpoint" "container-vpc-logs" { 246 | vpc_id = aws_vpc.container-test.id 247 | service_name = "com.amazonaws.${var.aws_region}.logs" 248 | vpc_endpoint_type = "Interface" 249 | 250 | security_group_ids = [aws_security_group.sg_internal_container_vpc.id] 251 | 252 | private_dns_enabled = true 253 | subnet_ids = [aws_subnet.container_subnet_peering_region-az-1.id, aws_subnet.container_subnet_peering_region-az-2.id] 254 | 255 | } 256 | 257 | 258 | -------------------------------------------------------------------------------- /sca/configuration_stack/declarativeOnboarding.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | external_bigip_az1 = flatten([ 3 | for environment, bigips in var.bigip_map.value : [ 4 | for key, bigip in bigips : { 5 | id : key 6 | subnets : { 7 | for subnet, data in bigip : data.attachment[0].device_index => { 8 | private_ip : data.private_ip, 9 | private_dns_name : data.private_dns_name 10 | } 11 | } 12 | } 13 | ] if(environment == "external_az1") 14 | ]) 15 | } 16 | locals { 17 | external_bigip_az2 = flatten([ 18 | for environment, bigips in var.bigip_map.value : [ 19 | for key, bigip in bigips : { 20 | id : key 21 | subnets : { 22 | for subnet, data in bigip : data.attachment[0].device_index => { 23 | private_ip : data.private_ip, 24 | private_dns_name : data.private_dns_name 25 | } 26 | } 27 | } 28 | ] if(environment == "external_az2") 29 | ]) 30 | } 31 | locals { 32 | ips_bigip_az1 = flatten([ 33 | for environment, bigips in var.bigip_map.value : [ 34 | for key, bigip in bigips : { 35 | id : key 36 | subnets : { 37 | for subnet, data in bigip : data.attachment[0].device_index => { 38 | private_ip : data.private_ip, 39 | private_dns_name : data.private_dns_name 40 | } 41 | } 42 | } 43 | ] if(environment == "ips_az1") 44 | ]) 45 | } 46 | locals { 47 | ips_bigip_az2 = flatten([ 48 | for environment, bigips in var.bigip_map.value : [ 49 | for key, bigip in bigips : { 50 | id : key 51 | subnets : { 52 | for subnet, data in bigip : data.attachment[0].device_index => { 53 | private_ip : data.private_ip, 54 | private_dns_name : data.private_dns_name 55 | } 56 | } 57 | } 58 | ] if(environment == "ips_az2") 59 | ]) 60 | } 61 | locals { 62 | internal_bigip_az1 = flatten([ 63 | for environment, bigips in var.bigip_map.value : [ 64 | for key, bigip in bigips : { 65 | id : key 66 | subnets : { 67 | for subnet, data in bigip : data.attachment[0].device_index => { 68 | private_ip : data.private_ip, 69 | private_dns_name : data.private_dns_name 70 | } 71 | } 72 | } 73 | ] if(environment == "internal_az1") 74 | ]) 75 | } 76 | locals { 77 | internal_bigip_az2 = flatten([ 78 | for environment, bigips in var.bigip_map.value : [ 79 | for key, bigip in bigips : { 80 | id : key 81 | subnets : { 82 | for subnet, data in bigip : data.attachment[0].device_index => { 83 | private_ip : data.private_ip, 84 | private_dns_name : data.private_dns_name 85 | } 86 | } 87 | } 88 | ] if(environment == "internal_az2") 89 | ]) 90 | } 91 | 92 | #retrieve secret from AWS to use in DO 93 | data "aws_secretsmanager_secret_version" "secret" { 94 | secret_id = var.secrets_manager_name.value 95 | } 96 | 97 | data "template_file" "ext_bigip_az1_do_json" { 98 | template = file("${path.module}/templates/declarativeOnboarding/externalClusterPayg.json") 99 | 100 | vars = { 101 | #Uncomment the following line for BYOL 102 | #local_sku = "${var.license1}" 103 | host1 = local.external_bigip_az1[0].subnets.0.private_ip 104 | host2 = local.external_bigip_az2[0].subnets.0.private_ip 105 | local_host = local.external_bigip_az1[0].subnets.0.private_dns_name 106 | local_selfip = local.external_bigip_az1[0].subnets.1.private_ip 107 | local_selfip2 = local.external_bigip_az1[0].subnets.2.private_ip 108 | local_selfip3 = local.external_bigip_az1[0].subnets.3.private_ip 109 | remote_host = local.external_bigip_az2[0].subnets.0.private_dns_name 110 | remote_selfip = local.external_bigip_az2[0].subnets.2.private_ip 111 | gateway = var.ext0_gateway 112 | dns_server = var.dns_server 113 | ntp_server = var.ntp_server 114 | timezone = var.timezone 115 | admin_user = var.uname 116 | admin_password = data.aws_secretsmanager_secret_version.secret.secret_string 117 | } 118 | } 119 | 120 | data "template_file" "ext_bigip_az2_do_json" { 121 | template = file("${path.module}/templates/declarativeOnboarding/externalClusterPayg.json") 122 | 123 | vars = { 124 | #Uncomment the following line for BYOL 125 | #local_sku = "${var.license1}" 126 | host1 = local.external_bigip_az1[0].subnets.0.private_ip 127 | host2 = local.external_bigip_az2[0].subnets.0.private_ip 128 | local_host = local.external_bigip_az2[0].subnets.0.private_dns_name 129 | local_selfip = local.external_bigip_az2[0].subnets.1.private_ip 130 | local_selfip2 = local.external_bigip_az2[0].subnets.2.private_ip 131 | local_selfip3 = local.external_bigip_az2[0].subnets.3.private_ip 132 | remote_host = local.external_bigip_az1[0].subnets.0.private_dns_name 133 | remote_selfip = local.external_bigip_az1[0].subnets.2.private_ip 134 | gateway = var.ext0_gateway 135 | dns_server = var.dns_server 136 | ntp_server = var.ntp_server 137 | timezone = var.timezone 138 | admin_user = var.uname 139 | admin_password = data.aws_secretsmanager_secret_version.secret.secret_string 140 | } 141 | } 142 | data "template_file" "ips_bigip_az1_do_json" { 143 | template = file("${path.module}/templates/declarativeOnboarding/externalClusterPayg.json") 144 | 145 | vars = { 146 | #Uncomment the following line for BYOL 147 | #local_sku = "${var.license1}" 148 | host1 = local.ips_bigip_az1[0].subnets.0.private_ip 149 | host2 = local.ips_bigip_az2[0].subnets.0.private_ip 150 | local_host = local.ips_bigip_az1[0].subnets.0.private_dns_name 151 | local_selfip = local.ips_bigip_az1[0].subnets.1.private_ip 152 | local_selfip2 = local.ips_bigip_az1[0].subnets.2.private_ip 153 | local_selfip3 = local.ips_bigip_az1[0].subnets.3.private_ip 154 | remote_host = local.ips_bigip_az2[0].subnets.0.private_dns_name 155 | remote_selfip = local.ips_bigip_az2[0].subnets.2.private_ip 156 | gateway = var.ips0_gateway 157 | dns_server = var.dns_server 158 | ntp_server = var.ntp_server 159 | timezone = var.timezone 160 | admin_user = var.uname 161 | admin_password = data.aws_secretsmanager_secret_version.secret.secret_string 162 | } 163 | } 164 | 165 | data "template_file" "ips_bigip_az2_do_json" { 166 | template = file("${path.module}/templates/declarativeOnboarding/externalClusterPayg.json") 167 | 168 | vars = { 169 | #Uncomment the following line for BYOL 170 | #local_sku = "${var.license1}" 171 | host1 = local.ips_bigip_az1[0].subnets.0.private_ip 172 | host2 = local.ips_bigip_az2[0].subnets.0.private_ip 173 | local_host = local.ips_bigip_az2[0].subnets.0.private_dns_name 174 | local_selfip = local.ips_bigip_az2[0].subnets.1.private_ip 175 | local_selfip2 = local.ips_bigip_az2[0].subnets.2.private_ip 176 | local_selfip3 = local.ips_bigip_az2[0].subnets.3.private_ip 177 | remote_host = local.ips_bigip_az1[0].subnets.0.private_dns_name 178 | remote_selfip = local.ips_bigip_az1[0].subnets.2.private_ip 179 | gateway = var.ips1_gateway 180 | dns_server = var.dns_server 181 | ntp_server = var.ntp_server 182 | timezone = var.timezone 183 | admin_user = var.uname 184 | admin_password = data.aws_secretsmanager_secret_version.secret.secret_string 185 | } 186 | } 187 | data "template_file" "internal_bigip_az1_do_json" { 188 | template = file("${path.module}/templates/declarativeOnboarding/externalClusterPayg.json") 189 | 190 | vars = { 191 | #Uncomment the following line for BYOL 192 | #local_sku = "${var.license1}" 193 | host1 = local.internal_bigip_az1[0].subnets.0.private_ip 194 | host2 = local.internal_bigip_az2[0].subnets.0.private_ip 195 | local_host = local.internal_bigip_az1[0].subnets.0.private_dns_name 196 | local_selfip = local.internal_bigip_az1[0].subnets.1.private_ip 197 | local_selfip2 = local.internal_bigip_az1[0].subnets.2.private_ip 198 | local_selfip3 = local.internal_bigip_az1[0].subnets.3.private_ip 199 | remote_host = local.internal_bigip_az2[0].subnets.0.private_dns_name 200 | remote_selfip = local.internal_bigip_az2[0].subnets.2.private_ip 201 | gateway = var.int0_gateway 202 | dns_server = var.dns_server 203 | ntp_server = var.ntp_server 204 | timezone = var.timezone 205 | admin_user = var.uname 206 | admin_password = data.aws_secretsmanager_secret_version.secret.secret_string 207 | } 208 | } 209 | 210 | data "template_file" "internal_bigip_az2_do_json" { 211 | template = file("${path.module}/templates/declarativeOnboarding/externalClusterPayg.json") 212 | 213 | vars = { 214 | #Uncomment the following line for BYOL 215 | #local_sku = "${var.license1}" 216 | host1 = local.internal_bigip_az1[0].subnets.0.private_ip 217 | host2 = local.internal_bigip_az2[0].subnets.0.private_ip 218 | local_host = local.internal_bigip_az2[0].subnets.0.private_dns_name 219 | local_selfip = local.internal_bigip_az2[0].subnets.1.private_ip 220 | local_selfip2 = local.internal_bigip_az2[0].subnets.2.private_ip 221 | local_selfip3 = local.internal_bigip_az2[0].subnets.3.private_ip 222 | remote_host = local.internal_bigip_az1[0].subnets.0.private_dns_name 223 | remote_selfip = local.internal_bigip_az1[0].subnets.2.private_ip 224 | gateway = var.int1_gateway 225 | dns_server = var.dns_server 226 | ntp_server = var.ntp_server 227 | timezone = var.timezone 228 | admin_user = var.uname 229 | admin_password = data.aws_secretsmanager_secret_version.secret.secret_string 230 | } 231 | } 232 | 233 | resource "bigip_do" "external_bigip_az1" { 234 | provider = bigip.external_bigip_az1 235 | do_json = data.template_file.ext_bigip_az1_do_json.rendered 236 | #tenant_name = "baseline" 237 | } 238 | 239 | resource "bigip_do" "external_bigip_az2" { 240 | provider = bigip.external_bigip_az2 241 | do_json = data.template_file.ext_bigip_az2_do_json.rendered 242 | #tenant_name = "baseline" 243 | } 244 | 245 | resource "bigip_do" "ips_bigip_az1" { 246 | provider = bigip.ips_bigip_az1 247 | do_json = data.template_file.ips_bigip_az1_do_json.rendered 248 | #tenant_name = "baseline" 249 | } 250 | 251 | resource "bigip_do" "ips_bigip_az2" { 252 | provider = bigip.ips_bigip_az2 253 | do_json = data.template_file.ips_bigip_az2_do_json.rendered 254 | #tenant_name = "baseline" 255 | } 256 | 257 | resource "bigip_do" "internal_bigip_az1" { 258 | provider = bigip.internal_bigip_az1 259 | do_json = data.template_file.internal_bigip_az1_do_json.rendered 260 | #tenant_name = "baseline" 261 | } 262 | 263 | resource "bigip_do" "internal_bigip_az2" { 264 | provider = bigip.internal_bigip_az2 265 | do_json = data.template_file.internal_bigip_az2_do_json.rendered 266 | #tenant_name = "baseline" 267 | } 268 | 269 | 270 | output external_bigips { 271 | value = var.bigip_mgmt_ips 272 | } 273 | 274 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /modules/awsInfrastructure/tgw_main.tf: -------------------------------------------------------------------------------- 1 | /* ## F5 Networks Secure Cloud Migration and Securty Zone Template for AWS #################################################################################################################################################################################### 2 | Version 1.4 3 | March 2020 4 | 5 | 6 | This Template is provided as is and without warranty or support. It is intended for demonstration or reference purposes. While all attempts are made to ensure it functions as desired it is not a supported by F5 Networks. This template can be used 7 | to quickly deploy a Security VPC - aka DMZ, in-front of the your application VPC(S). Additional VPCs can be added to the template by adding CIDR variables, VPC resource blocks, VPC specific route tables 8 | and TransitGateway edits. Limits to VPCs that can be added are =to the limits of transit gateway. 9 | 10 | It is built to run in a region with three zones to use and will place services in 1a and 1c. Modifications to other zones can be done. 11 | 12 | F5 Application Services will be deployed into the security VPC but if one wished they could also be deployed inside of the Application VPCs. 13 | 14 | */ 15 | ############################################################################################################################################################################################################################################################### 16 | 17 | #### Start Transit Gateway and subcomponents ################################################################################################################################################################################################################################# 18 | # 19 | # Transit Gateway is used to connect the VPCs and allows for client IP address transparency - IE "Transit" topologies. Transit Gateway should be used unless the customer is commited to the Transit VPC topology. 20 | # 21 | ############################################################################################################################################################################################################################################################################### 22 | 23 | #Transit Gateway 24 | 25 | resource "aws_ec2_transit_gateway" "security-app-tgw" { 26 | default_route_table_association = "disable" 27 | default_route_table_propagation = "disable" 28 | description = "${var.project}_transit_gateway" 29 | 30 | tags = { 31 | Name = "${var.project}_security-app-tgw" 32 | } 33 | } 34 | 35 | #Create Transit Gateway Route Table 36 | 37 | resource "aws_ec2_transit_gateway_route_table" "security-app-tgw-main-rt" { 38 | transit_gateway_id = aws_ec2_transit_gateway.security-app-tgw.id 39 | 40 | tags = { 41 | Name = "${var.project}_security-app-tgw-main-rt" 42 | } 43 | } 44 | 45 | # Attached the Transit Gateway to the VPCs 46 | 47 | resource "aws_ec2_transit_gateway_vpc_attachment" "security-app-tgw-security-vpc" { 48 | subnet_ids = [aws_subnet.sec_subnet_peering_region-az-1.id, aws_subnet.sec_subnet_peering_region-az-2.id] 49 | transit_gateway_id = aws_ec2_transit_gateway.security-app-tgw.id 50 | vpc_id = aws_vpc.security-vpc.id 51 | transit_gateway_default_route_table_association = "false" 52 | transit_gateway_default_route_table_propagation = "false" 53 | 54 | tags = { 55 | Name = "${var.project}_security-app-tgw-security-vpc" 56 | } 57 | } 58 | 59 | resource "aws_ec2_transit_gateway_vpc_attachment" "security-app-tgw-app-vpc" { 60 | subnet_ids = [aws_subnet.app_subnet_peering_region-az-1.id, aws_subnet.app_subnet_peering_region-az-2.id] 61 | transit_gateway_id = aws_ec2_transit_gateway.security-app-tgw.id 62 | vpc_id = aws_vpc.application-test.id 63 | transit_gateway_default_route_table_association = "false" 64 | transit_gateway_default_route_table_propagation = "false" 65 | 66 | tags = { 67 | Name = "${var.project}_security-app-tgw-app-vpc" 68 | } 69 | } 70 | 71 | resource "aws_ec2_transit_gateway_vpc_attachment" "security-app-tgw-container-vpc" { 72 | subnet_ids = [aws_subnet.container_subnet_peering_region-az-1.id, aws_subnet.container_subnet_peering_region-az-2.id] 73 | transit_gateway_id = aws_ec2_transit_gateway.security-app-tgw.id 74 | vpc_id = aws_vpc.container-test.id 75 | transit_gateway_default_route_table_association = "false" 76 | transit_gateway_default_route_table_propagation = "false" 77 | 78 | tags = { 79 | Name = "${var.project}_security-app-tgw-app-vpc" 80 | } 81 | } 82 | 83 | ## Tranist Gateway Route Table Associations 84 | 85 | resource "aws_ec2_transit_gateway_route_table_association" "security-app-tgw-security-vpc-internal" { 86 | transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-security-vpc.id 87 | transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.security-app-tgw-main-rt.id 88 | } 89 | 90 | resource "aws_ec2_transit_gateway_route_table_association" "security-app-tgw-app-main" { 91 | transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-app-vpc.id 92 | transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.security-app-tgw-main-rt.id 93 | } 94 | 95 | resource "aws_ec2_transit_gateway_route_table_association" "security-app-tgw-container-main" { 96 | transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-container-vpc.id 97 | transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.security-app-tgw-main-rt.id 98 | } 99 | 100 | #Create Transit Gateway Route Table Propegations 101 | 102 | resource "aws_ec2_transit_gateway_route_table_propagation" "security-app-tgw-sec-prop" { 103 | transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-security-vpc.id 104 | transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.security-app-tgw-main-rt.id 105 | } 106 | 107 | resource "aws_ec2_transit_gateway_route_table_propagation" "security-app-tgw-app-prop" { 108 | transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-app-vpc.id 109 | transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.security-app-tgw-main-rt.id 110 | } 111 | 112 | resource "aws_ec2_transit_gateway_route_table_propagation" "security-app-tgw-container-prop" { 113 | transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-container-vpc.id 114 | transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.security-app-tgw-main-rt.id 115 | } 116 | 117 | ## Create Transit Gateway Routes 118 | 119 | resource "aws_ec2_transit_gateway_route" "security-app-tgw-default" { 120 | destination_cidr_block = "0.0.0.0/0" 121 | transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-security-vpc.id 122 | transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.security-app-tgw-main-rt.id 123 | } 124 | #Remove the Propegations above and use the Static Below if you would like more control of the routes in the TGW table. 125 | /* 126 | resource "aws_ec2_transit_gateway_route" "security-app-tgw-default-security-cidr" { 127 | destination_cidr_block = var.cidr-1 128 | transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-security-vpc.id 129 | transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.security-app-tgw-main-rt.id 130 | } 131 | 132 | resource "aws_ec2_transit_gateway_route" "security-app-tgw-default-app-cidr" { 133 | destination_cidr_block = var.cidr-2 134 | transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-app-vpc.id 135 | transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.security-app-tgw-main-rt.id 136 | } 137 | 138 | resource "aws_ec2_transit_gateway_route" "security-app-tgw-default-container-cidr" { 139 | destination_cidr_block = var.cidr-3 140 | transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-container-vpc.id 141 | transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.security-app-tgw-main-rt.id 142 | } 143 | */ 144 | #### Internal Routes from VPCS to TGW ######################################################################################################################################################################################################################################## 145 | # 146 | # Transit Gateway is used to connect the VPCs and allows for client IP address transparency - IE "Transit" topologies. Transit Gateway should be used unless the customer is commited to the Transit VPC topology. 147 | # 148 | ############################################################################################################################################################################################################################################################################### 149 | 150 | #Security VPC to APP VPC 151 | 152 | resource "aws_route" "sec-vpc-routes" { 153 | route_table_id = aws_route_table.sec_Internal_rt.id 154 | destination_cidr_block = var.cidr-2 155 | transit_gateway_id = aws_ec2_transit_gateway.security-app-tgw.id 156 | depends_on = [aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-security-vpc] 157 | } 158 | 159 | 160 | resource "aws_route" "sec-container-vpc-routes" { 161 | route_table_id = aws_route_table.sec_Internal_rt.id 162 | destination_cidr_block = var.cidr-3 163 | transit_gateway_id = aws_ec2_transit_gateway.security-app-tgw.id 164 | depends_on = [aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-security-vpc] 165 | } 166 | 167 | resource "aws_route" "sec-vpc-nat-routes" { 168 | route_table_id = aws_route_table.internet_rt.id 169 | destination_cidr_block = var.cidr-2 170 | transit_gateway_id = aws_ec2_transit_gateway.security-app-tgw.id 171 | depends_on = [aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-security-vpc] 172 | } 173 | 174 | resource "aws_route" "sec-container-vpc-nat-routes" { 175 | route_table_id = aws_route_table.internet_rt.id 176 | destination_cidr_block = var.cidr-3 177 | transit_gateway_id = aws_ec2_transit_gateway.security-app-tgw.id 178 | depends_on = [aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-security-vpc] 179 | } 180 | 181 | resource "aws_route" "sec-default-routes" { 182 | route_table_id = aws_route_table.internet_rt.id 183 | destination_cidr_block = "0.0.0.0/0" 184 | gateway_id = aws_internet_gateway.gw.id 185 | } 186 | 187 | resource "aws_route" "nat-application-default-routes_az1" { 188 | route_table_id = aws_route_table.sec_application_az1_rt.id 189 | destination_cidr_block = "0.0.0.0/0" 190 | nat_gateway_id = aws_nat_gateway.sec-gw-az1.id 191 | } 192 | 193 | resource "aws_route" "nat-application-default-routes_az2" { 194 | route_table_id = aws_route_table.sec_application_az2_rt.id 195 | destination_cidr_block = "0.0.0.0/0" 196 | nat_gateway_id = aws_nat_gateway.sec-gw-az2.id 197 | } 198 | 199 | #App VPC Default to TGW 200 | resource "aws_route" "app-vpc-routes" { 201 | route_table_id = aws_route_table.app_tgw_main_rt.id 202 | destination_cidr_block = "0.0.0.0/0" 203 | transit_gateway_id = aws_ec2_transit_gateway.security-app-tgw.id 204 | depends_on = [aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-app-vpc] 205 | } 206 | 207 | #Conatiner VPC Default to TGW 208 | resource "aws_route" "container-vpc-routes" { 209 | route_table_id = aws_route_table.container_tgw_main_rt.id 210 | destination_cidr_block = "0.0.0.0/0" 211 | transit_gateway_id = aws_ec2_transit_gateway.security-app-tgw.id 212 | depends_on = [aws_ec2_transit_gateway_vpc_attachment.security-app-tgw-container-vpc] 213 | } 214 | 215 | 216 | -------------------------------------------------------------------------------- /sca/core/output.tf: -------------------------------------------------------------------------------- 1 | output aws_region { 2 | value = var.aws_region 3 | } 4 | 5 | output project { 6 | value = var.project 7 | } 8 | 9 | output random_id { 10 | value = random_id.id.hex 11 | } 12 | 13 | output secrets_manager_name { 14 | value = module.core.secrets_manager_name 15 | } 16 | 17 | output iam_instance_profile_name { 18 | value = aws_iam_instance_profile.bigip_profile.name 19 | } 20 | 21 | output security_groups { 22 | value = { 23 | management = module.bigip_mgmt_sg.this_security_group_id 24 | public = module.bigip_sg.this_security_group_id 25 | private = module.bigip_sg.this_security_group_id 26 | } 27 | } 28 | 29 | output vpcs { 30 | description = "Secure Cloud Architecture VPCs" 31 | value = { 32 | security = module.core.security-vpc 33 | application = module.core.application-test 34 | container = module.core.container-test 35 | 36 | } 37 | } 38 | output subnets { 39 | value = { 40 | az1 = { 41 | security = { 42 | internet = module.core.sec_subnet_internet_region-az-1 43 | egress_to_ch1 = module.core.sec_subnet_egress_to_ch1_region-az-1 44 | ingress_frm_ch1 = module.core.sec_subnet_ingress_frm_ch1_region-az-1 45 | application_region = module.core.sec_subnet_application_region-az-1 46 | egress_to_ch2 = module.core.sec_subnet_egress_to_ch2_region-az-1 47 | ingress_frm_ch2 = module.core.sec_subnet_ingress_frm_ch2_region-az-1 48 | dmz_outside = module.core.sec_subnet_dmz_outside_region-az-1 49 | dmz_inside = module.core.sec_subnet_dmz_inside_region-az-1 50 | mgmt = module.core.sec_subnet_mgmt_region-az-1 51 | internal = module.core.sec_subnet_internal_region-az-1 52 | peering = module.core.sec_subnet_peering_region-az-1 53 | 54 | } 55 | application = { 56 | internet = module.core.app_subnet_internet_region-az-1 57 | dmz_1 = module.core.app_subnet_dmz_1_region-az-1 58 | application_region = module.core.app_subnet_application_region-az-1 59 | peering = module.core.app_subnet_peering_region-az-1 60 | mgmt = module.core.app_subnet_mgmt_region-az-1 61 | } 62 | container = { 63 | internet = module.core.container_subnet_internet_region-az-1 64 | dmz_1 = module.core.container_subnet_dmz_1_region-az-1 65 | application_region = module.core.container_subnet_application_region-az-1 66 | peering = module.core.container_subnet_peering_region-az-1 67 | mgmt = module.core.container_subnet_mgmt_region-az-1 68 | } 69 | } 70 | az2 = { 71 | security = { 72 | internet = module.core.sec_subnet_internet_region-az-2 73 | egress_to_ch1 = module.core.sec_subnet_egress_to_ch1_region-az-2 74 | ingress_frm_ch1 = module.core.sec_subnet_ingress_frm_ch1_region-az-2 75 | application_region = module.core.sec_subnet_application_region-az-2 76 | egress_to_ch2 = module.core.sec_subnet_egress_to_ch2_region-az-2 77 | ingress_frm_ch2 = module.core.sec_subnet_ingress_frm_ch2_region-az-2 78 | dmz_outside = module.core.sec_subnet_dmz_outside_region-az-2 79 | dmz_inside = module.core.sec_subnet_dmz_inside_region-az-2 80 | mgmt = module.core.sec_subnet_mgmt_region-az-2 81 | internal = module.core.sec_subnet_internal_region-az-2 82 | peering = module.core.sec_subnet_peering_region-az-2 83 | 84 | } 85 | application = { 86 | internet = module.core.app_subnet_internet_region-az-2 87 | dmz_1 = module.core.app_subnet_dmz_1_region-az-2 88 | application_region = module.core.app_subnet_application_region-az-2 89 | peering = module.core.app_subnet_peering_region-az-2 90 | mgmt = module.core.app_subnet_mgmt_region-az-2 91 | } 92 | container = { 93 | internet = module.core.container_subnet_internet_region-az-2 94 | dmz_1 = module.core.container_subnet_dmz_1_region-az-2 95 | application_region = module.core.container_subnet_application_region-az-2 96 | peering = module.core.container_subnet_peering_region-az-2 97 | mgmt = module.core.container_subnet_mgmt_region-az-2 98 | } 99 | } 100 | } 101 | } 102 | 103 | output route_tables { 104 | value = { 105 | internet = module.core.internet_rt 106 | sec_internal = module.core.sec_Internal_rt 107 | to_security_inspection_1 = module.core.to_security_insepction_1_rt 108 | frm_security_inspection_1 = module.core.frm_security_insepction_1_rt 109 | to_security_inspection_2 = module.core.to_security_insepction_2_rt 110 | frm_security_inspection_2 = module.core.frm_security_insepction_2_rt 111 | app_tgw = module.core.app_tgw_main_rt 112 | container_tgw = module.core.container_tgw_main_rt 113 | sec_app_az1 = module.core.sec_application_az1_rt 114 | sec_app_az2 = module.core.sec_application_az2_rt 115 | } 116 | } 117 | 118 | output CFE_route_tables { 119 | value = { 120 | internet = module.core.CFE_external_route_table_tag 121 | internal = module.core.CFE_internal_route_table_tag 122 | } 123 | } 124 | 125 | output transit_gateways { 126 | value = { 127 | security_to_app = module.core.security-app-tgw 128 | security-app-tgw-main = module.core.security-app-tgw-main-rt 129 | } 130 | } 131 | 132 | output cidrs { 133 | value = { 134 | SecurityVPC = module.core.cidr-1 135 | ApplicationVPC = module.core.cidr-2 136 | ContainerVPC = module.core.cidr-3 137 | } 138 | } 139 | 140 | output subnet_cidrs { 141 | value = { 142 | az1 = { 143 | security = { 144 | internet = module.core.sec_subnet_internet_region-az-1-subnet 145 | egress_to_ch1 = module.core.sec_subnet_egress_to_ch1_region-az-1-subnet 146 | ingress_frm_ch1 = module.core.sec_subnet_ingress_frm_ch1_region-az-1-subnet 147 | application_region = module.core.sec_subnet_application_region-az-1-subnet 148 | egress_to_ch2 = module.core.sec_subnet_egress_to_ch2_region-az-1-subnet 149 | ingress_frm_ch2 = module.core.sec_subnet_ingress_frm_ch2_region-az-1-subnet 150 | dmz_outside = module.core.sec_subnet_dmz_outside_region-az-1-subnet 151 | dmz_inside = module.core.sec_subnet_dmz_inside_region-az-1-subnet 152 | mgmt = module.core.sec_subnet_mgmt_region-az-1-subnet 153 | internal = module.core.sec_subnet_internal_region-az-1-subnet 154 | peering = module.core.sec_subnet_peering_region-az-1-subnet 155 | 156 | } 157 | application = { 158 | internet = module.core.app_subnet_internet_region-az-1-subnet 159 | dmz_1 = module.core.app_subnet_dmz_1_region-az-1-subnet 160 | application_region = module.core.app_subnet_application_region-az-1-subnet 161 | peering = module.core.app_subnet_peering_region-az-1-subnet 162 | mgmt = module.core.app_subnet_mgmt_region-az-1-subnet 163 | } 164 | container = { 165 | internet = module.core.container_subnet_internet_region-az-1-subnet 166 | dmz_1 = module.core.container_subnet_dmz_1_region-az-1-subnet 167 | application_region = module.core.container_subnet_application_region-az-1-subnet 168 | peering = module.core.container_subnet_peering_region-az-1-subnet 169 | mgmt = module.core.container_subnet_mgmt_region-az-1-subnet 170 | } 171 | } 172 | az2 = { 173 | security = { 174 | internet = module.core.sec_subnet_internet_region-az-2-subnet 175 | egress_to_ch1 = module.core.sec_subnet_egress_to_ch1_region-az-2-subnet 176 | ingress_frm_ch1 = module.core.sec_subnet_ingress_frm_ch1_region-az-2-subnet 177 | application_region = module.core.sec_subnet_application_region-az-2-subnet 178 | egress_to_ch2 = module.core.sec_subnet_egress_to_ch2_region-az-2-subnet 179 | ingress_frm_ch2 = module.core.sec_subnet_ingress_frm_ch2_region-az-2-subnet 180 | dmz_outside = module.core.sec_subnet_dmz_outside_region-az-2-subnet 181 | dmz_inside = module.core.sec_subnet_dmz_inside_region-az-2-subnet 182 | mgmt = module.core.sec_subnet_mgmt_region-az-2-subnet 183 | internal = module.core.sec_subnet_internal_region-az-2-subnet 184 | peering = module.core.sec_subnet_peering_region-az-2-subnet 185 | 186 | } 187 | application = { 188 | internet = module.core.app_subnet_internet_region-az-2-subnet 189 | dmz_1 = module.core.app_subnet_dmz_1_region-az-2-subnet 190 | application_region = module.core.app_subnet_application_region-az-2-subnet 191 | peering = module.core.app_subnet_peering_region-az-2-subnet 192 | mgmt = module.core.app_subnet_mgmt_region-az-2-subnet 193 | } 194 | container = { 195 | internet = module.core.container_subnet_internet_region-az-2-subnet 196 | dmz_1 = module.core.container_subnet_dmz_1_region-az-2-subnet 197 | application_region = module.core.container_subnet_application_region-az-2-subnet 198 | peering = module.core.container_subnet_peering_region-az-2-subnet 199 | mgmt = module.core.container_subnet_mgmt_region-az-2-subnet 200 | } 201 | } 202 | } 203 | } 204 | 205 | output aws_cidr_ips { 206 | value = { 207 | az1 = { 208 | security = { 209 | internet = module.core.sec_subnet_internet_region-az-1-aws-ip 210 | egress_to_ch1 = module.core.sec_subnet_egress_to_ch1_region-az-1-aws-ip 211 | ingress_frm_ch1 = module.core.sec_subnet_ingress_frm_ch1_region-az-1-aws-ip 212 | application_region = module.core.sec_subnet_application_region-az-1-aws-ip 213 | egress_to_ch2 = module.core.sec_subnet_egress_to_ch2_region-az-1-aws-ip 214 | ingress_frm_ch2 = module.core.sec_subnet_ingress_frm_ch2_region-az-1-aws-ip 215 | dmz_outside = module.core.sec_subnet_dmz_outside_region-az-1-aws-ip 216 | dmz_inside = module.core.sec_subnet_dmz_inside_region-az-1-aws-ip 217 | mgmt = module.core.sec_subnet_mgmt_region-az-1-aws-ip 218 | internal = module.core.sec_subnet_internal_region-az-1-aws-ip 219 | peering = module.core.sec_subnet_peering_region-az-1-aws-ip 220 | 221 | } 222 | application = { 223 | internet = module.core.app_subnet_internet_region-az-1-aws-ip 224 | dmz_1 = module.core.app_subnet_dmz_1_region-az-1-aws-ip 225 | application_region = module.core.app_subnet_application_region-az-1-aws-ip 226 | peering = module.core.app_subnet_peering_region-az-1-aws-ip 227 | mgmt = module.core.app_subnet_mgmt_region-az-1-aws-ip 228 | } 229 | container = { 230 | internet = module.core.container_subnet_internet_region-az-1-aws-ip 231 | dmz_1 = module.core.container_subnet_dmz_1_region-az-1-aws-ip 232 | application_region = module.core.container_subnet_application_region-az-1-aws-ip 233 | peering = module.core.container_subnet_peering_region-az-1-aws-ip 234 | mgmt = module.core.container_subnet_mgmt_region-az-1-aws-ip 235 | } 236 | } 237 | az2 = { 238 | security = { 239 | internet = module.core.sec_subnet_internet_region-az-2-aws-ip 240 | egress_to_ch1 = module.core.sec_subnet_egress_to_ch1_region-az-2-aws-ip 241 | ingress_frm_ch1 = module.core.sec_subnet_ingress_frm_ch1_region-az-2-aws-ip 242 | application_region = module.core.sec_subnet_application_region-az-2-aws-ip 243 | egress_to_ch2 = module.core.sec_subnet_egress_to_ch2_region-az-2-aws-ip 244 | ingress_frm_ch2 = module.core.sec_subnet_ingress_frm_ch2_region-az-2-aws-ip 245 | dmz_outside = module.core.sec_subnet_dmz_outside_region-az-2-aws-ip 246 | dmz_inside = module.core.sec_subnet_dmz_inside_region-az-2-aws-ip 247 | mgmt = module.core.sec_subnet_mgmt_region-az-2-aws-ip 248 | internal = module.core.sec_subnet_internal_region-az-2-aws-ip 249 | peering = module.core.sec_subnet_peering_region-az-2-aws-ip 250 | 251 | } 252 | application = { 253 | internet = module.core.app_subnet_internet_region-az-2-aws-ip 254 | dmz_1 = module.core.app_subnet_dmz_1_region-az-2-aws-ip 255 | application_region = module.core.app_subnet_application_region-az-2-aws-ip 256 | peering = module.core.app_subnet_peering_region-az-2-aws-ip 257 | mgmt = module.core.app_subnet_mgmt_region-az-2-aws-ip 258 | } 259 | container = { 260 | internet = module.core.container_subnet_internet_region-az-2-aws-ip 261 | dmz_1 = module.core.container_subnet_dmz_1_region-az-2-aws-ip 262 | application_region = module.core.container_subnet_application_region-az-2-aws-ip 263 | peering = module.core.container_subnet_peering_region-az-2-aws-ip 264 | mgmt = module.core.container_subnet_mgmt_region-az-2-aws-ip 265 | } 266 | } 267 | } 268 | } -------------------------------------------------------------------------------- /sca/security_stack/templates/bigip_onboard_base.tmpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Script must be non-blocking or run in the background. 3 | mkdir -p /config/cloud 4 | cat << 'EOF' > /config/cloud/startup-script.sh 5 | #!/bin/bash 6 | # BIG-IPS ONBOARD SCRIPT 7 | LOG_FILE=${onboard_log} 8 | if [ ! -e $LOG_FILE ] 9 | then 10 | touch $LOG_FILE 11 | exec &>>$LOG_FILE 12 | else 13 | #if file exists, exit as only want to run once 14 | exit 15 | fi 16 | exec 1>$LOG_FILE 2>&1 17 | # CHECK TO SEE NETWORK IS READY 18 | count=0 19 | while true 20 | do 21 | STATUS=$(curl -s -k -I https://github.com | grep HTTP) 22 | if [[ $STATUS == *"200"* ]]; then 23 | echo "internet access check passed" 24 | break 25 | elif [ $count -le 6 ]; then 26 | echo "Status code: $STATUS Not done yet..." 27 | count=$[$count+1] 28 | else 29 | echo "GIVE UP..." 30 | break 31 | fi 32 | sleep 10 33 | done 34 | # WAIT FOR BIG-IP SYSTEMS & API TO BE UP 35 | curl -o /config/cloud/utils.sh -s --fail --retry 60 -m 10 -L https://raw.githubusercontent.com/F5Networks/f5-cloud-libs/develop/scripts/util.sh 36 | . /config/cloud/utils.sh 37 | wait_for_bigip 38 | ### GET SECRET VIA DEFAULT REQUESTS LIB ON BIG-IP 39 | echo "GET BIG-IP PASSWORD FROM AWS SECRET MANAGER" 40 | role_name=$(curl -s "http://169.254.169.254/latest/meta-data/iam/security-credentials/" ) 41 | payload=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$role_name) 42 | export AWS_ACCESS_KEY_ID=$(printf "$payload" | jq -r ".AccessKeyId") 43 | export AWS_SECRET_ACCESS_KEY=$(printf "$payload" | jq -r ".SecretAccessKey") 44 | export AWS_TOKEN=$(printf "$payload" | jq -r ".Token") 45 | export AWS_REGION=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone| sed s/.$//` 46 | export SECRET_ID=${secret_id} 47 | ### WRITE PYTHON FILE TO DISK 48 | cat > secrets_manager.py << END_TEXT 49 | # Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 50 | # 51 | # This file is licensed under the Apache License, Version 2.0 (the "License"). 52 | # You may not use this file except in compliance with the License. A copy of the 53 | # License is located at 54 | # 55 | # http://aws.amazon.com/apache2.0/ 56 | # 57 | # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 58 | # OF ANY KIND, either express or implied. See the License for the specific 59 | # language governing permissions and limitations under the License. 60 | 61 | import sys, os, base64, datetime, hashlib, hmac 62 | import requests 63 | import json 64 | 65 | access_key = os.environ.get('AWS_ACCESS_KEY_ID') 66 | secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY') 67 | token = os.environ.get('AWS_TOKEN') 68 | region = os.environ.get('AWS_REGION') 69 | secret_id = os.environ.get('SECRET_ID') 70 | if access_key is None: 71 | print('No access key was provided.') 72 | sys.exit() 73 | if secret_key is None: 74 | print('No secret key was provided.') 75 | sys.exit() 76 | if token is None: 77 | print('No token was provided.') 78 | sys.exit() 79 | if region is None: 80 | print('No region was provided.') 81 | sys.exit() 82 | if secret_id is None: 83 | print('No secret_id was provided.') 84 | sys.exit() 85 | # ************* REQUEST VALUES ************* 86 | method = 'POST' 87 | service = 'secretsmanager' 88 | host = 'secretsmanager.'+ region + '.amazonaws.com' 89 | endpoint = 'https://secretsmanager.'+ region +'.amazonaws.com/' 90 | content_type = 'application/x-amz-json-1.1' 91 | amz_target = 'secretsmanager.GetSecretValue' 92 | 93 | # Request parameters for GetSecretValue--passed in a JSON block. 94 | request_parameters = '{' 95 | request_parameters += '"SecretId": "'+ secret_id +'"' 96 | request_parameters += '}' 97 | 98 | def sign(key, msg): 99 | return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest() 100 | 101 | def getSignatureKey(key, date_stamp, regionName, serviceName): 102 | kDate = sign(('AWS4' + key).encode('utf-8'), date_stamp) 103 | kRegion = sign(kDate, regionName) 104 | kService = sign(kRegion, serviceName) 105 | kSigning = sign(kService, 'aws4_request') 106 | return kSigning 107 | 108 | # Create a date for headers and the credential string 109 | t = datetime.datetime.utcnow() 110 | amz_date = t.strftime('%Y%m%dT%H%M%SZ') 111 | date_stamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope 112 | canonical_uri = '/' 113 | canonical_querystring = '' 114 | canonical_headers = 'content-type:' + content_type + '\n' + 'host:' + host + '\n' + 'x-amz-date:' + amz_date + '\n' + 'x-amz-target:' + amz_target + '\n' 115 | signed_headers = 'content-type;host;x-amz-date;x-amz-target' 116 | payload_hash = hashlib.sha256(request_parameters.encode('utf-8')).hexdigest() 117 | canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash 118 | algorithm = 'AWS4-HMAC-SHA256' 119 | credential_scope = date_stamp + '/' + region + '/' + service + '/' + 'aws4_request' 120 | string_to_sign = algorithm + '\n' + amz_date + '\n' + credential_scope + '\n' + hashlib.sha256(canonical_request.encode('utf-8')).hexdigest() 121 | signing_key = getSignatureKey(secret_key, date_stamp, region, service) 122 | # Sign the string_to_sign using the signing_key 123 | signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest() 124 | authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature 125 | headers = {'Content-Type':content_type, 126 | 'X-Amz-Date':amz_date, 127 | 'X-Amz-Target':amz_target, 128 | 'Authorization':authorization_header, 129 | 'X-Amz-Security-Token': token} 130 | # ************* SEND THE REQUEST ************* 131 | 132 | r = requests.post(endpoint, request_parameters, headers=headers) 133 | 134 | print(r.text) 135 | END_TEXT 136 | 137 | ### SET BIG-IP PASSWORD 138 | echo "SET THE BIG-IP PASSWORD" 139 | pwd=$(python secrets_manager.py | jq -r ".SecretString") 140 | if [ -z "$pwd" ] 141 | then 142 | echo "ERROR: UNABLE TO OBTAIN PASSWORD" 143 | else 144 | tmsh modify auth user admin password $pwd 145 | fi 146 | 147 | ### install atc tools 148 | ## iapps dir fix 149 | 150 | # start modify appdata directory size 151 | echo "setting app directory size" 152 | tmsh show sys disk directory /appdata 153 | # 130,985,984 26,128,384 52,256,768 154 | tmsh modify /sys disk directory /appdata new-size 52256768 155 | tmsh show sys disk directory /appdata 156 | echo "done setting app directory size" 157 | tmsh save sys config 158 | # end modify appdata directory size 159 | 160 | ## set vars 161 | # constants 162 | rpmInstallUrl="/mgmt/shared/iapp/package-management-tasks" 163 | rpmFilePath="/var/config/rest/downloads" 164 | local_host="http://localhost:8100" 165 | # do 166 | doUrl="/mgmt/shared/declarative-onboarding" 167 | doCheckUrl="/mgmt/shared/declarative-onboarding/info" 168 | doTaskUrl="/mgmt/shared/declarative-onboarding/task" 169 | # as3 170 | as3Url="/mgmt/shared/appsvcs/declare" 171 | as3CheckUrl="/mgmt/shared/appsvcs/info" 172 | as3TaskUrl="/mgmt/shared/appsvcs/task" 173 | # ts 174 | tsUrl="/mgmt/shared/telemetry/declare" 175 | tsCheckUrl="/mgmt/shared/telemetry/info" 176 | # cloud failover ext 177 | cfUrl="/mgmt/shared/cloud-failover/declare" 178 | cfCheckUrl="/mgmt/shared/cloud-failover/info" 179 | # fast 180 | fastCheckUrl="/mgmt/shared/fast/info" 181 | # vars 182 | mgmt_port=`tmsh list sys httpd ssl-port | grep ssl-port | sed 's/ssl-port //;s/ //g'` 183 | # admin_username='$uname' 184 | admin_password='$pwd' 185 | # CREDS="$admin_username:$admin_password" 186 | CREDS="admin:$admin_password" 187 | toolsList=$(cat -< /config/cloud/startup-script.sh 5 | #!/bin/bash 6 | LOG_FILE=${onboard_log} 7 | if [ ! -e $LOG_FILE ] 8 | then 9 | touch $LOG_FILE 10 | exec &>>$LOG_FILE 11 | else 12 | #if file exists, exit as only want to run once 13 | exit 14 | fi 15 | exec 1>$LOG_FILE 2>&1 16 | function checkInternet () { 17 | host=$1 18 | count=0 19 | while true 20 | do 21 | STATUS=$(curl -s -k -I $host | grep HTTP) 22 | if [[ $STATUS == *"HTTP"* ]]; then 23 | echo "passed $host" 24 | break 25 | elif [ $count -le 6 ]; then 26 | count=$[$count+1] 27 | else 28 | echo "failed $host" 29 | break 30 | fi 31 | sleep 10 32 | done 33 | } 34 | checkInternet https://github.com 35 | curl -o /config/cloud/utils.sh -s --fail --retry 60 -m 10 -L https://raw.githubusercontent.com/F5Networks/f5-cloud-libs/develop/scripts/util.sh 36 | . /config/cloud/utils.sh 37 | wait_for_bigip 38 | echo "GET BIG-IP PASSWORD FROM AWS SECRET MANAGER" 39 | role_name=$(curl -s "http://169.254.169.254/latest/meta-data/iam/security-credentials/" ) 40 | payload=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$role_name) 41 | export AWS_ACCESS_KEY_ID=$(printf "$payload" | jq -r ".AccessKeyId") 42 | export AWS_SECRET_ACCESS_KEY=$(printf "$payload" | jq -r ".SecretAccessKey") 43 | export AWS_TOKEN=$(printf "$payload" | jq -r ".Token") 44 | export AWS_REGION=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone| sed s/.$//` 45 | export SECRET_ID=${secret_id} 46 | cat > secrets_manager.py << END_TEXT 47 | # Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 48 | # 49 | 50 | import sys, os, base64, datetime, hashlib, hmac 51 | import requests 52 | import json 53 | 54 | access_key = os.environ.get('AWS_ACCESS_KEY_ID') 55 | secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY') 56 | token = os.environ.get('AWS_TOKEN') 57 | region = os.environ.get('AWS_REGION') 58 | secret_id = os.environ.get('SECRET_ID') 59 | if access_key is None: 60 | print('No access key was provided.') 61 | sys.exit() 62 | if secret_key is None: 63 | print('No secret key was provided.') 64 | sys.exit() 65 | if token is None: 66 | print('No token was provided.') 67 | sys.exit() 68 | if region is None: 69 | print('No region was provided.') 70 | sys.exit() 71 | if secret_id is None: 72 | print('No secret_id was provided.') 73 | sys.exit() 74 | 75 | method = 'POST' 76 | service = 'secretsmanager' 77 | host = 'secretsmanager.'+ region + '.amazonaws.com' 78 | endpoint = 'https://secretsmanager.'+ region +'.amazonaws.com/' 79 | content_type = 'application/x-amz-json-1.1' 80 | amz_target = 'secretsmanager.GetSecretValue' 81 | 82 | 83 | request_parameters = '{' 84 | request_parameters += '"SecretId": "'+ secret_id +'"' 85 | request_parameters += '}' 86 | 87 | def sign(key, msg): 88 | return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest() 89 | 90 | def getSignatureKey(key, date_stamp, regionName, serviceName): 91 | kDate = sign(('AWS4' + key).encode('utf-8'), date_stamp) 92 | kRegion = sign(kDate, regionName) 93 | kService = sign(kRegion, serviceName) 94 | kSigning = sign(kService, 'aws4_request') 95 | return kSigning 96 | 97 | t = datetime.datetime.utcnow() 98 | amz_date = t.strftime('%Y%m%dT%H%M%SZ') 99 | date_stamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope 100 | canonical_uri = '/' 101 | canonical_querystring = '' 102 | canonical_headers = 'content-type:' + content_type + '\n' + 'host:' + host + '\n' + 'x-amz-date:' + amz_date + '\n' + 'x-amz-target:' + amz_target + '\n' 103 | signed_headers = 'content-type;host;x-amz-date;x-amz-target' 104 | payload_hash = hashlib.sha256(request_parameters.encode('utf-8')).hexdigest() 105 | canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash 106 | algorithm = 'AWS4-HMAC-SHA256' 107 | credential_scope = date_stamp + '/' + region + '/' + service + '/' + 'aws4_request' 108 | string_to_sign = algorithm + '\n' + amz_date + '\n' + credential_scope + '\n' + hashlib.sha256(canonical_request.encode('utf-8')).hexdigest() 109 | signing_key = getSignatureKey(secret_key, date_stamp, region, service) 110 | signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest() 111 | authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature 112 | headers = {'Content-Type':content_type, 113 | 'X-Amz-Date':amz_date, 114 | 'X-Amz-Target':amz_target, 115 | 'Authorization':authorization_header, 116 | 'X-Amz-Security-Token': token} 117 | r = requests.post(endpoint, request_parameters, headers=headers) 118 | 119 | print(r.text) 120 | END_TEXT 121 | ### SET BIG-IP PASSWORD 122 | echo "SET THE BIG-IP PASSWORD" 123 | checkInternet https://secretsmanager.$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone| sed s/.$//).amazonaws.com 124 | pwd=$(python secrets_manager.py | jq -r ".SecretString") 125 | if [ -z "$pwd" ] 126 | then 127 | echo "ERROR: UNABLE TO OBTAIN PASSWORD" 128 | else 129 | tmsh modify auth user admin password $pwd 130 | fi 131 | ### install atc tools 132 | # start modify appdata directory size 133 | echo "setting app directory size" 134 | tmsh show sys disk directory /appdata 135 | # 130,985,984 26,128,384 52,256,768 136 | tmsh modify /sys disk directory /appdata new-size 52256768 137 | tmsh show sys disk directory /appdata 138 | echo "done setting app directory size" 139 | tmsh save sys config 140 | # end modify appdata directory size 141 | # constants 142 | rpmInstallUrl="/mgmt/shared/iapp/package-management-tasks" 143 | rpmFilePath="/var/config/rest/downloads" 144 | local_host="http://localhost:8100" 145 | doUrl="/mgmt/shared/declarative-onboarding" 146 | doCheckUrl="/mgmt/shared/declarative-onboarding/info" 147 | doTaskUrl="/mgmt/shared/declarative-onboarding/task" 148 | as3Url="/mgmt/shared/appsvcs/declare" 149 | as3CheckUrl="/mgmt/shared/appsvcs/info" 150 | as3TaskUrl="/mgmt/shared/appsvcs/task" 151 | tsUrl="/mgmt/shared/telemetry/declare" 152 | tsCheckUrl="/mgmt/shared/telemetry/info" 153 | cfUrl="/mgmt/shared/cloud-failover/declare" 154 | cfCheckUrl="/mgmt/shared/cloud-failover/info" 155 | fastCheckUrl="/mgmt/shared/fast/info" 156 | mgmt_port=`tmsh list sys httpd ssl-port | grep ssl-port | sed 's/ssl-port //;s/ //g'` 157 | admin_password='$pwd' 158 | CREDS="admin:$admin_password" 159 | toolsList=$(cat -<