Skip to content

Commit

Permalink
Fix AWS cloud formation template (#2087)
Browse files Browse the repository at this point in the history
  • Loading branch information
kbeaugrand committed Jun 22, 2023
1 parent 1e82da0 commit 0b564a6
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 62 deletions.
41 changes: 25 additions & 16 deletions src/AzureIoTHub.Portal.sln
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{3CA1
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{3F7A2982-4F0B-45F9-9FCA-923D5A7A1511}"
ProjectSection(SolutionItems) = preProject
..\templates\app_insights.bicep = ..\templates\app_insights.bicep
..\templates\app_service.bicep = ..\templates\app_service.bicep
..\templates\app_service_plan.bicep = ..\templates\app_service_plan.bicep
..\templates\azuredeploy.bicep = ..\templates\azuredeploy.bicep
..\templates\azuredeployUI.json = ..\templates\azuredeployUI.json
..\templates\blob_container.bicep = ..\templates\blob_container.bicep
..\templates\database.bicep = ..\templates\database.bicep
..\templates\dps.bicep = ..\templates\dps.bicep
..\templates\iothub.bicep = ..\templates\iothub.bicep
..\templates\iothub_eventhub_consumer_group.bicep = ..\templates\iothub_eventhub_consumer_group.bicep
..\templates\portal_without_lorawan.bicep = ..\templates\portal_without_lorawan.bicep
..\templates\portal_with_lorawan.bicep = ..\templates\portal_with_lorawan.bicep
..\templates\portal_with_lorawan_and_starter_kit.bicep = ..\templates\portal_with_lorawan_and_starter_kit.bicep
..\templates\storage.bicep = ..\templates\storage.bicep
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ISSUE_TEMPLATES", "ISSUE_TEMPLATES", "{4B89F192-EA33-4121-9809-D99621C40F3B}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -75,6 +59,29 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureIoTHub.Portal.Postgres
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureIoTHub.Portal.Tests.E2E", "AzureIoTHub.Portal.Tests.E2E\AzureIoTHub.Portal.Tests.E2E.csproj", "{9C5F753D-B9A3-4E7F-BFF3-37EB8BEBAB80}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "aws", "aws", "{AD6BE5D2-0FFB-4629-8DE1-67D9B4D39577}"
ProjectSection(SolutionItems) = preProject
..\templates\aws\awsdeploy.yml = ..\templates\aws\awsdeploy.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "azure", "azure", "{EB8B706B-11C0-4D53-B5DA-603A4C1668F9}"
ProjectSection(SolutionItems) = preProject
..\templates\app_insights.bicep = ..\templates\app_insights.bicep
..\templates\app_service.bicep = ..\templates\app_service.bicep
..\templates\app_service_plan.bicep = ..\templates\app_service_plan.bicep
..\templates\azuredeploy.bicep = ..\templates\azuredeploy.bicep
..\templates\azuredeployUI.json = ..\templates\azuredeployUI.json
..\templates\blob_container.bicep = ..\templates\blob_container.bicep
..\templates\database.bicep = ..\templates\database.bicep
..\templates\dps.bicep = ..\templates\dps.bicep
..\templates\iothub.bicep = ..\templates\iothub.bicep
..\templates\iothub_eventhub_consumer_group.bicep = ..\templates\iothub_eventhub_consumer_group.bicep
..\templates\portal_without_lorawan.bicep = ..\templates\portal_without_lorawan.bicep
..\templates\portal_with_lorawan.bicep = ..\templates\portal_with_lorawan.bicep
..\templates\portal_with_lorawan_and_starter_kit.bicep = ..\templates\portal_with_lorawan_and_starter_kit.bicep
..\templates\storage.bicep = ..\templates\storage.bicep
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -137,6 +144,8 @@ Global
{3CA153F4-1172-4AF5-B483-94200717AB5C} = {20EC2171-363D-4DDE-827F-F56D4FE9ADF3}
{3F7A2982-4F0B-45F9-9FCA-923D5A7A1511} = {20EC2171-363D-4DDE-827F-F56D4FE9ADF3}
{4B89F192-EA33-4121-9809-D99621C40F3B} = {3CA153F4-1172-4AF5-B483-94200717AB5C}
{AD6BE5D2-0FFB-4629-8DE1-67D9B4D39577} = {3F7A2982-4F0B-45F9-9FCA-923D5A7A1511}
{EB8B706B-11C0-4D53-B5DA-603A4C1668F9} = {3F7A2982-4F0B-45F9-9FCA-923D5A7A1511}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E03F3EEB-7B2B-4849-A581-4150BF29EC2B}
Expand Down
144 changes: 98 additions & 46 deletions templates/aws/awsdeploy.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
AWSTemplateFormatVersion: 2010-09-09
Description: AWS S3 storage template | PostgreSQL database storage template | Application Runner template
Description: IoT Hub portal deployment template

Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Solution"
Parameters:
- UniqueSolutionPrefix
- Label:
default: "Amazon Web Services resources access"
Parameters:
- awsAccess
- awsAccessSecretkey
- Label:
default: "PostgreSQL"
Parameters:
- pgsqlAdminLogin
- pgsqlAdminPassword
- Label:
default: "Open ID"
Parameters:
- openIdApiClientId
- openIdClientId
- openIdAuthority
- openIdMetadataURL
- openIdScopeName
ParameterLabels:
ParameterLabel

Parameters:
UniqueSolutionPrefix:
Expand All @@ -10,22 +38,24 @@ Parameters:
ConstraintDescription: Should be less than 20 letters
AllowedPattern: '^[a-z]+$'
pgsqlAdminLogin:
Type: String
Description: PostgreSQL user
MinLength: '1'
MaxLength: '30'
Type: String
Description: PostgreSQL user
MinLength: '1'
MaxLength: '30'
pgsqlAdminPassword:
Type: String
NoEcho: 'true'
Description: PostgreSQL password
MinLength: '8'
MaxLength: '41'
Type: String
NoEcho: 'true'
Description: PostgreSQL password
MinLength: '8'
MaxLength: '41'
awsAccess:
Type: String
Description: AWS Access Sectet
Description: AWS Access Secret
NoEcho: 'true'
awsAccessSecretkey:
Type: String
Description: AWS Access Secret Key
NoEcho: 'true'
openIdApiClientId:
Type: String
Description: The Open ID API client ID for the B2C tenant
Expand All @@ -46,15 +76,6 @@ Parameters:
Type: String
Description: The Open ID Scope name
Default: iot_access
VPC:
Type: AWS::EC2::VPC::Id
Subnet1:
Type: AWS::EC2::Subnet::Id
Subnet2:
Type: AWS::EC2::Subnet::Id
Subnet3:
Type: AWS::EC2::Subnet::Id


Resources:
#======== S3 Storage ==========
Expand All @@ -71,15 +92,35 @@ Resources:
Rules:
- ObjectOwnership: BucketOwnerPreferred
AccessControl: AwsExecRead
#======== Virtual Private Cloud ==========
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: 'true'
EnableDnsHostnames: 'true'
Subnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPC
CidrBlock: 10.0.0.0/27
AvailabilityZone: !Join [ "", [!Ref AWS::Region, "a"] ]
Subnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPC
CidrBlock: 10.0.0.32/27
AvailabilityZone: !Join [ "", [!Ref AWS::Region, "b"] ]

#======== PostgreSQL database ==========
PostgreSQLDB:
Type: AWS::RDS::DBInstance
DeletionPolicy: Retain # CloudFormation keeps the resource without deleting the resource or its contents when the resource is replaced
UpdateReplacePolicy: Retain # see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
Properties:
DBInstanceIdentifier: !Join [ "-", [!Ref UniqueSolutionPrefix, "pgdbinstance"] ]
DBInstanceIdentifier: !Join [ "-", [!Ref UniqueSolutionPrefix, "pgdb"] ]
AllocatedStorage: '20'
DBInstanceClass: 'db.t2.micro' # A voir quel instance utilisé : https://instances.vantage.sh/rds/
DBInstanceClass: 'db.t2.micro'
Engine: postgres
EngineVersion: 12
LicenseModel: postgresql-license
Expand All @@ -89,6 +130,7 @@ Resources:
VPCSecurityGroups:
- !Ref PgSQLSecurityGroup
DBSubnetGroupName: !Ref PgSQLSubnetGroup

PgSQLSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
Expand All @@ -99,21 +141,21 @@ Resources:
FromPort: 5432
ToPort: 5432
CidrIp: 0.0.0.0/0

PgSQLSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupName: !Join [ "-", [!Ref UniqueSolutionPrefix, "pgSqlsubnetgroup"] ]
DBSubnetGroupDescription: Subnets available for the database
SubnetIds: # A voir le nombre de subnets qu'on veut dans le groupe
SubnetIds:
- !Ref Subnet1
- !Ref Subnet2
- !Ref Subnet3


#InstanceRoleArn
InstanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join [ "-", [!Ref UniqueSolutionPrefix, "AWSAppRunner"] ]
RoleName: !Join [ "-", [!Ref UniqueSolutionPrefix, "AppRunner"] ]
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
Expand Down Expand Up @@ -191,47 +233,39 @@ Resources:
# AWS Secrets Manager
SMAWSKey:
Type: AWS::SecretsManager::Secret
DeletionPolicy: Retain # CloudFormation keeps the resource without deleting the resource or its contents when the resource is replaced
UpdateReplacePolicy: Retain # see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
Properties:
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "SMAWSKey"] ]
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "AWSKey"] ]
SecretString: !Sub '${awsAccess}'
SMAWSSecretKey:
Type: AWS::SecretsManager::Secret
DeletionPolicy: Retain # CloudFormation keeps the resource without deleting the resource or its contents when the resource is replaced
UpdateReplacePolicy: Retain # see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
Properties:
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "SMAWSSecretKey"] ]
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "AWSSecretKey"] ]
SecretString: !Sub '${awsAccessSecretkey}'
SMPostgreConnection:
SMPostgreSQLConnectionString:
Type: AWS::SecretsManager::Secret
DeletionPolicy: Retain # CloudFormation keeps the resource without deleting the resource or its contents when the resource is replaced
UpdateReplacePolicy: Retain # see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
Properties:
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "SMPostgreConnection"] ]
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "PostgreSQLConnectionString"] ]
SecretString: !Join
- ""
- - 'Server='
- !GetAtt PostgreSQLDB.Endpoint.Address
- !Sub ';Database=${UniqueSolutionPrefix}_cgigeiotdemo;Port=5432;User Id=${pgsqlAdminLogin};Password=${pgsqlAdminPassword};Pooling=true;Connection Lifetime=0;Command Timeout=0;'
SMAWSStorageConnection:
SMS3StorageConnectionString:
Type: AWS::SecretsManager::Secret
DeletionPolicy: Retain # CloudFormation keeps the resource without deleting the resource or its contents when the resource is replaced
UpdateReplacePolicy: Retain # see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
Properties:
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "SMAWSStorageConnection"] ]
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "S3StorageConnectionString"] ]
SecretString: !Join
- ""
- - !Sub 'https://s3.${AWS::Region}.amazonaws.com/'
- !Ref UniqueSolutionPrefix
- '-bucket'


#============= App Runner - To Lunch the App ==============
#============= App Runner - To Launch the App ==============
AppRunnerService:
Type: AWS::AppRunner::Service
Properties:
ServiceName: !Join [ "-", [!Ref UniqueSolutionPrefix, "appRunner"] ]
ServiceName: !Join [ "-", [!Ref UniqueSolutionPrefix, "portal"] ]
InstanceConfiguration:
Cpu: 1 vCPU
Memory: 2 GB
Expand All @@ -243,6 +277,10 @@ Resources:
Timeout: 5
HealthyThreshold: 2
UnhealthyThreshold: 5
NetworkConfiguration:
EgressConfiguration:
EgressType: VPC
VpcConnectorArn: !Ref AppRunnerServiceVPCConnector
SourceConfiguration:
AutoDeploymentsEnabled: false
AuthenticationConfiguration:
Expand All @@ -256,10 +294,14 @@ Resources:
- Name: AWS__AccessSecret
Value: !Ref SMAWSSecretKey
- Name: PostgreSQL__ConnectionString
Value: !Ref SMPostgreConnection
Value: !Ref SMPostgreSQLConnectionString
- Name: AWS__S3Storage__ConnectionString
Value: !Ref SMAWSStorageConnection
Value: !Ref SMS3StorageConnectionString
RuntimeEnvironmentVariables:
- Name: AWS__Region
Value: !Ref AWS::Region
- Name: AWS__BucketName
Value: !Join [ "-", [!Ref UniqueSolutionPrefix, "bucket"] ]
- Name: OIDC__ApiClientId
Value: !Sub '${openIdApiClientId}'
- Name: OIDC__ClientId
Expand All @@ -276,6 +318,16 @@ Resources:
Value: IoT Portal DEMO - AWS
ImageIdentifier: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/iot-hub-portal:latest'
ImageRepositoryType: ECR

AppRunnerServiceVPCConnector:
Type: AWS::AppRunner::VpcConnector
Properties:
VpcConnectorName: !Join [ "-", [!Ref UniqueSolutionPrefix, "portal-vpc-connector"] ]
Subnets:
- !Ref Subnet1
- !Ref Subnet2
SecurityGroups:
- !Ref PgSQLSecurityGroup

#GreenGras role script
GreenGrasRole:
Expand Down

0 comments on commit 0b564a6

Please sign in to comment.